SpringMVC学习简要

学习资料:

SpringMVC-03-入门案例工作流程解析_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1ZF411G7eP/?p=3&spm_id_from=pageDriver&vd_source=4ac53f52a57eb96a3c8406b971b038ae

常用MYSQL命令:icon-default.png?t=N7T8http://t.csdn.cn/zshCP

学习要求 

SpringMVC学习简要_第1张图片

什么是springmvc

  • springmvc是一种基于java实现MVC模型的轻量级web框架
  • 比servlet更便捷
  • MVC模式:后端服务器
    • controller

      view(页面)

      • HTML
      • CSS
      • VUE
      • ElementUI

      model

      (最终生成的model对象是一个java对象,不能直接返回页面,要使用json格式)

      service
      dao

springmvc基本使用步骤

  • 创建web工程(maven结构)
  • 设置tomcat服务器,加载web工程(tomcat插件)
  • 导入坐标(SpringMVC+Servlet)
  • 定义处理请求的功能类(UserController)
  • 设置请求映射 (配置映射关系)
  • 将SpringMVC设定加载到Tomcat容器中 

启动服务器初始化过程

  •  服务器启动,执行ServletContainersInitConfig类,初始化web容器
  • 执行createServletApplicationContext方法,创建了WebApplicationContext对象
  • 加载SpringMvcConfig
  • 执行@ComponentScan,加载对应的bean
  • 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  • 执行getServletMappings方法,定义所有的请求都通过SpringMVC
  • SpringMVC学习简要_第2张图片
  •  简而言之:
    • 1、把springmvc配置加载到tomcat容器中
    • 2、把所有请求拦截给springmvc处理

单次请求过程

  • 发送请求localhost/save
  • web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
  • 解析请求路径/save
  • 由/save匹配执行对应的方法save()
  • 执行save()
  • 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方

Springmvc的bean扫描范围

  • 因为功能不同,如何避免spring错误地加载到SpringMVC的bean?
  • springmvc加载的bean均在com.itheima.controller包内
  • 所以要修改spring的bean扫描范围:
    • 方式一:把加载bean的扫描范围设定为com.itheima,再排除掉controller包内的bean
      @Configuration
      @ComponentScan(
              value="com.study",//扫描该包
              [email protected](
                      type= FilterType.ANNOTATION, //按注解排除
                      classes= Controller.class//不扫描有@Controller注解的包
          )
      )
      public class SpringConfig {
      }
      
    • 方式二:直接设定为更具体的包,如com.itheima.service,com.itheima.dao。。。
    • 在springmvc项目中,以使用方式二为主

请求(解决传参的问题)

  • 请求映射路径(@RequestMapping)

  • 该代码具有一般性
    • package com.study.config;
      
      import org.springframework.web.filter.CharacterEncodingFilter;
      import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
      
      import javax.servlet.Filter;
      
      public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
      
          protected Class[] getRootConfigClasses() {
              return new Class[0];
          }
      
          protected Class[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
          protected String[] getServletMappings() {
              return new String[]{"/"};
          }
      
          //乱码处理
          @Override
          protected Filter[] getServletFilters() {
              //为web容器添加过滤器并指定字符集
              CharacterEncodingFilter filter=new CharacterEncodingFilter();
              filter.setEncoding("UTF-8");
              return new Filter[]{};//数组的形式
          }
      }
      
  • 1、五种数据类型的传参(@RequestParam)

    • package com.study.controller;
      
      import com.study.domain.User;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import java.util.Arrays;
      import java.util.List;
      
      @Controller
      public class UserController {
      
          //普通参数,当请求参数名与形参名不同时,使用RequestParam注解
          @RequestMapping("/commonParam")
          @ResponseBody
          public String commonParam(@RequestParam("name")String userName){
              System.out.println("普通参数传递,userName:"+userName);
              return "{'module':'common Param'}";
          }
      
          //POJO参数
          @RequestMapping("/pojoParam")
          @ResponseBody
          public String pojoParam(User user){
              System.out.println("pojo参数传递,user:"+user);
              return "{'module':'pojo Param'}";
          }
      
          //嵌套POJO参数
          @RequestMapping("/pojoContainPojoParam")
          @ResponseBody
          public String pojoContainPojoParam(User user){
              System.out.println("pojo嵌套参数传递,user:"+user);
              return "{'module':'pojo contain Param'}";
          }
      
          //数组参数
          @RequestMapping("/arrayParam")
          @ResponseBody
          public String arrayParam(String[] likes){
              System.out.println("数组参数传递,likes:"+ Arrays.toString(likes));
              return "{'module':'array Param'}";
          }
      
          //集合参数
          @RequestMapping("/listParam")
          @ResponseBody
          public String listParam(@RequestParam List likes){
              System.out.println("集合参数传递,likes:"+ likes);
              return "{'module':'list Param'}";
          }
      }
      
    • 简而言之,url传递参数时,如果名称不对应,使用@RequestParam注解
  • 2、json数据传递参数(@RequestBody和@RequestParam

    • (1)导入坐标
      
            com.fasterxml.jackson.core
            jackson-databind
            2.8.10
      
    • (2)在核心注解类中加注解,开启自动转换json数据的支持
      • @EnableWebMvc
        public class SpringMvcConfig {
        }
        
    • (3)注意postman里的4处SpringMVC学习简要_第3张图片
    • (4)添加@RequestBody注解
          //集合参数:json格式
          @RequestMapping("/listParamForJson")
          @ResponseBody
          public String listParamForJson(@RequestBody List likes){
              System.out.println("list common(json)参数传递,list:"+ likes);
              return "{'module':'list Param for json param'}";
          }
      
          //POJO参数:json格式
          @RequestMapping("/pojoParamForJson")
          @ResponseBody
          public String pojoParamForJson(@RequestBody User user){
              System.out.println("pojo(json)参数传递,user:"+ user);
              return "{'module':'pojo for json param'}";
          }
      
          //集合参数:json格式
          @RequestMapping("/listPojoParamForJson")
          @ResponseBody
          public String listPojoParamForJson(@RequestBody List list){
              System.out.println("list pojo(json)参数传递,list:"+ list);
              return "{'module':'list pojo for json param'}";
          }
      • 发送json数据,用注解@RequestBody
      • 发送非json数据,用注解@RequestParam接收参数
  • 3、日期型参数传递(@DateTimeFormat)

    • 根据不同的日期格式设置不同的接收格式
          //日期参数
          @RequestMapping("/dataParam")
          @ResponseBody
          public String dataParam(Date date,
                                  @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
                                  @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
              System.out.println("参数传递,date:"+ date);//2088/08/08
              System.out.println("参数传递,date1(yyyy-MM-dd):"+ date1);//2088-08-08
              System.out.println("参数传递,date1(yyyy/MM/dd HH:mm:ss):"+ date2);//2088/08/08 8:08:08
              return "{'module':'date param'}";
          }
    • 注解@DateTimeFormat用于设定接收的日期格式

响应(@ResponseBody)

  • 1、响应页面

    • @RequestMapping("/toPage")
      public String toPage(){
          return "page.jsp";
      }
  • 2、响应json数据(对象转json)

    • @RequestMapping("/toJsonPOJO")
      @ResponseBody //把user对象转成json数据返回
      public User toJsonPOJO(){
              User user=new User();
              user.setName("itcast");
              user.setAge(15);
              return user;
      }
  • 3、响应json数据(对象集合转json数组)

    • @RequestMapping("/toJsonList")
      @ResponseBody
      public List toJsonList(){
              System.out.println("返回json集合数据");
              User user1=new User();
              user1.setName("itcast");
              user1.setAge(15);
      
              User user2=new User();
              user2.setName("黑马");
              user2.setAge(12);
      
              List userList=new ArrayList<>();
              userList.add(user1);
              userList.add(user2);
              return userList;
      }
  • 类型转换器(HttpMessageConverter)
        

REST风格

  • Representational State Transfer,表现层资源状态转移
  • 简而言之,REST风格就是访问网络资源的格式
  • 约定可以打破,所以叫REST风格,而不是REST规范
  • 模块名称通常用复数
  • 使用

    • 1、设定http请求动作SpringMVC学习简要_第4张图片
    • 2、设定请求参数路径变量SpringMVC学习简要_第5张图片
  • 三个接收参数的注解区别:
    • (1)@RequestParam用于接收url地址传参或表单传参
    • (2)@RequestBody用于接收json数据
    • (3)@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • REST风格简化开发

    • //简化前
      @Controller
      public class UserController {
      
          @RequestMapping(value="/users",method=RequestMethod.POST)
          @ResponseBody
          public String save(){
              System.out.println("user save...");
              return "{'module':'user save'}";
          }
      
          @RequestMapping(value="/users/{id}",method=RequestMethod.DELETE)
          @ResponseBody
          public String delete(@PathVariable Integer id){//从路径处传过来的变量
              System.out.println("user delete..."+id);
              return "{'module':'user delete'}";
          }
      
          @RequestMapping(value="/users",method=RequestMethod.PUT)
          @ResponseBody
          public String update(@RequestBody User user){
              System.out.println("user update..."+user);
              return "{'module':'user update'}";
          }
      
          @RequestMapping(value="/users/{id}",method=RequestMethod.GET)
          @ResponseBody
          public String getById(@PathVariable Integer id){
              System.out.println("user getById..."+id);
              return "{'module':'user getById'}";
          }
      
          @RequestMapping(value = "/users",method = RequestMethod.GET)
          @ResponseBody
          public String getAll(){
              System.out.println("user getAll...");
              return "{'module':'user getAll'}";
          }
      }
      
      
      
      
      //简化后
      @RestController
      @RequestMapping("/users")
      public class UserController {
      
          @PostMapping
          public String save(){
              System.out.println("user save...");
              return "{'module':'user save'}";
          }
      
          @DeleteMapping("/{id}")
          public String delete(@PathVariable Integer id){
              System.out.println("user delete..."+id);
              return "{'module':'user delete'}";
          }
      
          @PutMapping
          public String update(@RequestBody User user){
              System.out.println("user update..."+user);
              return "{'module':'user update'}";
          }
      
          @GetMapping("/{id}")
          public String getById(@PathVariable Integer id){
              System.out.println("user getById..."+id);
              return "{'module':'user getById'}";
          }
      
          @GetMapping
          public String getAll(){
              System.out.println("user getAll...");
              return "{'module':'user getAll'}";
          }
      }
  • 基于RESTful页面数据交互 

    • 1、做后台功能,开发接口并调通接口
    • 2、做页面异步调用,确认功能正常可以访问
    • 3、完成页面数据展示 
    • 4、放行静态资源的访问

SSM整合(Spring,MyBatis,SpringMVC)

  • 详见具体项目代码
  • Spring整合MyBatis的结构

配置(config)

  • SpringConfig
  • JDBCConfig、jdbc.properties
  • MyBatisConfig

表现层(controller)

  • BookController
  • Result
  • Code

模型(domain)

  • Book

数据层标准开发(dao)

  • BookDao

业务层标准开发(service)

  • BookService
  • BookServiceImpl

测试接口(test/service)

  • BookServiceTest
  • 异常处理
    • 项目异常:
      • 1、业务异常(BusinessException)
        • 发送对应消息传递给用户,提醒规范操作
      • 2、系统异常(SystemException)
        • 发送固定消息传递给用户,安抚用户
      • 3、其他异常(Exception)
        • 发送固定消息传递给用户,安抚用户
    • 项目异常处理
      • 1、自定义项目系统级异常、业务级异常……
        • //自定义项目系统级异常
          axios.get("/books").then((res)=>{});//查询
          axios.post("/books",this.formData).then((res)=>{});//添加
          axios.delete("/books"+row.id).then((res)=>{});//删除
          axios.put("/books",this.formData).then((res)=>{});//修改
          axios.get("/books"+row.id).then((res)=>{});//查询
      • 2、自定义异常编码(类似404,500的存在)
      • 3、触发自定义异常

拦截器(Interceptor)

  • 是一种动态拦截方法调用的机制
  • 拦截器和过滤器的区别:
    • 1、Filter属于Servlet技术,Interceptor属于SpringMVC技术
    • 2、Filter对所有访问进行增强,Interceptor仅对SpringMVC的访问进行增强
  • 使用步骤:

    • 1、声明拦截器的bean,并实现HandlerInterceptor接口
    • 2、定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法
    • 3、添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
    • SpringMVC学习简要_第6张图片
  • 拦截器参数:

    • 1、前置处理
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              String contentType=request.getHeader("Content-Type");
              System.out.println("preHandle..."+contentType);
              return true;
      }
      • 参数:
        • request:请求对象
        • response:响应对象
        • handler:被调用的处理器对象
      • 返回值: false,被拦截的处理器将不执行
    • 2、后置处理
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
              System.out.println("postHandle...");
      
      }
      • modelAndView: 读取并调整返回结果对应的数据和页面信息
    • 3、完成后处理
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
              System.out.println("afterCompletion...");
      
      }
      • ex:处理处理器执行过程中出现的异常情况
  • 多拦截器执行顺序(了解即可,通常一个拦截器就够用了) 

    • 配置的多个拦截器形成拦截器链
    • 拦截器链的运行顺序以拦截器添加顺序为准

你可能感兴趣的:(java框架,学习,java,开发语言)