zoukankan      html  css  js  c++  java
  • SpringMVC学习笔记

    Spring MVC

    工作原理

    • 用户发送请求至前端控制器(DispatcherServlet)。
    • 前端控制器委托请求至Controller。
    • Controller再去调用Model(service、dao)去请求数据。
    • 数据请求回来再由Controller响应至前端控制器。
    • 前端控制器将响应来的数据在视图层渲染。
    • 最后将数据显示给用户。

    SPring MVC 的web围绕DispatcherServlet设计,DispathcherServlet可以将请求分发到不同的控制器。

    DispatcherServlet本质也是servlet

    SpringMVC流程:

    1. 用户发送请求,请求到前端控制器webapp.xml(DispatcherServlet)
    2. DispatcherServlet将请求交给处理器(controller)
    3. 控制器去调用业务对象(service)并拿到结果返回一个ModelAndView(模型装数据,并且添加一个视图的名字)给前端控制器webapp.xml(DispatcherServlet)
    4. 前端控制器去将数据渲染至视图中。
    5. 返回至用户

    搭建SpringMVC

    1. pom.xml添加依赖

      <!--导入依赖-->
          <dependencies>
              <!--单元测试-->
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
              </dependency>
      
              <!--spring框架-->
              <dependency>
                  <groupId>org.springframework</groupId>
                  <artifactId>spring-webmvc</artifactId>
                  <version>5.1.9.RELEASE</version>
              </dependency>
      
              <!--servlet-->
              <dependency>
                  <groupId>javax.servlet</groupId>
                  <artifactId>servlet-api</artifactId>
                  <version>2.5</version>
              </dependency>
      
              <!--jsp-->
              <dependency>
                  <groupId>javax.servlet.jsp</groupId>
                  <artifactId>jsp-api</artifactId>
                  <version>2.2</version>
              </dependency>
      
              <!--jstl标签库-->
              <dependency>
                  <groupId>javax.servlet</groupId>
                  <artifactId>jstl</artifactId>
                  <version>1.2</version>
              </dependency>
      
          </dependencies>
      
    2. 注册DispatcherServlet至web.xml。

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
      
          <!--注册DispatcherServlet-->
          <servlet>
              <servlet-name>springmvc</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      
              <!--关联一个springmvc的配置文件,【param-name】-servlet.xml-->
              <init-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>classpath*:springmvc-servlet.xml</param-value>
              </init-param>
      
              <!--启动级别-1-->
              <load-on-startup>1</load-on-startup>
          </servlet>
      
          <!--/匹配所有请求(不包括.jsp)-->
          <!--/*匹配所有请求(包括.jsp)-->
          <servlet-mapping>
              <servlet-name>springmvc</servlet-name>
              <url-pattern>/</url-pattern>
          </servlet-mapping>
      </web-app>
      
    3. 配置springmvc-servlet.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:mvc="http://www.springframework.org/schema/mvc"
             xmlns:context="http://www.springframework.org/schema/context"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
      		http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
      		http://www.springframework.org/schema/mvc
      		http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
      		http://www.springframework.org/schema/context
      		http://www.springframework.org/schema/context/spring-context-3.2.xsd
      		http://www.springframework.org/schema/aop
      		http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
      		http://www.springframework.org/schema/tx
      		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
      
          <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
          <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
      
          <context:component-scan base-package="com.sx.controller"></context:component-scan>
          <mvc:annotation-driven/>
      
          <!--视图解析器:DispatcherServlet 给他的 ModelAndView
            1.获取一个ModelAndView数据
            2.解析ModelAndView视图名
            3.拼接视图名,找到对应的视图
            4.将数据渲染到视图
        -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
              <!--前缀-->
              <property name="prefix" value="/"/>
              <!--后缀-->
              <property name="suffix" value=".jsp"/>
          </bean>
      </beans>
      
    4. 在webapp创建对应视图。(jsp等)

    5. 创建controller(加入controller注解将它装配到bean)。

    6. 创建方法,处理数据,返回字符串,字符串就是视图的名字,会被视图解析器处理。

    7. 加入@ReauestMapping("请求名")。(类上也可以加ReauestMapping)相当于多访问一层。

    关于重定向和转发

    • 使用视图解析器的话,return视图名称默认就是转发
    • 重定向的话,在return的视图字符串中加入redirect:即可。

    关于前端提交数据

    提交数据

    • 数据名和形参列表名相同的话可直接接收。

    • 数据名和形参列表名不同的话需加入RequestParam("")注解转换(尽量全部加上)。

    • 前端提交实体类可以用实体类去接收。

    对象和json转换

    后端向前端传递json字符串

    • jackson包

       <!--jackson:对后端的json字符串进行转换的工具-->
              <dependency>
                  <groupId>com.fasterxml.jackson.core</groupId>
                  <artifactId>jackson-databind</artifactId>
                  <version>2.9.8</version>
              </dependency>
      

      可将对象/List/SimpleDateFormat等类型转换为json类型

      ObjectMapper mapper = new ObjectMapper();
      String user = mapper.writeValueAsString(new User(1, "张三", "女"));
      

      使用writeValueAsString获取时间并以json类型响应至前端

      		//关闭日期转换为时间戳
              mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
              //指定日期格式
              SimpleDateFormat sdf = new SimpleDateFormat("yyyy-YY-dd HH:mm:hh");
              //SimpleDateFormat转为String
              mapper.writeValueAsString(sdf);
              //new一个Date
              Date date = new Date();
              return mapper.writeValueAsString(date);
      
    • @RequestBody

      将服务器端返回的对象转换为json对象响应回去

    • 出现中文???解决方法:

      1. @RequestMapping注解上加入produces = "application/json;charset=utf-8"

        @RequestMapping(value = "/test",produces = "application/json;charset=utf-8")
        
      2. 在springmvc核心配置文件中加入

         <!--解决后端向前端传josn字符串时中文?的问题-->
            <mvc:annotation-driven>
                <mvc:message-converters register-defaults="true">
                    <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                        <constructor-arg value="UTF-8"/>
                    </bean>
        
                    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                        <property name="objectMapper">
                            <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                                <property name="failOnEmptyBeans" value="false"/>
                            </bean>
                        </property>
                    </bean>
                </mvc:message-converters>
            </mvc:annotation-driven>
        

    前端json和对象类型的互换

    <script type="text/javascript">
        var user = {
            ID:1,
            name:"sx",
            gender:"男"
        }
       
       	//对象转json
        var s = JSON.stringify(user);
        //json转对象
        var user =  JSON.parse(s);
    </script>
    

    AJAX异步交互

    AJAX是一种无需重新加载整个网页的情况下,能够更新部分网页的技术。可以增强B/S的体验性

    AJAX例子:

    • 注册时,输入用户名可直接提示用户名是否可用。
    • 登陆时提示用户名密码错误。
    • 删除数据时,将ID发送到后台,后台在数据库删除后,页面DOM处也进行删除。

    使用AJAX

    1. 导入jQuery文件

    2. 对应事件函数中写ajax主体

      $.ajax({
              url:"ajaxTest",  //请求地址
              data:{  //传入参数
                name:$("#textName").val()
              },
              success:function (data) {  //执行成功返回数据  data为return的数据
                alert(data)  
                var user = JSON.parse(data);
              console.log(user);
              }
            });
      
    3. 对应controller

      @RequestMapping("ajaxTest")  //接收请求
          @ResponseBody  //转json
          String ajaxTest(String name) throws IOException {
              System.out.println(name);
              if ("admin".equals(name)){
                  ObjectMapper mapper = new ObjectMapper();  //jackson方法
                  String s = mapper.writeValueAsString(new User(4,"赵六","男"));
                  return s;  //返回的data
              }else {
                  return null;
              }
          }
      

    RestFul风格

    Restful风格是一种资源定位操作的风格,不是标准也不是协议,只是一种风格。基于这和风格设计可以更简洁,更有层次,更容易实现缓存等机制。

    • 请求方式:使用POST,GET,PUT,DELETE等不同方法对资源进行操作。
    • 分别对应:添加、查询、修改、删除

    使用Restful风格可以通过不同的请求方式来实现不同的效果。请求地址栏一样,但功能不同!

    //@RequestMapping(value ="/test/{a}/{b}",method = RequestMethod.GET)
    @GetMapping("/test/{a}/{b}")
        public String allUser(@PathVariable int a , @PathVariable int b , Model md){
            int res = a+b;
            md.addAttribute("s",res);
            return "test";
        }
    
    1. controller形参列表处,每个形参前加上注解@PathVariable
    2. Mapping注解在请求地址后加上参数 @GetMapping("/test/{a}/{b}")
    3. 选用不同请求可使用不同注解,也可在@RequestMapping注解中加入method = RequestMethod.GET

    浏览器效果:http://localhost:8080/test/2/8

    • 使用RestFul风格可使请求名复用(相同请求名使用不同请求方式)
    • 可在地址栏隐藏参数名

    SpringMVC拦截器

    过滤器:

    • servlet规范中的一部分,任何java web工程都可以使用
    • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
    <!--乱码过滤器-->
    <filter>
            <filter-name>encoding</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>utf-8</param-value>
            </init-param>
        </filter>
        
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>/</url-pattern>
        </filter-mapping>
    

    拦截器:

    SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。拦截器是AOP思想的具体应用。

    • 拦截器是SpringMVC自己的,只有使用了SpringMVC自己的工程才能使用。
    • 拦截器只会拦截访问控制器的方法。如果访问jsp/html/css/image/js等静态资源是不会进行拦截的(减少资源损耗)。

    实现拦截器

    • 写一个类,实现HandlerInterceptor接口,可选重写三个方法

      public class MyInterceptor implements HandlerInterceptor {
          //return true;会放行,执行下一个拦截器/return false;会卡死,不执行下一个拦截器
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              System.out.println("处理前-------------------");
              return true;
          }
          //拦截日志
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
              System.out.println("处理后-------------------");
          }
          //拦截日志
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
              System.out.println("清理-------------------");
          }
      }
      
    • 因为使用了AOP所以必须在xml中配置。

        <!--配置拦截器-->
          <mvc:interceptors>
              <mvc:interceptor>
                  <!--
                  path:处理请求路径
                  /只拦截一个请求
                  /**拦截一个请求下的所有请求
                  -->
                  <mvc:mapping path="/**"/>
                  <bean class="com.sx.config.MyInterceptor"/>
              </mvc:interceptor>
          </mvc:interceptors>
      

    文件上传

    前端操作

    • 在表单属性中加入multipart/form-data,这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
    	<form action="" enctype="multipart/form-data" method="post">
        	<input type="file" name="file">
        	<input type="submit" value="sub">
        </form>
    

    后端操作

    springMVC对文件上传提供了专门的支持,这种支持是即插即用的MultipartResolver实现的。

    • 导入文件上传的jar包,commons-fileupload,Maven会自动帮我们导入他的依赖包。

       		<!--文件上传-->
              <dependency>
                  <groupId>commons-fileupload</groupId>
                  <artifactId>commons-fileupload</artifactId>
                  <version>1.3.3</version>
              </dependency>
              <!--io包-->
              <dependency>
                  <groupId>commons-io</groupId>
                  <artifactId>commons-io</artifactId>
                  <version>2.4</version>
              </dependency>
              <!--更高版本的servlet-api-->
              <dependency>
                  <groupId>javax.servlet</groupId>
                  <artifactId>javax.servlet-api</artifactId>
                  <version>4.0.1</version>
              </dependency>
      
    • 在xml文件中配置

      <!--文件上传配置-->
          <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
             <!--编码格式必须和jsp的pageEncoding属性一致,以便正确读取表单内容-->
              <property name="defaultEncoding" value="utf-8"/>
              <!--上传限制大小,字节(10485760=10M)-->
              <property name="maxUploadSize" value="10485760"/>
              <property name="maxInMemorySize" value="40960"/>
          </bean>
      
    • controller

      @RequestMapping("test")
          public String allUser(MultipartFile inFile) throws IOException {
              String filePath = "D:\";  //本地路径
              if (!inFile.isEmpty()){  //文件是否为空
                  String originalFilename = inFile.getOriginalFilename();  //获取上传的文件名
                  originalFilename = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf(".")); //避免名称相同,上传文件名改为UUID名+原文件名后缀
                  File file = new File(filePath, originalFilename);
                  inFile.transferTo(file);
              }
              return "test";
          }
      
  • 相关阅读:
    P2890 [USACO07OPEN]Cheapest Palindrome G 题解
    「NOIP2021模拟赛 By JXC C」位运算 题解
    AT5759 ThREE 题解
    P7532 [USACO21OPEN] Balanced Subsets P 题解
    linux下的pdf分割合并软件
    Python小练习 SDUT 2521 出现次数
    小问题备查持续更新
    Python小练习自动登录人人发送消息并返回好友列表
    Debian系使用小红点
    linux权限问题学习总结
  • 原文地址:https://www.cnblogs.com/sxblogs/p/13054937.html
Copyright © 2011-2022 走看看