• 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

    • 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
    •  简而言之:
      • 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
        1. @Configuration
        2. @ComponentScan(
        3. value="com.study",//扫描该包
        4. excludeFilters=@ComponentScan.Filter(
        5. type= FilterType.ANNOTATION, //按注解排除
        6. classes= Controller.class//不扫描有@Controller注解的包
        7. )
        8. )
        9. public class SpringConfig {
        10. }
      • 方式二:直接设定为更具体的包,如com.itheima.service,com.itheima.dao。。。
      • 在springmvc项目中,以使用方式二为主

    请求(解决传参的问题)

    • 请求映射路径(@RequestMapping)

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

        1. package com.study.controller;
        2. import com.study.domain.User;
        3. import org.springframework.stereotype.Controller;
        4. import org.springframework.web.bind.annotation.RequestMapping;
        5. import org.springframework.web.bind.annotation.RequestParam;
        6. import org.springframework.web.bind.annotation.ResponseBody;
        7. import java.util.Arrays;
        8. import java.util.List;
        9. @Controller
        10. public class UserController {
        11. //普通参数,当请求参数名与形参名不同时,使用RequestParam注解
        12. @RequestMapping("/commonParam")
        13. @ResponseBody
        14. public String commonParam(@RequestParam("name")String userName){
        15. System.out.println("普通参数传递,userName:"+userName);
        16. return "{'module':'common Param'}";
        17. }
        18. //POJO参数
        19. @RequestMapping("/pojoParam")
        20. @ResponseBody
        21. public String pojoParam(User user){
        22. System.out.println("pojo参数传递,user:"+user);
        23. return "{'module':'pojo Param'}";
        24. }
        25. //嵌套POJO参数
        26. @RequestMapping("/pojoContainPojoParam")
        27. @ResponseBody
        28. public String pojoContainPojoParam(User user){
        29. System.out.println("pojo嵌套参数传递,user:"+user);
        30. return "{'module':'pojo contain Param'}";
        31. }
        32. //数组参数
        33. @RequestMapping("/arrayParam")
        34. @ResponseBody
        35. public String arrayParam(String[] likes){
        36. System.out.println("数组参数传递,likes:"+ Arrays.toString(likes));
        37. return "{'module':'array Param'}";
        38. }
        39. //集合参数
        40. @RequestMapping("/listParam")
        41. @ResponseBody
        42. public String listParam(@RequestParam List likes){
        43. System.out.println("集合参数传递,likes:"+ likes);
        44. return "{'module':'list Param'}";
        45. }
        46. }
      • 简而言之,url传递参数时,如果名称不对应,使用@RequestParam注解
    • 2、json数据传递参数(@RequestBody和@RequestParam

      • (1)导入坐标
        1. <dependency>
        2. <groupId>com.fasterxml.jackson.coregroupId>
        3. <artifactId>jackson-databindartifactId>
        4. <version>2.8.10version>
        5. dependency>
      • (2)在核心注解类中加注解,开启自动转换json数据的支持
          1. @EnableWebMvc
          2. public class SpringMvcConfig {
          3. }
      • (3)注意postman里的4处
      • (4)添加@RequestBody注解
        1. //集合参数:json格式
        2. @RequestMapping("/listParamForJson")
        3. @ResponseBody
        4. public String listParamForJson(@RequestBody List likes){
        5. System.out.println("list common(json)参数传递,list:"+ likes);
        6. return "{'module':'list Param for json param'}";
        7. }
        8. //POJO参数:json格式
        9. @RequestMapping("/pojoParamForJson")
        10. @ResponseBody
        11. public String pojoParamForJson(@RequestBody User user){
        12. System.out.println("pojo(json)参数传递,user:"+ user);
        13. return "{'module':'pojo for json param'}";
        14. }
        15. //集合参数:json格式
        16. @RequestMapping("/listPojoParamForJson")
        17. @ResponseBody
        18. public String listPojoParamForJson(@RequestBody List list){
        19. System.out.println("list pojo(json)参数传递,list:"+ list);
        20. return "{'module':'list pojo for json param'}";
        21. }
        • 发送json数据,用注解@RequestBody
        • 发送非json数据,用注解@RequestParam接收参数
    • 3、日期型参数传递(@DateTimeFormat)

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

    响应(@ResponseBody)

    • 1、响应页面

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

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

        1. @RequestMapping("/toJsonList")
        2. @ResponseBody
        3. public List toJsonList(){
        4. System.out.println("返回json集合数据");
        5. User user1=new User();
        6. user1.setName("itcast");
        7. user1.setAge(15);
        8. User user2=new User();
        9. user2.setName("黑马");
        10. user2.setAge(12);
        11. List userList=new ArrayList<>();
        12. userList.add(user1);
        13. userList.add(user2);
        14. return userList;
        15. }
    • 类型转换器(HttpMessageConverter)
            

    REST风格

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

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

        1. //简化前
        2. @Controller
        3. public class UserController {
        4. @RequestMapping(value="/users",method=RequestMethod.POST)
        5. @ResponseBody
        6. public String save(){
        7. System.out.println("user save...");
        8. return "{'module':'user save'}";
        9. }
        10. @RequestMapping(value="/users/{id}",method=RequestMethod.DELETE)
        11. @ResponseBody
        12. public String delete(@PathVariable Integer id){//从路径处传过来的变量
        13. System.out.println("user delete..."+id);
        14. return "{'module':'user delete'}";
        15. }
        16. @RequestMapping(value="/users",method=RequestMethod.PUT)
        17. @ResponseBody
        18. public String update(@RequestBody User user){
        19. System.out.println("user update..."+user);
        20. return "{'module':'user update'}";
        21. }
        22. @RequestMapping(value="/users/{id}",method=RequestMethod.GET)
        23. @ResponseBody
        24. public String getById(@PathVariable Integer id){
        25. System.out.println("user getById..."+id);
        26. return "{'module':'user getById'}";
        27. }
        28. @RequestMapping(value = "/users",method = RequestMethod.GET)
        29. @ResponseBody
        30. public String getAll(){
        31. System.out.println("user getAll...");
        32. return "{'module':'user getAll'}";
        33. }
        34. }
        35. //简化后
        36. @RestController
        37. @RequestMapping("/users")
        38. public class UserController {
        39. @PostMapping
        40. public String save(){
        41. System.out.println("user save...");
        42. return "{'module':'user save'}";
        43. }
        44. @DeleteMapping("/{id}")
        45. public String delete(@PathVariable Integer id){
        46. System.out.println("user delete..."+id);
        47. return "{'module':'user delete'}";
        48. }
        49. @PutMapping
        50. public String update(@RequestBody User user){
        51. System.out.println("user update..."+user);
        52. return "{'module':'user update'}";
        53. }
        54. @GetMapping("/{id}")
        55. public String getById(@PathVariable Integer id){
        56. System.out.println("user getById..."+id);
        57. return "{'module':'user getById'}";
        58. }
        59. @GetMapping
        60. public String getAll(){
        61. System.out.println("user getAll...");
        62. return "{'module':'user getAll'}";
        63. }
        64. }
    • 基于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、自定义项目系统级异常、业务级异常……
            1. //自定义项目系统级异常
            2. axios.get("/books").then((res)=>{});//查询
            3. axios.post("/books",this.formData).then((res)=>{});//添加
            4. axios.delete("/books"+row.id).then((res)=>{});//删除
            5. axios.put("/books",this.formData).then((res)=>{});//修改
            6. 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、添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
    • 拦截器参数:

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

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

  • 相关阅读:
    Django4 -----深入模板
    Java 正则表达式
    HTML5高级部分
    SpringBoot 接口访问频率限制
    jenkins pipline发布至docker集群
    【软件测试】—软件测试的基本流程、 网络协议应该怎么测(一)
    golang常用库之-HTTP客户端请求库 grequests
    选择商品属性弹框从底部弹出动画效果
    购物车——js小项目实例
    MySQL:你做过哪些MySQL的优化?
  • 原文地址:https://blog.csdn.net/weixin_72052233/article/details/132551217