三层结构介绍
表现层:
* 也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。
* 表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
* 表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
* 表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)
业务层:
* 也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。
* 业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的, 事务应该放到业务层来控制)
持久层:
* 也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。
SpringMvc是什么?
SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring 的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等
SpringMvc整体结构
开发环境:
本案例使用开发环境:
Jdk:jdk1.8
IDE:Oxygen
Tomcat:apache-tomcat-8.5.x
Springmvc:5.0.7
编写简单的springmvc程序:
package com.kkb.springmvc.controller; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.kkb.springmvc.po.Item; /*** * 处理器的开发方式有多种,比如实现HttpRequestHandler接口、Controller接口的方式,还有注解的方式 * 企业中使用的一般来讲都是注解的方式 注解的方式,主要有两个注意事项: * 类上加上@Controller注解(必须是Controller,可以通过源码找到答案) 类上或者方法上面要加上@RequestMapping注解(必须的) * * @author think * */ @Controller public class ItemController { // @RequestMapping此时填写的是url // ModelAndView:model表示的是数据模型,view就是最终要展示给用户的视图 @RequestMapping("queryItem") public ModelAndView queryItem() { // 查询数据库,用静态数据模拟 List<Item> itemList = new ArrayList<>(); // 商品列表 Item item_1 = new Item(); item_1.setName("联想笔记本_3"); item_1.setPrice(6000f); item_1.setDetail("ThinkPad T430 联想笔记本电脑!"); Item item_2 = new Item(); item_2.setName("苹果手机"); item_2.setPrice(5000f); item_2.setDetail("iphone6苹果手机!"); itemList.add(item_1); itemList.add(item_2); ModelAndView mvAndView = new ModelAndView(); // 设置数据模型,相当于request的setAttribute方法,实质上,底层确实也是转成了request(暂时这样理解) // 先将k/v数据放入map中,最终根据视图对象不同,再进行后续处理 mvAndView.addObject("itemList", itemList); // 设置视图(逻辑路径) mvAndView.setViewName("item/item-list"); // mvAndView.setViewName("/WEB-INF/jsp/item/item-list.jsp"); return mvAndView; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 处理器类的扫描 --> <context:component-scan base-package="com.kkb.springmvc.controller" /> <!--注解映射器 @Controller和@RequestMapping组合这种方式的注解映射的解析 --> <!-- <bean --> <!-- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> --> <!--注解适配器 --> <!-- <bean --> <!-- class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" /> --> <!-- 配置注解的适配器和映射器,同时还注入了很多其他的bean --> <mvc:annotation-driven/> <!-- 显式的配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- 学习前置条件 --> <!-- 问题1:web.xml中servelet、filter、listener、context-param加载顺序 --> <!-- 问题2:load-on-startup标签的作用,影响了servlet对象创建的时机 --> <!-- 问题3:url-pattern标签的配置方式有四种:/dispatcherServlet、 /servlet/* 、*.do 、/ ,以上四种配置,加载顺序是如何的--> <!-- 问题4:url-pattern标签的配置为/*报错,原因是它拦截了JSP请求,但是又不能处理JSP请求。为什么配置/就不拦截JSP请求,而配置/*,就会拦截JSP请求--> <!-- 问题5:配置了springmvc去读取spring配置文件之后,就产生了spring父子容器的问题 --> <!-- 配置前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 设置spring配置文件路径 --> <!-- 如果不设置初始化参数,那么DispatcherServlet会读取默认路径下的配置文件 --> <!-- 默认配置文件路径:/WEB-INF/springmvc-servlet.xml --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <!-- 指定初始化时机,设置为2,表示Tomcat启动时,DispatcherServlet会跟随着初始化 --> <!-- 如果不指定初始化时机,DispatcherServlet就会在第一次被请求的时候,才会初始化,而且只会被初始化一次 --> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- URL-PATTERN的设置 --> <!-- 不要配置为/*,否则报错 --> <!-- 通俗解释:/*,会拦截整个项目中的资源访问,包含JSP和静态资源的访问,对于静态资源的访问springMVC提供了默认的Handler处理器 --> <!-- 但是对于JSP来讲,springmvc没有提供默认的处理器,我们也没有手动编写对于的处理器,此时按照springmvc的处理流程分析得知,它短路了 --> <url-pattern>/</url-pattern> </servlet-mapping> <!-- <servlet> --> <!-- <servlet-name>sss</servlet-name> --> <!-- <servlet-class>sss</servlet-class> --> <!-- </servlet> --> <!-- <servlet-mapping> --> <!-- <servlet-name>sss</servlet-name> --> <!-- <url-pattern>/sss</url-pattern> --> <!-- </servlet-mapping> --> </web-app>
SSM框架的整合
配置版:
1.添加依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.13.RELEASE</version> </dependency> 2.创建Student实体类 package cn.tina; public class Student { private int stuNo; private String name; public int getStuNo() { return stuNo; } public void setStuNo(int stuNo) { this.stuNo = stuNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 3.编写spring核心配置文件applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <bean id="student" class="cn.tina.Student"> <property name="name" value="张三"/> <property name="stuNo" value="1001"/> </bean> </beans> 4.编写测试类 public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()+"---"+student.getStuNo()); }
注解版:
//添加依赖 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.hynnet</groupId> <artifactId>oracle-driver-ojdbc6</artifactId> <version>12.1.0.1</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.1.9.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0-alpha-1</version> <!-- 打包的时候忽略,因为tomcat中有,重复的包会冲突--> <scope>provided</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.6</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies> //编写实体类 package cn.entity; public class Grade { private int gradeId; private String gradeName; @Override public String toString() { return "Grade{" + "gradeId=" + gradeId + ", gradeName='" + gradeName + '\'' + '}'; } public int getGradeId() { return gradeId; } public void setGradeId(int gradeId) { this.gradeId = gradeId; } public String getGradeName() { return gradeName; } public void setGradeName(String gradeName) { this.gradeName = gradeName; } } //编写Mapper package cn.dao; import cn.entity.Grade; import java.util.List; public interface GradeMapper { public List<Grade> getListGrade(); public int addGrade(Grade grade); } //编写Mapper.xml 注意放入resource下同名文件夹 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL映射文件 --> <mapper namespace="cn.dao.GradeMapper"> <select id="getListGrade" resultType="Grade"> select * from grade </select> <insert id="addGrade" parameterType="Grade"> insert into grade(gradeId,gradeName)values(#{gradeId},#{gradeName}) </insert> </mapper> //编写Service package cn.service; import cn.entity.Grade; import java.util.List; public interface GradeService { public List<Grade> getListGrade(); public int addGrade(Grade grade); } 编写实现类: package cn.service.impl; import cn.dao.GradeMapper; import cn.entity.Grade; import cn.service.GradeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service//默认bean的名称与类名同名,只是首字母改为小写 public class GradeServiceImpl implements GradeService { @Autowired//可以从spring容器中取出gradeMapper组件 GradeMapper gradeMapper; @Override public List<Grade> getListGrade() { return gradeMapper.getListGrade(); } @Transactional //添加事务注解 public int addGrade(Grade grade) { int cn = gradeMapper.addGrade(grade); // int i=1/0; //这个错误不能去捕获 让spring容器处理 会回滚数据 return cn; } } //编写Spring配置类 package cn.config; import org.apache.commons.dbcp.BasicDataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration @ComponentScan(value = "cn") @EnableTransactionManagement//开启注解式事务 @EnableAspectJAutoProxy //开启注解式aop public class SpringConfig { @Bean//在spring中注入一个数据源 public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); //mysql--连接 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setPassword("root"); dataSource.setUsername("root"); dataSource.setUrl("jdbc:mysql://localhost:3306/myschool"); /* dataSource.setUsername("system"); dataSource.setPassword("root"); dataSource.setDriverClassName("oracle.jdbc.OracleDriver"); dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");*/ return dataSource; } @Bean //设置session工厂 public SqlSessionFactoryBean sqlSessionFactory( DataSource dataSource) { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setTypeAliasesPackage("cn.entity"); //如果命名规范,且在同一个包中,可省略 // ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); // try { // sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:cn/dao/*Dao.xml")); // } catch (IOException e) { // e.printStackTrace(); // } return sqlSessionFactoryBean; } @Bean//扫描mapper 为它生成mapper的实现类 public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setBasePackage("cn.dao"); return mapperScannerConfigurer; } //配置事务管理器 @Bean public PlatformTransactionManager transactionManager(DataSource dataSource ){ return new DataSourceTransactionManager(dataSource); } } //先编写main方法,测试spring和myabtis是否整合完成 public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); GradeService gradeService = (GradeService) context.getBean("gradeServiceImpl"); Grade grade=new Grade(); grade.setGradeId(5); grade.setGradeName("444"); int cn =gradeService.addGrade(grade); System.out.println(cn+"---------------"); } //编写Controller package cn.controller; import cn.entity.Grade; import cn.service.GradeService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.annotation.Resource; import java.util.List; @Controller public class GradeController { @Resource GradeService gradeService; @RequestMapping("/") public String toIndex(){ return "redirect:/index"; } @RequestMapping("/add") public String add(Grade grade, Model model){ int cn =gradeService.addGrade(grade); model.addAttribute("msg","新增成功"); return "forward:/index"; } @RequestMapping("/index") public String index(Model model){ List<Grade> list= gradeService.getListGrade(); model.addAttribute("list",list); return "index"; } } //编写全局异常处理类 //这个注解可以对全局异常,或者数据类型转换 @ControllerAdvice public class MyAdvice { @ExceptionHandler public String handlerException(Exception e, HttpServletRequest request) { request.setAttribute("msg", "异常:" + e.getMessage()); return "error"; } /* @InitBinder //使用配置转换器方式 public void web(WebDataBinder binder) { binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)); }*/ } //编写前台到后台的日期转换器 public class StringFormatByDate implements Converter<String, Date> { @Override public Date convert(String s) { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); try { return sf.parse(s); } catch (ParseException e) { e.printStackTrace(); return null; } } } //配置拦截器 public class MyInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("进入了拦截。。。。。"); return true; } } //编写MVC配置类 @Configuration @EnableWebMvc //相当于开启注解方式 @ComponentScan(value = "cn.controller") public class MvcConfig extends WebMvcConfigurerAdapter { @Override //视图解析器 注意:views文件夹在resource下 public void configureViewResolvers(ViewResolverRegistry registry) { registry.jsp("/WEB-INF/classes/views/", ".jsp"); } @Override//不能直接使用add.jsp 配置一个跳转 public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/toAdd").setViewName("add"); } @Override //静态资源映射 注意:static文件夹在resources下 public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/static/"); } @Override //json前台到后台的问题:中文编码和日期问题 public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter(); fastJsonHttpMessageConverter.setCharset(Charset.forName("utf-8")); fastJsonHttpMessageConverter.setFeatures(SerializerFeature.WriteDateUseDateFormat); converters.add(fastJsonHttpMessageConverter); } @Override //注册 :前台到后台的日期问题 public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringFormatByDate()); } @Override //配置拦截器 public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()); } } //取代在web.xml配置中的启动spring和mvc public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override//相当于在以前web.xml中配置的读取applicationContext.xml protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class};//用于Spring的配置 } @Override//相当于在以前web.xml中配置的读取springmvc-servlet.xml protected Class<?>[] getServletConfigClasses() { return new Class[]{MvcConfig.class};//专门用于MVC的配置 } @Override protected String[] getServletMappings() { // /处理请求,不拦截jsp /* 会拦截jsp return new String[]{"/"}; } /* 添加过滤器*/ @Override protected Filter[] getServletFilters() { CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); characterEncodingFilter.setEncoding("UTF-8"); characterEncodingFilter.setForceEncoding(true); return new Filter[]{characterEncodingFilter}; } }
来源:https://www.cnblogs.com/wnlsq/p/12239164.html