# SpringMVCStudy **Repository Path**: amespaces/spring-mvcstudy ## Basic Information - **Project Name**: SpringMVCStudy - **Description**: 学习springmvc - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-03-30 - **Last Updated**: 2022-07-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringMVC ## 简介 轻量级web开发框架 ### 入门案例 - 导入坐标 ```xml javax.servlet javax.servlet-api 3.1.0 provided org.springframework spring-webmvc 5.2.8.RELEASE ``` - 初始化servlet容器配置类:加载SpringMvc环境,并设置SpringMvc请求拦截的路径 ```java public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { protected WebApplicationContext createServletApplicationContext() { AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext(); annotationConfigWebApplicationContext.register(SpringMvcConfig.class); return annotationConfigWebApplicationContext; } protected String[] getServletMappings() { return new String[]{"/"};//所有请求 } protected WebApplicationContext createRootApplicationContext() { return null; } } ``` - AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类 - 提供三个接口方法供用户实现 1. createServletApplicationContext()方法,创建servlet容器时加载SpringMVC对应的bean并放入 2. getServletMappings()方法,设定SpringMvc对应的请求映射路径,设置/表示拦截所有的请求,任意请求都将转入到SpringMvc进行处理 3. createRootApplicationContext()方法,创建servlet容器时需要加载非SpringMvc对应的bean, - 控制器类:设定请求方法的返回值为字符串类型,并返回自定义的json数据 ```java @Controller public class UserController { @RequestMapping("/save")//设置当前控制器方法请求访问路径 @ResponseBody//返回结果为提供的结果 public String save(){ System.out.println("user save ..."); return "{'info':'springmvc'}"; } } ``` ## 请求与响应 ## Rest风格 ### 简介 - REST(Representational State Transfer)表现形式状态转换 - 优点 - 隐藏资源的访问行为,无法通过地址得知对资源是何种操作 - 书写简化 - 根据REST风格对资源进行访问称为RESTful - 注解 - **@RequestBody**用于接收url地址传参或者表单传参 - **@RequsetParam**用于接收json数据 - **@PathVariable**用于接收路径参数,使用{参数名称}描述路径参数 - 应用 - 当参数超过一个以json为主,@RequestBody应用较广 - 如果非json数据,选用@RequestParam接收请求参数 - 采用@Restful进行开发参数较少时,采用@PathVariable ## 快速开发 - @RestController:等同于@Controller与@ResponseBody两个注解 - PostMapping - GetMapping - @RequestBody ### 案例(放行!!别的资源) ```java @Configuration @ComponentScan({"com.itheima.controller","com.itheima.config"}) @EnableWebMvc public class SpringMvcConfig { } ``` 静态资源访问不到这里走pages,不走mvc ```java @Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { //当访问pages/的文件时不走mvc registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); } } ``` 前端页面通过异步提交访问后台控制器 ```html //添加 saveBook () { axios.post("/books",this.formData).then((res)=>{ }); }, //主页列表查询 getAll() { axios.get("/books").then((result)=>{ this.dataList=result.data; }); }, ``` # SSM整合 ## SSM整合流程 1. 创建工程 2. SSM整合 - Spring - SpringConfig - Mybatis - MybatisConfig - JdbcConfig - Jdbc.properties - SpringMVC - ServletConfig - SpringMvcConfig 3. 功能模块 - 表与实体类 - dao(接口+自动代理) - service(接口+实现类) - 业务层接口测试(整合JUnit) - controller - 表现层接口测试(PostMan) ### 导入坐标 ```xml 4.0.0 com.itheima springmvc_08_ssm 1.0-SNAPSHOT org.apache.tomcat.maven tomcat7-maven-plugin 2.2 / 80 org.springframework spring-webmvc 5.2.8.RELEASE org.springframework spring-jdbc 5.2.8.RELEASE org.springframework spring-test 5.2.8.RELEASE org.mybatis mybatis 3.5.5 org.mybatis mybatis-spring 2.0.5 mysql mysql-connector-java 5.1.46 com.alibaba druid 1.1.12 javax.servlet javax.servlet-api 3.1.0 provided junit junit 4.13 test com.fasterxml.jackson.core jackson-databind 2.11.4 war ``` ### 整合 ### 接口测试 ```java @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class BookServiceTest { @Autowired private BookService bookService; @Test public void testGetById(){ Book book = bookService.getById(1); System.out.println(book); } @Test public void testGetAll(){ List list= bookService.getAll(); System.out.println(list); } } ``` ### 与前端数据传输 Code ```java package com.itheima.controller; public class Code { public static final Integer SAVE_OK=20011; public static final Integer DELETE_OK=20021; public static final Integer UPDATE_OK=20031; public static final Integer GET_OK=20041; public static final Integer SAVE_ERR=20010; public static final Integer DELETE_ERR=20020; public static final Integer UPDATE_ERR=20030; public static final Integer GET_ERR=20040; } ``` Result ```java package com.itheima.controller; public class Result { private Object data; private Integer code; private String msg; public Result() { } public Result(Integer code, Object data ) { this.data = data; this.code = code; } public Result(Integer code, Object data, String msg) { this.data = data; this.code = code; this.msg = msg; } @Override public String toString() { return "Result{" + "data=" + data + ", code=" + code + ", msg='" + msg + '\'' + '}'; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } ``` ### 异常处理 ```java @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(Exception.class ) public void doException(Exception e){ } } ``` #### 项目异常处理方案 - 项目异常分类(BusinessException) - 规范的用户行为产生的异常 - 不规范 - 系统异常(Systemexception) - 项目运行过程中可预计且无法避免的异常 - 其他异常(Exception) - 编程人员未预期到的异常 拦截并处理异常 ```java @RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(SystemException.class ) public Result doSystemException(SystemException e){ //记录日志 //发送消息给运维 //发送邮件给开发人员 return new Result(e.getCode(),null,e.getMessage()); } @ExceptionHandler(BusinessException.class ) public Result doBusinessException(BusinessException e){ return new Result(e.getCode(),null,e.getMessage()); } @ExceptionHandler(Exception.class) public Result doException(Exception e){ //记录日志 //发送消息给运维 //发送邮件给开发人员,e对象发送给开发人员 return new Result(Code.SYSTEM_TIMEOUT_ERR,null,"系统繁忙,请稍后再试"); } } ``` # 拦截器 ## 概念 拦截器(interceptor)是一种动态拦截方法调用的机制,在SpringMvc中动态拦截控制器方法的执行 - 作用 - 在指定的方法前后调用前后执行预先设定的代码 - 阻止原始方法的执行 ## 拦截器与过滤器的区别 - 归属不同:Filter属于Servlet技术,Interceptor属于SpringMvc技术 - 拦截内容不同:Filter对所用访问进行增强,Interceptor仅针对SpringMvc的访问进行增强 ## 入门案例 1.声明拦截器的bean,并实现HandlerInterceptot接口,需要扫描加 载bean ```java @Component public class ProjectInterceptior implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return false; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } } ``` 2.定义配置类,基层继承WebMvcConfigurationSupport,实现addInterceptor方法(需要扫描加载配置类) ```java @Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Autowired private ProjectInterceptior projectInterceptior; @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**").addResourceLocations("/pages/"); } @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptior).addPathPatterns("/books"); } } ``` 3.使用标准的接口WebMvcConfigurer简化开发(侵入式强) ```java @Configuration @ComponentScan({"com.itheima.controller"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private ProjectInterceptior projectInterceptior; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(projectInterceptior).addPathPatterns("/books"); } } ``` ## 拦截器执行顺序 - preHandle - return true - controller - postHandle - afterCompletion - return false - 结束 ## 拦截器参数 - handle - ModelAndView - Exception ex - request - response ## 多拦截器执行顺序 - 当配置多个拦截器时,形成拦截器链 - 拦截器的运行顺序参照拦截器添加顺序为准 - 当拦截器中出现对原始处理器的拦截,后面的拦截器均终止运行 ###运行顺序 - preHandle:与配置顺序相同,必运行 - postHandle:与配置顺序相反,可能不运行 - afterCompletion:与配置顺序相同,可能不运行