SpringMVC study notes-06 patrón de URL, procesamiento de recursos estáticos

1. análisis de patrones de URL

El patrón de URL se utiliza para configurar el servlet que procesa la solicitud. Tomcat elegirá a qué clase de entidad entregar la solicitud de acuerdo con la configuración del patrón de URL.

    <!--注册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>

Agreguemos recursos estáticos a la página de inicio para ver el efecto de acceso:

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

Hacer referencia a recursos estáticos en 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>

Visite index.jsp:

Visite la página html estática:

Pregunta 1: ¿Quién es responsable de procesar la solicitud para acceder al index.jsp de la página de inicio del proyecto? Tomcat, Tomcat traducirá la página JSP en el objeto Servlet correspondiente.

Pregunta 2: Quién es responsable de procesar la solicitud para acceder a jquery.js (URL de solicitud: http: // localhost: 8080 / SpringMVC_01 / js / jquery-3.5.1.js) --Tomcat

La razón es simple, js / jquery-3.5.1.js no se ajusta al mapeo del patrón * .do que configuramos para DispatcherServlet.

Pregunta 3: ¿Quién es responsable de acceder a los recursos estáticos (recursos de imágenes, URL de solicitud: http: // localhost: 8080 / SpringMVC_01 / images / 0.jpg) dentro del proyecto - Tomcat

La misma razón que la anterior

Pregunta 4: Quién es responsable de procesar la solicitud para acceder directamente a una página estática-Tomcat

La misma razón que la anterior

 

Pregunta 5: Quién es responsable de procesar una solicitud * .do - DispatcherServlet

A través del análisis anterior, probablemente podamos adivinar que el propio Tomcat puede manejar el acceso a recursos estáticos (html, imágenes, js). De hecho, hay un servlet predeterminado dentro del servidor Tomcat para manejar estas solicitudes:

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

Existe una sección de este tipo en el archivo web.xml que viene con Tomcat, lo que significa que Tomcat integra un servlet predeterminado para procesar  1. Recursos estáticos 2. Aquellas solicitudes que no están configuradas con la asignación de URL.

El servlet predeterminado se define de la siguiente manera:

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

        Si establecemos <url-pattern> en /, significa que el servlet puede usarse para procesar recursos estáticos y solicitudes que no coinciden con el servlet (o aquellas solicitudes que no son respondidas por otros servlets); si introducimos el servlet < url -pattern> está configurado en /, entonces se reemplazará el servlet predeterminado de Tomcat.

        Como dijimos antes, el patrón de URL de DispatcherServlet puede usar /, pero debido a que DispatcherServlet no tiene la capacidad de procesar recursos estáticos y el mapeo de Servlets no coincidentes de forma predeterminada, una vez que accedemos a esos recursos (imágenes, html, js, Css ) informará un error 404.

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

[Nota]: Si se encuentra que todavía es accesible, puede deberse a la función de almacenamiento en caché incorporada del navegador. En este momento, el código de estado es 304 y solo necesita limpiar la caché.        

        Pero en este caso aún se puede acceder a los recursos dinámicos:

2.Acceso a recursos estáticos SpringMVC

1. 配置 <mvc: controlador-servlet-predeterminado />

        Después de configurar <mvc: default-servlet-handler /> en springMVC-servlet.xml, se definirá un DefaultServletHttpRequestHandler en el contenedor Spring MVC, que filtrará la URL que ingresa al DispatcherServlet. Si se encuentra que es una solicitud de recurso estático , La solicitud se reenvía al Servlet predeterminado del servidor de aplicaciones Web para su procesamiento. Si no es una solicitud de recursos estáticos, DispatcherServlet continúa procesando. Generalmente, el nombre de servlet predeterminado de un servidor de aplicaciones web es "predeterminado" (como también hemos visto anteriormente, el servlet predeterminado de Tomcat es exactamente este), por lo que DefaultServletHttpRequestHandler puede encontrarlo. Si el nombre de servlet predeterminado del servidor de aplicaciones web utilizado no es "predeterminado", debe especificarlo explícitamente a través del atributo default-servlet-name:

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

        En este punto, normalmente podemos acceder a recursos estáticos como imágenes y js, ¡pero mágicamente descubriremos que los recursos dinámicos ya no son compatibles! Esto se debe a que existe un crudo conflicto entre <mvc: default-servlet-handler /> y @RequestingMapping. Si no abrimos el <mvc: annotation-drive /> controlado por anotaciones, SpringMVC entregará todos los recursos al servidor. El servlet predeterminado lo maneja, pero obviamente, no puede manejar recursos dinámicos, por lo que la configuración completa debería ser la siguiente:

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

2. Configurar <mvc: recursos>

        La configuración anterior es extremadamente simple, pero requiere que el propio servidor proporcione un servlet que maneje recursos estáticos y solicitudes no mapeadas. Si el servidor no lo tiene, no se puede usar. SpringMVC proporciona un ResourceHttpRequestHandler dedicado a procesar solicitudes de acceso a recursos estáticos.

        Después de configurar <mvc: resources> en springMVC-servlet.xml, se definirá un ResourceHttpRequestHandler en el contenedor Spring MVC, que será responsable de manejar el acceso a los recursos estáticos sin depender del servlet predeterminado del servidor.

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

        El atributo de mapeo puede usar comodines ** para indicar archivos directos, archivos de directorio de un nivel y archivos de directorio de varios niveles en una carpeta.

        Para diferentes tipos de recursos estáticos, si no están en el mismo directorio, debemos configurarlos por separado:

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

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

[Nota]: Todavía existe un conflicto entre las anotaciones <mvc: resources> y @RequestMapping, por lo que el controlador de anotaciones debe estar activado, de lo contrario, los recursos dinámicos serán inaccesibles.

Por supuesto, también podemos colocarlos en un directorio, de modo que solo se pueda configurar un mapeo.

<%@ 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. Pequeño consejo

        Como mencionamos anteriormente, en realidad / representa todas las solicitudes que no son procesadas por el servlet. Luego, cuando configuramos / para DispatcherServlet y también configuramos el acceso a recursos estáticos, ya que no agregamos ningún otro Servlet, entonces todo el marco puede manejar todas las solicitudes. En este momento, ya no necesitamos el extraño mapeo de ruta de * .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";
    }

 

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_39304630/article/details/112969416
Recomendado
Clasificación