Bootstrap

SpringMVC

目录

1. 什么是SpringMVC

​编辑

2. SpringMVC框架的优点 

3. SpringMVC时序图

4. SpringMVC执行流程图

4. 基于注解的SpringMVC框架开发的步骤

5. 分析web请求

6. @RequestMapping注解详解

7. 五种数据注入方式

8.  中文乱码解决方案

9. xxxAction中方法的返回值

10. 完成ajax请求访问服务器,返回学生集合(就是返回json数据)

json数据的接收与返回json数据补充: 

11. 五种跳转方式

12. SpringMVC默认的参数类型

13. 注入日期时进行处理

  1)日期的提交(注入)的处理

  2)日期的显示处理

14. 标签的使用

14. 资源在WEB-INF目录下

15. SpringMVC的拦截器

16. 拦截器执行的时机

17. 拦截器实现的两种方式

18. 拦截器实现的步骤

19. SSM整合的步骤


1. 什么是SpringMVC

  它是基于MVC开发模式的框架,用来优化控制器.它是Spring家族的一员.它也具备IOC和AOP.

  什么是MVC?
  它是一种开发模式,它是模型视图控制器的简称.所有的web应用都是基于MVC开发.
  M:模型层,包含实体类,业务逻辑层,数据访问层
  V:视图层,html,javaScript,vue等都是视图层,用来显现数据
  C:控制器,它是用来接收客户端的请求,并返回响应到客户端的组件,Servlet就是组件

2. SpringMVC框架的优点 

  1)轻量级,基于MVC的框架
  2)易于上手,容易理解,功能强大
  3)它具备IOC和AOP
  4)完全基于注解开发

3. SpringMVC时序图

4. SpringMVC执行流程图

4. 基于注解的SpringMVC框架开发的步骤

 1)新建项目,maven选择webapp模板.
  2)修改目录,添加缺失的test,java,resources(两套),并修改目录属性
  3)修改pom.xml文件,添加SpringMVC的依赖,添加Servlet的依赖,指定资源文件

上面的版本不行,改一下版本


  4)添加springmvc.xml配置文件,指定包扫描,添加视图解析器(ViewResoler)

 


  5)删除web.xml文件,新建web1.xml;然后再改回web.xml

  6)在web.xml文件中配置DispatcherServlet,同时表明(使用)注册springMVC框架(所有的web请求都是基于servlet的)


  7)在webapp目录下新建admin目录,在admin目录下新建main.jsp页面,删除index.jsp页面,并新建,发送请求给服务器


 

8)开发控制器(Servlet),它是一个普通的类


9)添加tomcat进行测试功能(部署的时候选长的)

 

注意不要用tomcat10,即不要用Jakarta的api;spring_mvc框架不要用5.3.18(@RequestMapping注解爆红,但是能正常使用)用5.3.22没问题

总结: 创建一个欢迎页面;欢迎页面上发送请求;先到web.xml,根据路径发现使用springmvc(创建dispatcherServlet);dispatcherServlet要干什么(创建类(对象),视图解析器)写在springmvc.xml里,并且通过<init-param>引入到web.xml;创建类(对象)执行方法,如有返回值,返回给dispatcherServlet,dispatcherServlet将返回值交给视图解析器,视图解析器根据路径解析找到服务器上面的资源,相应到浏览器

5. 分析web请求


  web请求执行的流程
                                                                                                        普通类
  index.jsp<--------------->DispatcherServlet<--------->SpringMVC的处理器就是类里一个普通的方法
  one.jsp  <--------------->DispatcherServlet<--------->SpringMVC的处理器就是类里一个普通的方法

6. @RequestMapping注解详解


  此注解就是来映射服务器访问的路径.
  1)此注解可加在方法上,是为此方法注册一个可以访问的名称(路径)
 

  2)此注解可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称

  3)此注解加载方法上还可区分get请求和post请求

7. 五种数据注入方式

使用springmvc框架提交数据到服务器,服务器会自动将数据完成类型转换,注入到xxxAction的方法中;只要按照不同方式的规则就行

注意:1234、以及13.1日期的注入属于自动注入,5属于手动注入


  1)散注入数据散提交要求方法中的参数名要和提交参数的key值一致

  页面:  

点击提交测试


  2)对象封装注入数据:创建实体类,实体类中成员变量的名称与参数的key值一致



  3)动态占位符注入(很少用)
    仅限于超链接或地址拦提交数据.它是一杠一值,一杠一大括号,使用注解@PathVariable来解析.      
    <a href="${pageContext.request.contextPath}/three/张三/22.action">动态提交</a>    
    @RequestMapping("/three/{uname}/{uage}")
    public String three(
            @PathVariable("uname")  ===>用来解析路径中的请求参数
            String name,
            @PathVariable("uage")
            int age){
        System.out.println("name="+name+",age="+(age+100));
        return "main";
    }
  4)映射名称不一致
    提交请求参数与action方法的形参的名称不一致,使用注解@RequestParam来解析
    /**
     *  姓名:<input name="name"><br>
     *  年龄:<input name="age"><br>
     */
    @RequestMapping("/four")
    public String four(
            @RequestParam("name")  ===>专门用来解决名称不一致的问题
            String uname,
            @RequestParam("age")
            int uage){
        System.out.println("uname="+uname+",uage="+(uage+100));
        return "main";
    }
  5)手工注入数据
  /**
     *  姓名:<input name="name"><br>
     *  年龄:<input name="age"><br>
     */
  @RequestMapping("/five")
    public String five(HttpServletRequest request){
        String name = request.getParameter("name");
        int age = Integer.parseInt(request.getParameter("age"));
        System.out.println("name="+name+",age="+(age+100));
        return "main";
    }  

8.  中文乱码解决方案

post方式提交数据会有中文乱码问题

例如将封装对象注入的提交方式改为"post",接收到的数据将会出现中文乱码

解决方法:

在web.xml配置过滤器.

<filter>
        <filter-name>encode</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--
          配置参数
            private String encoding;
            private boolean forceRequestEncoding;
            private boolean forceResponseEncoding;
        -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encode</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

9. xxxAction中方法的返回值


  1)String:客户端资源的地址的一部分,用于自动拼接前缀和后缀然后指定返回的路径;还可以屏蔽自动拼接字符串。


  2)Object:返回json格式的对象.自动将对象或集合转为json.使用的jackson工具进行转换,必须要添加jackson依赖.一般用于ajax请求.


  3)void:无返回值,一般用于ajax请求.


  4)基本数据类型,用于ajax请求.


  5)ModelAndView:返回数据和视图对象,现在用的很少

10. 完成ajax请求访问服务器,返回学生集合(就是返回json数据)


  1)添加jackson依赖(在添加Jackson依赖后springmvc内容的@responseBody注解负责将list转成json数组)

2)完成springmvc.xml,因为是Ajax请求所以不需要添加视图解析器,但要添加@responseBody注解的驱动,

<mvc:annotation-driven></mvc:annotation-driven>

它用来解析@ResponseBody注解

3)处理web.xml

4)在webapp目录下新建js目录,添加jQuery函数库


  3)在index.jsp页面上导入函数库,编写Ajax进行发送和接收

  4)在action方法上添加注解@ResponseBody,用来处理ajax请求

(在添加Jackson依赖后springmvc负责将list转成json数组)
 

结果:

json数据的接收与返回json数据补充: 

11. 五种跳转方式


  本质还是两种跳转:请求转发和重定向,衍生出五种是请求转发页面,转发action,重定向页面,重定向action

注意:forward和redirect会自动屏蔽视图解析器

           springmvc里面的重定向和Javaweb里面的不同之处是这里不用加项目名

           返回String类型的返回值,在默认情况下:使用视图解析器拼接前后缀,完成请求转发

12. SpringMVC默认的参数类型

不需要去创建,直接拿来使用即可.
  1)HttpServletRequest
  2)HttpServletResponse
  3)HttpSession
  4)Model
  5)Map
  6)ModelMap

  注意:Map,Model,ModelMap和request一样,都使用请求作用域进行数据传递。所以服务器端的跳转必须是请求转发。

如果用重定向方式:只有session里面有可以携带到重定向后的资源里

13. 注入日期时进行处理


  1)日期的提交(注入)的处理


    A.单个日期处理
    要使用注解@DateTimeFormat进行日期格式转换完成注入,此注解必须搭配springmvc.xml文件中的@DateTimeFormat注解的驱动

<mvc:annotation-driven></mvc:annotation-driven>

注意:使用注解@DateTimeFormat进行日期格式转换只是完成注入到Date(即将日期字符串转换为日期,完成注入)@DateTimeFormat(pattern = "yyyy-MM-dd")是表示:转换什么样的日期字符串;输出日期仍要使用格式刷刷出你想要的格式

    B.类中全局日期处理
        注册一个注解,用来解析本类中所有的日期类型,自动转换

@InitBinder
    public void initBinder(WebDataBinder webDataBinder){
        webDataBinder.registerCustomEditor(Date.class,new CustomDateEditor(simpleDateFormat,true));

        采用这种全局的处理方式不再需要单个处理的驱动了

        用数据绑定器    注册一个习惯编辑器 完成数据格式的转换;

这里用的时日期,所以里面的参数时日期相关的,new CustomDateEditor(simpleDateFormat,true)

里面的simpleDateFormat作用和单个处理中的@DateTimeFormat(pattern = "yyyy-MM-dd")相同

        

    C.日期是实体类的成员变量的日期处理

把@DateTimeFormat(pattern = "yyyy-MM-dd")表在实体类相关属性的上面或者该属性的get方法上面

  2)日期的显示处理

    如果是单个日期对象,直接转为好看的格式化的字符串进行显示(simpleDateFormat.parse())
    如果是list中的实体类对象的成员变量是日期类型,则必须使用jstl进行显示,(将对象传过去,它是Date类型的属性,如果直接获取它显示的还是不好看的那种,显示好看的那种就要转成(yyyy-MM-dd)字符串;不能再后端直接转,因为你要封装到实体类的Date属性啊,转成字符串就不能再封装到实体类里面,所以使用jstl进行处理)
    在页面上显示好看的日期,必须使用JSTL.
    步骤:
    A)添加依赖jstl

    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    B)在页面上导入标签库
    如果是单个日期对象,直接转为好看的格式化的字符串进行显示
    如果是list中的实体类对象的成员变量是日期类型,则必须使用jstl进行显示.
 

    <%--导入jstl核心标签库--%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%--导入jstl格式化标签库--%>
    <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

    C)使用标签显示数据    
 

   <table width="800px" border="1">
    <tr>
        <th>姓名</th>
        <th>生日</th>
    </tr>
        <c:forEach items="${list}" var="stu">
    <tr>
            <td>${stu.name}</td>
            <td>${stu.birthday}------ <fmt:formatDate value="${stu.birthday}" pattern="yyyy-MM-dd"></fmt:formatDate></td>
    </tr>
        </c:forEach>
    </table>

14. <mvc:annotation-driven/>标签的使用

14. 资源在WEB-INF目录下


  此目录下的动态资源,不可直接访问,也不能重定向,只能通过请求转发的方式进行访问 (这样相对安全一点)


登录的业务判断(虚假的增加安全性)

        @RequestMapping("/login")
        public String login(String name, String pwd, HttpServletRequest request){
            if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
                return "main";
            }else{
                request.setAttribute("msg","用户名或密码不正确!");
                return "login";
            }
        }
    }

这样还是存在问题,就是如果输入的路径不是login,而是能返回(或找到)main的那方法仍能访问main


15. SpringMVC的拦截器


  针对请求和响应进行的额外的处理,在请求和响应的过程中添加预处理,后处理和最终处理


16. 拦截器执行的时机


  1)preHandle():在请求被处理之前进行操作,预处理
  2)postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
  3)afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理

17. 拦截器实现的两种方式


  1)继承HandlerInterceptorAdapter的父类
  2)实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式

18. 拦截器实现的步骤


  1)改造登录方法,在session中存储用户信息,用于进行权限验证

  @RequestMapping("/login")
    public String login(String name, String pwd, HttpServletRequest request){
        if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
            //在session中存储用户信息,用于进行权限验证
            request.getSession().setAttribute("users",name);
            return "main";
        }else{
            request.setAttribute("msg","用户名或密码不正确!");
            return "login";
        }
    }


  2)开发拦截器的功能.实现HandlerInterceptor接口,重写preHandle()方法

    if(request.getSession().getAttribute("users") == null){
            //此时就是没有登录,打回到登录页面,并给出提示
            request.setAttribute("msg","您还没有登录,请先去登录!");
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
        return true;//放行请求


  3)在springmvc.xml文件中注册拦截器
 

      <mvc:interceptors>
        <mvc:interceptor>
            <!--映射要拦截的请求-->
            <mvc:mapping path="/**"/>
            <!--设置放行的请求-->
            <mvc:exclude-mapping path="/showLogin"></mvc:exclude-mapping>
            <mvc:exclude-mapping path="/login"></mvc:exclude-mapping>
            <!--配置具体的拦截器实现功能的类-->
            <bean class="com.bjpowernode.interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

19. SSM整合的步骤


  0)建库,建表


  1)新建Maven项目,选择webapp模板
  2)修改目录
  3)修改pom.xml文件

注意:在添加spring相关依赖时;要确定那些spring本身带着,那些需要额外加;只加spring的依赖会加入的依赖有


  4)添加jdbc.properties属性文件
  5)添加SqlMapConfig.xml文件(使用模板)


  6)添加applicationContext_mapper.xml文件(数据访问层的核心配置文件)
  7)添加applicationContext_service.xml文件(业务逻辑层的核心配置文件)
  8)添加spirngmvc.xml文件
  9)删除web.xml文件,新建,改名,设置中文编码,并注册spirngmvc框架,并注册Spring框架
  10)新建实体类user
  11)新建UserMapper.java接口

项目的接口文档


  12)新建UserMapper.xml实现增删查所有功能,没有更新
  13)新建service接口和实现类
  14)新建测试类,完成所有功能的测试
  15)新建控制器,完成所有功能
  16)浏览器测试功能

;