zoukankan      html  css  js  c++  java
  • SpringMVC02


    title: SpringMVC02
    date: 2020-03-11 21:48:52
    tags:


    这里是SpringMVC的所有知识点了。

    基本骨架

    依赖包

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
    
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    

    配置文件

    • 首先是web.xml,因为springMVC的底层是servlet,所以要在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">
      
          <!--    注册前端控制器-->
          <servlet>
              <servlet-name>springmvc</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
              <!--        关联springmvc的配置文件-->
              <init-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>classpath:springmvc-servlet.xml</param-value>
              </init-param>
              <!--        设置启动级别-->
              <load-on-startup>1</load-on-startup>
          </servlet>
      
      
          <!--    url-pattern
              / : 拦截所有的请求,但不包括jsp
              /* :拦截所有的请求,包括jsp
          -->
          <servlet-mapping>
              <servlet-name>springmvc</servlet-name>
              <url-pattern>/</url-pattern>
          </servlet-mapping>
      
          <!--spring官方的过滤器-->
          <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>
      
      
      </web-app>
      

      (注意的是,servlet-pattern要为 “ / ”)

    • 既然web.xml中配置了依赖的springmvc配置文件,那么就要在src---main---resources中添加springmvc的配置文件了,文件名可以随意,不过要和web.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:context="http://www.springframework.org/schema/context"
             xmlns:mvc="http://www.springframework.org/schema/mvc"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd
                                 http://www.springframework.org/schema/context
                                 https://www.springframework.org/schema/context/spring-context.xsd
                                 http://www.springframework.org/schema/mvc
                                 https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      
          <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
          <context:component-scan base-package="com.annotation.controller"/>
          <!-- 让Spring MVC不处理静态资源 -->
          <mvc:default-servlet-handler />
          <!--
          支持mvc注解驱动
              在spring中一般采用@RequestMapping注解来完成映射关系
              要想使@RequestMapping注解生效
              必须向上下文中注册DefaultAnnotationHandlerMapping
              和一个AnnotationMethodHandlerAdapter实例
              这两个实例分别在类级别和方法级别处理。
              而annotation-driven配置帮助我们自动完成上述两个实例的注入。
           -->
          <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>
      
      
      
          <!-- 视图解析器 -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
                id="internalResourceViewResolver">
              <!-- 前缀 -->
              <property name="prefix" value="/WEB-INF/jsp/" />
              <!-- 后缀 -->
              <property name="suffix" value=".jsp" />
          </bean>
      
      </beans>
      

      这个配置文件已经是完全版的了。

      支持mvc注解驱动就是<mvc:annotation-driven />

      不过这里为了解析json乱码在其中配置了一些东西,需要注意的是如果要解决全局json乱码,除了这个配置之外还要下载Jackson的包。

    controller

    原始的写法

    这里简单说一下最原始的写法,最原始的写法是实现Controller接口,这样该类就有Controller的功能了,然后实现其中的方法:

    package com.mvc.controller;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class helloController implements Controller {
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
    
            //        1.处理业务
            String res = "hello,my first springmvc demo!!";
            //        2.放入模型
            modelAndView.addObject("msg",res);
            //        3.封装要跳转的视图
            modelAndView.setViewName("test");
    
            return modelAndView;
        }
    }
    
    

    需要注意的是,因为是原始的写法,所以springmvc的配置文件中需要注册:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--    注册处理映射器-->
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        <!--    注册处理适配器-->
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    
        <!--    添加视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
            <!--        设置解析前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--        设置解析后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--    注册controller-->
        <bean id="/hello" class="com.mvc.controller.helloController"/>
    
    </beans>
    

    当今的写法

    当今的写法当然是使用注解了,需要用到如下注解:

    • @Controller :在类上使用该注解表明该类是一个Controller
    • @RequestMapping("/xxx") :在方法上使用该注解,并为其写一个请求的名字,相当于servlet的名字,重点是记得写引号中的 **/ ** !!!!

    以下是一个小例子:

    package com.annotation.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class encodingController {
    
        @RequestMapping("/encoding")
        public String test(String name, Model model){
            //将name的值存入msg中
            model.addAttribute("msg",name);
            return "hello";
        }
    }
    
    • 用注释的话,方法要接收的的参数名称需要与前端传来的数据名称相同,不过在真实开发中应该一个注释:@RequestParam("name") String name。一方面可以保持与前端数据的一致性,另一方面可以清楚的分辨出哪些参数是前端传过来的,哪些是后端的。

    • 以往的servlet传递数据都是使用request的set方法将传递的数据存放到域中,此时我们使用model来传递。

    • 如果要接收一个对象,那么前端传递过来的应该是对象的各个属性,此时直接将对象作为参数即可,springmvc框架也可以为我们解析。

      如一个User类(属性有id,name,age):

      @RequestMapping("/object")
      public String test(User user, Model model){
          //将name的值存入msg中
          model.addAttribute("msg",user.name);
          return "hello";
      }
      

      那么前端传递过来的url地址应该是:

      ip地址/项目名称/object?id=1&name=小王&age=10
      

    既然我们传递了参数,那么接下来当然是转发到我们数据需要送往的视图了,怎么转发的呢?这便是接下来的内容。

    转发和重定向

    当然,最原始的方法是像原先的servlet一样使用request和response了,那么只需向我们的方法中传入这两个参数再使用即可。既然我们是用了springmvc的框架,当然有更简单的方法:

    转发

    使用视图解析器

    如上的代码:

    @RequestMapping("/object")
    public String test(User user, Model model){
        //将name的值存入msg中
        model.addAttribute("msg",user.name);
        return "hello";
    }
    

    只需要 return 我们需要转发到的视图即可。那么他是怎么实现的呢?还记得我们配置的springmvc的配置文件吗?对。就是视图解析器的作用。

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
    

    该视图解析器会自动帮我们完成转发地址的解析

    如上方hello解析完之后便是:/WEB-INF/jsp/hello.jsp

    不使用视图解析器

    当然这是有视图解析器的情况下,当我们将视图解析器注释掉,我们可以这样写:

    @RequestMapping("/object")
    public String test(User user, Model model){
        //将name的值存入msg中
        model.addAttribute("msg",user.name);
        return "/hello.jsp";
    }
    

    或者:

    @RequestMapping("/object")
    public String test(User user, Model model){
        //将name的值存入msg中
        model.addAttribute("msg",user.name);
        return "forward:/hello.jsp";
    }
    

    两者的效果都是一样的

    重定向

    重定不需要使用视图解析器,不过需要注意路径问题:

    @RequestMapping("/object")
    public String test(User user, Model model){
        //将name的值存入msg中
        model.addAttribute("msg",user.name);
        return "redirect:/hello.jsp";
    }
    

    接受数据参数

    RestFul风格

    前边已经提及了参数的一些知识,这里补充一种规范:RestFul风格

    我们接受参数可以这样:

    @RequestMapping("/requestful/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable int b, Model model){
        int res = a + b;
        model.addAttribute("msg","res is " + res);
        return "hello";
    }
    

    这样发送过来的请求url地址便是

    ip地址/项目名称/requestful/1/2
    

    这样传递参数更加简洁,但是最重要的是更加安全,因为这样其他人根本不知道传递的参数是什么,就算知道了传递什么参数,也不知道该参数对应的键。

    限定请求方式

    @RequestMapping中还有其他参数,其中一个便是method,当我们给这个参数赋值之后,该方法便会只接受该种方式请求的url,如:

    @RequestMapping(value = "/forward",method = RequestMethod.GET)
    public String forwardTest(Model model){
        model.addAttribute("msg","forward");
        return "hello";
    }
    

    那么该方法只会接受get请求。当然实际开发中并不用每次都写上该参数,比较麻烦,每个对应的请求方式都有其对应的注释:

    • @GetMapping()
    • @PostMapping()
    • @DeleteMapping()
    • @PutMapping()

    需要使用哪种就使用哪种即可。

    参数乱码

    如果传递过来的参数中有参数,肯定会遇到乱码问题,别急,我们已经在web.xml中配置好了过滤器,是springmvc帮我们写好的现成的过滤器,可以帮助我们解决乱码的问题。

    <!--spring官方的过滤器-->
        <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>
    

    如何只展示数据?

    想起来ajax的异步请求,我们servlet返回json数据了吗?对的,使用response.getWriter().write()方法,如果访问该servlet就会在网页上显示其返回的内容,那么这里我们怎么做到呢?

    只需要在方法上再加一个注释即可:**@ResponseBody **

    这就表明只是作为反映的方法,只返回数据,不做转发或跳转

    那么整个类都是这样的,每个方法上加注释也是很麻烦,这是我们的类可以将@Controller注解换为:**@RestController **,这样就表明该类中的所有方法只做数据的返回了。

    例如:

    package com.annotation.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.annotation.pojo.User;
    import com.google.gson.Gson;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class JsonController {
    
        @RequestMapping("/json1")
        public String test1(){
            User user = new User(1, 5, "小王");
            Gson gson = new Gson();
            String toJson = gson.toJson(user);
            return toJson;
        }
    
        @RequestMapping("/json2")
        public String test2(){
            User user = new User(1, 5, "小王");
            String s = JSON.toJSONString(user);
            return s;
        }
    
    
    }
    

    既然是数据的展示,那么与前端交接,肯定是使用json了,接下来的就是json的部分。

    json

    解决json乱码

    前边的配置文件已经写到了,需要在springmvc的配置文件中进行配置:

    <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>
    

    记得下jackson的包哦!

    工具的推荐

    • jackson,使用方法网上很多。

      <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.8</version>
      </dependency>
      
    • fastjson,阿里出品

      <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.66</version>
      </dependency>
      
    • gson,一直在使用的一款,谷歌出品

      <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
      <dependency>
          <groupId>com.google.code.gson</groupId>
          <artifactId>gson</artifactId>
          <version>2.8.6</version>
      </dependency>
      

    小结

    springmvc的知识点不是很多,配置也比较少,较spring来说还是比较好理解,目前ssm三个框架已经基本掌握了一点,接下来尝试整合ssm,加油!

  • 相关阅读:
    webpack基础+webpack配置文件常用配置项介绍+webpack-dev-server
    webpack 支持的模块方法
    在nodejs中引进模块要经历的步骤
    git 学习笔记(常用命令)
    http缓存(http caching)
    http协议——cookie详解
    JavaScript实现排序二叉树的相关算法
    JavaScript将小写金额转换成大写
    React——组件的生命周期函数
    React——高阶组件
  • 原文地址:https://www.cnblogs.com/wuren-best/p/12466363.html
Copyright © 2011-2022 走看看