SpringMVC注解式开发

一、@RequestMapping 定义请求规则

1. 指定模块名称

通过@RequestMapping 注解可以定义处理器对于请求的映射规则

该注解可以注解在方法上,也可以注解在类上,但意义是不同的

value 属性值常以“/”开始

一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URI 是不同的

这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的value 属性中

但若这些请求具有相同的 URI 部分,则这些相同的 URI,可以被抽取到注解在类之上的@RequestMapping 的 value 属性中,此时的这个 URI 表示模块的名称

URI 的请求是相对于 Web 的根目录

下面的例子还是在第一个程序的上面进行改写

/**
 *@RequestMapping:
 * value:所有请求地址的公共部分,叫做模块名称
 * 位置:放在类的上面
 */

@Controller
@RequestMapping(value = "/test")
public class MyController {

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc");
        mv.addObject("fun","执行的是doSome方法");
        mv.setViewName("show");
        return mv;
    }


    @RequestMapping(value = "/other.do")
    public ModelAndView doOther(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc");
        mv.addObject("fun","执行的是doOther方法");
        mv.setViewName("show");
        return mv;
    }
}

此时在index.jsp中

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <p>第一个springmvc项目</p>

    <p> <a href="test/some.do">发起test/some.do的请求</a> </p>
	<p> <a href="test/other.do">发起test/other.do的请求</a> </p>
</body>
</html>

也就是把请求这些请求中相同的部分添加到了类的上面,添加了@RequestMapping(value = "/test")

2. 对请求提交方式的定义

对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交方式进行限制,即只有满足该method属性指定的提交方式的请求,才会执行该被注解方法
Method 属性的取值为 RequestMethod 枚举常量。常用的为 RequestMethod.GET 与RequestMethod.POST,分别表示提交方式的匹配规则为 GET 与 POST 提交

只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式:要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用

当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配。即对于请求的提交方式无要求

例子如下:

@Controller
@RequestMapping(value = "/test")
public class MyController {


    /**
     *@RequestMapping:请求映射
     *          属性:method:请求的方式,它的值是RequestMethod类枚举值
     */

    @RequestMapping(value = "/some.do",method = RequestMethod.GET)
    public ModelAndView doSome(){

        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc");
        mv.addObject("fun","执行的是doSome方法");

        mv.setViewName("show");

        return mv;
    }


    /**
     *
     * 获取到请求参数
     */

     @RequestMapping(value = "/other.do",method = RequestMethod.POST)
    public ModelAndView doOther(HttpServletRequest request, HttpServletResponse response
                                    , HttpSession session){

        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc,获取请求的参数:"+request.getParameter("name"));
        mv.addObject("fun","执行的是doOther方法");


        mv.setViewName("show");

        return mv;
    }
}

在index.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <p>第一个springmvc项目</p>

    <p> <a href="test/some.do">发起test/some.do的get请求</a> </p>

    <form action="test/other.do" method="post">

        name:<input type="text" name="name">
        <input type="submit" value="post请求other.do">

    </form>
</body>
</html>

二、处理器方法的参数

处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序员可在方法内直接使用

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • 请求中所携带的请求参数

1. 逐个参数

只要保证请求参数名与该请求处理方法的参数名相同即可

还是在上面的例子中,修改index.jsp页面

<h1>提交参数给Controller</h1>

    <form action="test/receive.do" method="post">

        姓名:<input type="text" name="name"><br>
        年龄:<input type="text" name="age"><br>
        <input type="submit">
        
    </form>

然后修改处理器类

@Controller
@RequestMapping(value = "/test")
public class MyController {

    /**
     * 逐个接收请求参数:
     *   要求: 处理器(控制器)方法的形参名和请求中参数名必须一致。
     *          同名的请求参数赋值给同名的形参
     *
     * 框架接收请求参数
     *   1. 使用request对象接收请求参数
     *      String strName = request.getParameter("name");
     *      String strAge = request.getParameter("age");
     *   2. springmvc框架通过 DispatcherServlet 调用 MyController的doOther()方法
     *      调用方法时,按名称对应,把接收的参数赋值给形参
     *      doOther(strName,Integer.valueOf(strAge))
     *      框架会提供类型转换的功能,能把String转为 int ,long , float, double等类型。
     *
     *  400状态码是客户端错误, 表示提交请求参数过程中,发生了问题。
     */

    @RequestMapping(value = "/receive.do")
    public ModelAndView doOther(String name, Integer age){

        // 可以直接使用name和age

        ModelAndView mv = new ModelAndView();

        // 获取到表单中的数据
        mv.addObject("myname",name);
        mv.addObject("myage",age);
        mv.setViewName("show");
        return mv;
    }

}

此时在show页面就可以的到数据了

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h1>show.jsp</h1>

    这些都是从request作用域获取到的数据
    <h2>姓名:${myname}</h2>

    <h2>年龄: ${myage}</h2>

</body>
</html>

2. 校正请求参数名@RequestParam

请求中参数名和处理器方法的形参名不一样

在index.jsp页面

  <p>请求参数名和处理器方法的形参名不一致</p>

    <form action="test/receiveparam.do" method="post">

        姓名:<input type="text" name="username"><br>
        年龄:<input type="text" name="rage"><br>
        <input type="submit">

    </form>

主要就是处理器中方法的名字和请求参数的名字不一样,这个时候需要添加注解

 /**
     *请求中参数名和处理器方法的形参名不一样
     * @RequestParam:逐个解决请求中参数名和形参名不一致的问题
     * 属性:
     *      1. value,请求中参数的名称
     *      2. required 是一个boolean,默认是true
     *          true表示请求中必须包含此参数
     * 作为:在处理器方法的形参前面定义
     */

    @RequestMapping(value = "/receiveparam.do")
    public ModelAndView receiveParam(@RequestParam(value = "username") String name,
                                     @RequestParam(value = "rage") Integer age){

        ModelAndView mv = new ModelAndView();

        // 获取到表单中的数据
        mv.addObject("myname",name);
        mv.addObject("myage",age);

        mv.setViewName("show");

        return mv;
    }

这样就可以在show页面接收到数据了

3. 请求参数中文乱码问题

对于前面所接收的post请求,若含有中文,则会出现中文乱码问题

Spring 对于请求参数中的中文乱码问题,给出了专门的字符集过滤器,解决方法:

在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题

注意:最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的

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

        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>


    <!--声明过滤器,解决post请求乱码的问题-->

    <filter>
        <filter-name>characterEncodingFilter</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>

        <!--强制请求对象(HttpServletRequest)使用encoding编码-->
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--强制请求对象(HttpServletResponse)使用encoding编码-->
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>


    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <!--
            /* : 所有的请求都会先通过这个过滤器
        -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!--这个过滤器基本上每个项目都有使用,直接用即可-->

</web-app>

4. 对象参数接收

将处理器方法的参数定义为一个对象,只要保证请求参数名与这个对象的属性同名即可

1. 定义一个Student类

package com.md.vo;

/**
 * @author MD
 * @create 2020-08-12 15:33
 */

// 用于保存请求的参数的
public class Student {

    // 属性名和请求参数名一样
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2. 在index.jsp中

<p>使用java对象来接收请求参数</p>
    <form action="test/receiveobject.do" method="post">

        姓名:<input type="text" name="name"><br>
        年龄:<input type="text" name="age"><br>
        <input type="submit">

    </form>

3. 在处理器类

package com.md.controller;

@Controller
@RequestMapping(value = "/test")
public class MyController {

    /**
     * 处理器方法形参是java对象,这个对象的属性名和请求中参数名一样
     * 框架会创建形参的java对象,给属性赋值,请求中的参数是name,框架会调用setName()
     *
     */

    @RequestMapping(value = "/receiveobject.do")
    public ModelAndView receiveObject(Student student){

        ModelAndView mv = new ModelAndView();

        // 获取到表单中的数据
        mv.addObject("myname",student.getName());
        mv.addObject("myage",student.getAge());

        mv.setViewName("show");

        return mv;
    }
}

此时show页面也是可以接收到数据的

三、处理器方法的返回值

使用@Controller 注解的处理器的处理器方法,其返回值常用的有四种类型:

  • 第一种:ModelAndView
  • 第二种:String
  • 第三种:无返回值 void
  • 第四种:返回自定义类型对象

1. 返回 ModelAndView

若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回 ModelAndView 比较好。当然,若要返回 ModelAndView,则处理器方法中需要定义 ModelAndView 对象。

在使用时,若该处理器方法只是进行跳转而不传递数据,或只是传递数据而并不向任何资源跳转(如对页面的 Ajax 异步响应),此时若返回 ModelAndView,则将总是有一部分多余:要么 Model 多余,要么 View 多余。即此时返回 ModelAndView 将不合适

之前的例子中一直用的就是这个

2. 返回 String

处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析可以将其转换为物理视图地址

例如:

在index.jsp页面中

<h1>处理器方法返回String表示视图名称</h1>

    <form action="return-view.do" method="post">

        姓名:<input type="text" name="name"><br>
        年龄:<input type="text" name="age"><br>
        <input type="submit">
        
    </form>

在springmvc.xml中配置视图解析器

<!--声明springmvc框架中的视图解析器,帮助开发人员设置视图文件路径-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />

        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp"/>

    </bean>

在处理器中,

@Controller
public class MyController {


    /**
     * 处理器方法返回String--表示逻辑视图名称,需要配置视图解析器
     */
    @RequestMapping(value = "/return-view.do")
    public String doReturnView(HttpServletRequest request,String name , Integer age){
        System.out.println("doReturnView , name="+name+" "+"age="+age);

        // 这个时候可以自己手动的添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);


        // show , 是逻辑视图名称,项目中已经配置了视图解析器
        // 在这里,框架对视图执行的是转发操作
        return "show";
    }
}    

由于配置了视图解析器,此时返回字符串show,这个字符串与视图解析器中的 prefix、suffix 相结合,即可形成要访问的 URI

当然,也可以直接返回资源的物理视图名。不过,此时就不需要再在视图解析器中再配置前辍与后辍了

 // 处理器方法返回的String,表示完整的视图路径,
    // 此时不能配置视图解析器
    @RequestMapping(value = "/return-view2.do")
    public String doReturnView2(HttpServletRequest request,String name , Integer age){
        System.out.println("---------doReturnView2--------- , name="+name+" "+"age="+age);

        // 这个时候可以自己手动的添加数据到request作用域
        request.setAttribute("myname",name);
        request.setAttribute("myage",age);


        // show , 是逻辑视图名称,项目中已经配置了视图解析器
        // 在这里,框架对视图执行的是转发操作
        return "/WEB-INF/view/show.jsp";
    }

四、返回对象Object

处理器方法也可以返回 Object 对象。这个 Object 可以是 Integer,String,自定义对象,Map,List 等。但返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现的

返回对象,需要使用@ResponseBody 注解,将转换后的 JSON 数据放入到响应体中

1. 环境搭建

由于返回 Object 数据,一般都是将数据转化为了 JSON 对象后传递给浏览器页面的。而这个由 Object 转换为 JSON,是由 Jackson 工具完成的。所以需要导入 Jackson 的相关 Jar 包

1. 在pom.xml中

<!--jackson依赖-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>

2. 声明注解驱动

将 Object 数据转化为 JSON 数据,需要由消息转换器 HttpMessageConverter 完成。而转换器的开启,需要由<mvc:annotation-driven/>来完成。

SpringMVC 使用消息转换器实现请求数据和对象,处理器方法返回对象和响应输出之间的自动转换

在springmvc.xml中添加

<!-- 加入注解驱动 -->
    <!--注意:找到结尾为mvc的driven-->
    <mvc:annotation-driven />

2. 返回自定义类型对象

返回自定义类型对象时,不能以对象的形式直接返回给客户端浏览器,而是将对象转换为 JSON 格式的数据发送给浏览器的

由于转换器底层使用了Jackson转换方式将对象转换为JSON数据,所以需要导入Jackson的相关 Jar 包

1. 定义数据类

package com.md.vo;
public class Student {

    // 属性名和请求参数名一样
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

	// set和get方法,
}

修改处理器

重点看注释

package com.md.controller;
@Controller
public class MyController {
    /**
     * 处理器方法返回一个Student,通过框架转为json,响应ajax请求
     * @ResponseBody
     *      作用:把处理器方法返回对象转为json后,通过HttpServletResponse输出给浏览器
     *      位置:方法定义的上面
     * 返回对象框架的处理流程:
     *  1. 框架会把返回Student类型,调用框架的中ArrayList<HttpMessageConverter>中每个类的canWrite()方法
     *    检查那个HttpMessageConverter接口的实现类能处理Student类型的数据--MappingJackson2HttpMessageConverter
     *
     *  2.框架会调用实现类的write(), MappingJackson2HttpMessageConverter的write()方法
     *     把林动的student对象转为json, 调用Jackson的ObjectMapper实现转为json
     *     contentType: application/json;charset=utf-8
     *
     *  3.框架会调用@ResponseBody把2的结果数据输出到浏览器, ajax请求处理完成
     */

    @RequestMapping(value = "/returnStudentJson.do")
    @ResponseBody
    public Student doStudentJson(String name , Integer age){
        // 调用service , 获取请求结果数据,Student对象表示结果数据
        Student student = new Student("林动", 20);
        // 会被框架转为json
        return student;
    }
}

在index.jsp页面

首先把jQuery导入进来,在webapp下建立js目录,jQuery复制进来就行了

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        $(function(){
            $("button").click(function(){
                $.ajax({
                   url:"returnStudentJson.do",
                    data:{
                        name:"pony",
                        age:20
                    },
                    type:"post",

                    dataType:"json",

                    success:function(resp){
                        //resp从服务器端返回的是json格式的字符串 {"name":"林动","age":20}
                        //jquery会把字符串转为json对象, 赋值给resp形参。

                        alert(resp.name + "    "+resp.age);
                    }
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">发起Ajax请求</button>
</body>
</html>

3. 返回List集合

还是在上面的基础上,修改处理器MyController

package com.md.controller;

@Controller
public class MyController {

    /**
     * 处理器方法返回的是List<Student>
     *     处理的方式和上面的一样,
     */

    @RequestMapping(value = "/returnStudentJsonArray.do")
    @ResponseBody
    public List<Student> doStudentJsonArray(String name , Integer age){

        List<Student> list = new ArrayList<>();

        // 调用service , 获取请求结果数据,Student对象表示结果数据

        Student student = new Student("林动", 20);
        Student student1 = new Student("唐三", 20);
        Student student2 = new Student("白昊天", 10);

        list.add(student);
        list.add(student1);
        list.add(student2);

        // 会被框架转为json的数组
        return list;
    }
}

此时在index.jsp页面上

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        $(function(){
            $("button").click(function(){

                $.ajax({

                    url:"returnStudentJsonArray.do",
                    data:{
                        name:"pony",
                        age:20
                    },
                    type:"post",


              		dataType:"json",

                    success:function(resp){
 
                        [{"name":"林动","age":20},{"name":"唐三","age":20},{"name":"白昊天","age":10}]
                        $.each(resp,function(i,n){
                             alert(n.name+"   "+n.age)
                        })

                    }
                })
            })
        })
    </script>
</head>
<body>

    <button id="btn">发起Ajax请求</button>

</body>
</html>

这样点击按钮就可以获取到数据了

3. 返回字符串对象

若要返回非中文字符串,将前面返回数值型数据的返回值直接修改为字符串即可。

但若返回的字符串中带有中文字符 ,则接收方页面将会出现乱码 。此时需要使用@RequestMapping 的 produces 属性指定字符集

还是修改处理器

package com.md.controller;

@Controller
public class MyController {

    /**
     * 处理器方法返回的是String , String表示数据的,不是视图。
     * 区分返回值String是数据,还是视图,看有没有@ResponseBody注解
     *
     * 如果有@ResponseBody注解,返回String就是数据,反之就是视图
     *
     *
     * 默认使用“text/plain;charset=ISO-8859-1”作为contentType,导致中文有乱码,
     * 解决方案:给RequestMapping增加一个属性 produces, 使用这个属性指定新的contentType.
     *
     *
     * 返回对象框架的处理流程:
     *  1. 框架会把返回String类型,调用框架的中ArtrayList<HtpMessageConverter>中每个类的canWrite()方法
     *     检查那个HttpMessageConverter接口的实现类能处理String类型的数据--StringHttpMessageConverter
     *
     *  2.框架会调用实现类的write(), StringHttpMessageConverter的write()方法
     *    把字符按照指定的编码处理 text/plain;charset=ISO-8859-1
     *
     *  3.框架会调用@ResponseBody把2的结果数据输出到浏览器, ajax请求处理完成
     */

    // 返回的是字符串,直接输出ajax请求,并不走过滤器,必须加属性才能解决乱码问题
    @RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8")
    @ResponseBody
    public String doStringData(String name, Integer age){

        return "我是返回的数据";
    }
}

在index.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.4.1.js"></script>
    <script type="text/javascript">
        $(function(){
            $("button").click(function(){
                $.ajax({

                    url:"returnStringData.do",
                    data:{
                        name:"pony",
                        age:20
                    },
                    type:"post",

                    // 返回文本数据
                    dataType:"text",
                    success:function(resp){

                        alert("返回的是文本数据:"+resp);

                    }
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">发起Ajax请求</button>
</body>
</html>

五、 解读url-pattern

1. *.do

在没有特殊要求的情况下,SpringMVC 的中央调度器 DispatcherServlet 的<url-pattern/>常使用后辍匹配方式,如写为*.do 或者 *.action, *.mvc

2. /

可以写为/,因为 DispatcherServlet 会将向静态资源的获取请求,例如.css、.js、.jpg、.png等资源的获取请求,当作是一个普通的 Controller 请求。中央调度器会调用处理器映射器为其查找相应的处理器,当然也是找不到的,

所以在这种情况下,所有的静态资源获取请求也均会报 404 错误

例如:

在index.jsp页面中存在一个访问图片的链接,演示将<url-pattern/>写为*.do可以访问到该图片,而写为/,则无法访问,还是在第一个例子中

1. 首先在Webapp下建立img目录,然后放一张图片

2. 然后在web.xml中

<servlet-mapping>
        <servlet-name>springmvc</servlet-name>

        <!--
            使用框架时,url-pattern可以有两种值
            1. 扩展名  *.xxx , xxx是扩展名,例如:*.do,*.action等

            2. 使用 "/"
                当你的项目中使用了 / ,它会替代Tomcat中的default
                导致所有的静态资源都给DispatcherServlet处理,而默认情况下DispatcherServlet没有处理静态资源的能力
                没有控制器对象能处理静态资源的访问,静态资源(html、js、img、css)都404

                静态资源访问不成,但动态资源可以访问,因为我们的程序写了MyController控制器对象,能处理some.do
        -->
        <!--<url-pattern>*.do</url-pattern>-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

修改index.jsp页面

<img src="img/time.jpg" alt="我是静态资源">

此时图片是显示不出来的

3. 静态资源的访问

<url-pattern/>的值并不是说写为/后,静态资源就无法访问了。经过一些配置后,该问题也是可以解决的

1. 使用<mvc:default-servlet-handler/>

声 明 了 <mvc:default-servlet-handler /> 后 , springmvc 框 架 会 在 容 器 中 创 建
DefaultServletHttpRequestHandler 处理器对象。它会像一个检查员,对进入 DispatcherServlet的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的Servlet 处理。一般的服务器都有默认的 Servlet

在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet

所以,只需要在springmvc.xml中加入这个标签即可

<!-- default-servlet-handler 和 @RequestMapping注解 有冲突, 需要加入annotation-driven 解决问题-->
    <mvc:annotation-driven />

    <!--第一种处理静态资源的方式:
        需要在springmvc配置文件加入 <mvc:default-servlet-handler>
        原理是: 加入这个标签后,框架会创健控制器对象DefaultServletHttpRequestHandler(类似我们自己创建的MyController).
        DefaultServletHttpRequestHandler这个对象可以把接收的请求转发给 tomcat的default这个servlet。
    -->
    <mvc:default-servlet-handler />

2. 使用<mvc:resources/>

在 Spring3.0 版本后,Spring 定义了专门用于处理静态资源访问请求的处理器ResourceHttpRequestHandler。并且添加了<mvc:resources/>标签,专门用于解决静态资源无法访问问题。需要在 springmvc 配置文件中添加如下形式的配置 :

   <!--第二种处理静态资源的方式
            mvc:resources 加入后框架会创建 ResourceHttpRequestHandler这个处理器对象。
            让这个对象处理静态资源的访问,不依赖tomcat服务器。
            mapping:访问静态资源的uri地址, 使用通配符 **
            location:静态资源在你的项目中的目录位置,目录不要使用/WEB-INF/及其子目录

            images/**:表示 images/time.jpg  , images/user/logo.gif , images/order/history/list.png
        -->
    <mvc:resources mapping="/img/**" location="/img/" />
    <mvc:resources mapping="/html/**" location="/html/" />
    <mvc:resources mapping="/js/**" location="/js/" />

    <!--mvc:resources和@RequestMapping有一定的冲突-->
    <mvc:annotation-driven />


    <!--通常在webapp目录下建立static目录,把使用的静态资源都放进来,这样一句话搞定-->
    <!--使用一个配置语句,指定多种静态资源的访问-->
    <!--<mvc:resources mapping="/static/**" location="/static/" />-->
posted @ 2020-08-17 22:05  山丘i  阅读(306)  评论(0编辑  收藏  举报