SpringMVC study notes-06 url-pattern, static resource processing

1. url-pattern analysis

The url-pattern is used to configure the servlet that processes the request. Tomcat will choose which entity class to deliver the request to according to the url-pattern configuration.

    <!--注册DispatcherServlet,配置Tomcat启动后就创建-->
    <servlet>
        <!--SpringMVC容器创建时,读取的配置文件默认为<servlet-name>-servlet.xml-->
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>
            <!--自定义SpringMVC读取的配置文件的位置-->
            <param-name>contextConfigLocation</param-name>
            <!--类路径下的springmvc.xml文件(resources目录就是类路径)-->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>

        <!--Tomcat启动后,创建对象的顺序-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--配置DispatcherServlet拦截哪些请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--
            使用框架时,url-pattern可以使用两种
            1. 扩展名  *代表通配符,匹配任意长度的路径  只看扩展名  *.do *.action 等
            2. 使用 "/"
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

Let's add static resources to the home page to see the access effect:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    这是一个静态页面
</body>
</html>

Reference static resources in index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="js/jquery-3.5.1.js"></script>
    <script type="text/javascript">
        $(function () {
            $("button").click(function () {
                $.ajax({
                    url:"test/returnStringAjax.do", // 请求路径
                    data:{ // 请求的数据
                        name:"zzt",
                        age:21
                    },
                    type:"post", // 请求方式
                    dataType:"text",
                    success:function (resp) { // resp结果数据解析后的结果
                        alert("返回文本数据:" + resp);
                    }
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">发起Ajax请求</button>
    <br>
    <img src="images/0.jpg" alt="图片无法正常显示"/>
</body>
</html>

Visit index.jsp:

Visit static html page:

Question 1: Who is responsible for processing the request to access the index.jsp of the project homepage-Tomcat, Tomcat will translate the JSP page into the corresponding Servlet object

Question 2: Who is responsible for processing the request to access jquery.js (Request URL: http://localhost:8080/SpringMVC_01/js/jquery-3.5.1.js)--Tomcat

The reason is simple, js/jquery-3.5.1.js does not conform to the mapping of the *.do pattern we configured for DispatcherServlet.

Question 3: Who is responsible for accessing the static resources (picture resources, Request URL: http://localhost:8080/SpringMVC_01/images/0.jpg) inside the project--Tomcat

Same reason as above

Question 4: Who is responsible for processing the request to directly access a static page-Tomcat

Same reason as above

 

Question 5: Who is responsible for processing a *.do request--DispatcherServlet

Through the above analysis and analysis, we can probably guess that Tomcat itself can handle the access of static resources (html, pictures, js). In fact, there is a default servlet inside the Tomcat server to handle these requests:

  <!-- The default servlet for all web applications, that serves static     -->
  <!-- resources.  It processes all requests that are not mapped to other   -->
  <!-- servlets with servlet mappings (defined either here or in your own   -->
  <!-- web.xml file).  This servlet supports the following initialization   -->

There is such a section in the web.xml file that comes with Tomcat, which means that Tomcat integrates a default servlet to process  1. Static resources 2. Those requests that are not configured with URL mapping.

The default servlet is defined as follows:

    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- The mapping for the default servlet -->
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

        If we set <url-pattern> to /, it means that the servlet can be used to process static resources and requests that do not match the servlet (or those requests that are not responded by other servlets); if we introduce the servlet's <url -pattern> is set to /, then Tomcat's default Servlet will be replaced.

        As we said before, the url-pattern of DispatcherServlet can indeed use /, but because DispatcherServlet does not have the ability to process static resources and the mapping of unmatched Servlets by default, once we access those resources (pictures, html, js , Css) will report a 404 error.

    <servlet>
        <!--SpringMVC容器创建时,读取的配置文件默认为<servlet-name>-servlet.xml-->
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>
            <!--自定义SpringMVC读取的配置文件的位置-->
            <param-name>contextConfigLocation</param-name>
            <!--类路径下的springmvc.xml文件(resources目录就是类路径)-->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>

        <!--Tomcat启动后,创建对象的顺序-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--配置DispatcherServlet拦截哪些请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--
            使用框架时,url-pattern可以使用两种
            1. 扩展名  *代表通配符,匹配任意长度的路径  只看扩展名  *.do *.action 等
            2. 使用 "/"
        -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

[Note]: If it is found that it is still accessible, it may be caused by the browser’s built-in caching function. At this time, the Status Code is 304, and you only need to clean up the cache.        

        But in this case dynamic resources can still be accessed:

2.SpringMVC static resource access

1. 配置<mvc:default-servlet-handler/>

        After configuring <mvc:default-servlet-handler /> in springMVC-servlet.xml, a DefaultServletHttpRequestHandler will be defined in the Spring MVC container, which will screen the URL that enters the DispatcherServlet. If it is found to be a static resource request, The request is forwarded to the default Servlet of the Web application server for processing. If it is not a request for static resources, the DispatcherServlet continues processing. Generally, the default servlet name of a web application server is "default" (as we have also seen above, Tomcat's default servlet is exactly this), so DefaultServletHttpRequestHandler can find it. If the default servlet name of the web application server used is not "default", you need to explicitly specify it through the default-servlet-name attribute:

<mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />

        At this point, we can normally access static resources such as pictures and js, but we will magically find that dynamic resources are not supported anymore! This is because there is a crude conflict between <mvc:default-servlet-handler/> and @RequestingMapping. If we do not open the annotation-driven <mvc:annotation-driven/>, SpringMVC will give all resources to the server The default servlet handles it, but obviously, he cannot handle dynamic resources, so the complete configuration should be as follows:

    <!--配置注解驱动-->
    <mvc:annotation-driven/>
    
    <!--静态资源处理 方式1-->
    <mvc:default-servlet-handler/>

2. Configure <mvc:resources>

        The above configuration is extremely simple, but it requires the server itself to provide a servlet that handles static resources and unmapped requests. If the server does not have it, it cannot be used. SpringMVC provides a ResourceHttpRequestHandler dedicated to processing static resource access requests.

        After configuring <mvc:resources> in springMVC-servlet.xml, a ResourceHttpRequestHandler will be defined in the Spring MVC container, which will be responsible for handling access to static resources without relying on the default servlet of the server.

<mvc:resources location="静态资源目录" mapping="对该静态资源的请求路径"/>

        The mapping attribute can use wildcard ** to indicate direct files, one-level directory files, and multi-level directory files under a folder.

        For different kinds of static resources, if they are not in the same directory, we need to configure them separately:

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--静态资源处理 方式2-->
    <mvc:resources mapping="/images/**" location="/images/" />
    <mvc:resources mapping="/html/**" location="/html/" />
    <mvc:resources mapping="/js/**" location="/js/" />

[Note]: There is still conflict between the <mvc:resources> and @RequestMapping annotations, so the annotation driver needs to be turned on, otherwise the dynamic resources will be inaccessible.

Of course, we can also place them in a directory, so that only one mapping can be configured.

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="static/js/jquery-3.5.1.js"></script>
    <script type="text/javascript">
        $(function () {
            $("button").click(function () {
                $.ajax({
                    url:"test/returnStringAjax.do", // 请求路径
                    data:{ // 请求的数据
                        name:"zzt",
                        age:21
                    },
                    type:"post", // 请求方式
                    dataType:"text",
                    success:function (resp) { // resp结果数据解析后的结果
                        alert("返回文本数据:" + resp);
                    }
                })
            })
        })
    </script>
</head>
<body>
    <button id="btn">发起Ajax请求</button>
    <br>
    <img src="static/images/0.jpg" alt="图片无法正常显示"/>
</body>
</html>

3. Small Tip

        As we mentioned above, actually/represents all requests that are not processed by servlet. Then when we configure/ for DispatcherServlet and also configure static resource access, since we did not add any other Servlet, then the whole framework It can handle all requests. At this time, we no longer need the strange path mapping of *.do:

        $(function () {
            $("button").click(function () {
                $.ajax({
                    url:"test/returnStringAjax", // 请求路径
                    data:{ // 请求的数据
                        name:"zzt",
                        age:21
                    },
                    type:"post", // 请求方式
                    dataType:"text",
                    success:function (resp) { // resp结果数据解析后的结果
                        alert("返回文本数据:" + resp);
                    }
                })
            })
        })
    @ResponseBody
    @RequestMapping(value = "/returnStringAjax", produces = "text/plain;charset=utf-8")
    public String doReturnStringAjax(){
        return "返回的是字符串不是数据--SpringMVC";
    }

 

 

 

Guess you like

Origin blog.csdn.net/qq_39304630/article/details/112969416