Web开发 web.xml中metadata-complete属性

无论是Servlet,还是Filter,Listener等,在自定义Filter时,要想使它起作用,那么必须要对它进行配置,一般都有两种配置的方式,一种是基于配置式的,另一种则是基于注解式的。

以Servlet为例

在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">
    <servlet>
        <servlet-name>mys</servlet-name>
        <servlet-class>com.mycat.web.MyFirstServlet</servlet-class>
        <init-param>
            <param-name>tom</param-name>
            <param-value>123</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mys</servlet-name>
        <url-pattern>/myser</url-pattern>
    </servlet-mapping>
</web-app>

类上注解式:(基于配置式的话,就不要使用它的配置式了,即不要同时配置该Servlet的web.xml的servlet配置和类上注解添加)

package com.mycat.web;

import javax.servlet.*;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 自定义的Servlet必须实现Servlet接口
 */
@WebServlet(value = "/myser",initParams = @WebInitParam(name="tom",value="123"))
public class MyFirstServlet implements Servlet {

    private ServletConfig servletConfig;
    private ServletRequest servletRequest;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig=servletConfig;
        System.out.println("Servlet的初始化方法...");
    }

    @Override
    public ServletConfig getServletConfig() {

        return servletConfig;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        this.servletRequest=servletRequest;

        System.out.println("service....运行时方法");
        PrintWriter writer = servletResponse.getWriter();

        System.out.println("获得Servlet的配置对象:"+this.getServletConfig());
        System.out.println("变量tom的值:"+servletConfig.getInitParameter("tom"));
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        writer.println("===============================");
        writer.println("<a href='myser2?username=2'>去myser2</a>");
    }

    @Override
    public String getServletInfo() {
        return servletRequest.getServletContext().getServerInfo();
    }

    @Override
    public void destroy() {
        System.out.println("Servlet的销毁方法...");
    }
}
1.为什么基于注解的方式可以被识别,并且可以被访问
1)先来看看@WebServlet这个注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
    String name() default "";
    String[] value() default {};
    String[] urlPatterns() default {};
    int loadOnStartup() default -1;
    WebInitParam[] initParams() default {};  // 使用:@WebInitParam(参数列表)
    boolean asyncSupported() default false;
    String smallIcon() default "";
    String largeIcon() default "";
    String description() default "";
    String displayName() default "";
}

对于Servlet来说,他有 name, value, urlpattern, loadOnStatus, initParams, asyncSupported, smallIcon, largeIcon, description, displayName 共10的属性

name: 自定义Servlet的名称 ,String类型。对应于web.xml中< servlet-name>的配置

value: 自定义 Servlet的映射模式,即等价于urlPattern属性,与urlPattern属不同同时使用,多个的话,使用逗号分隔开。参数是String[]。

urlPattern:自定义 Servlet的映射模式,即等价于value属性,与value属不同同时使用,对应于web.xml中< url-pattern>标签的配置。多个的话,使用逗号分隔开。参数是String[]。

loadOnStartup: 指定Servlet的加载顺序,等同于web.xml中< load-on-startup>标签的配置,整型数值

initParams:指定一组Servlet的初始化参数,相当于web.xml中的< init-param>标签,可以看做是Servlet的全局变量。

asyncSupported: 声明Servlet是否支持异步操作模式,等同于web.xml中< asyn-supported>标签

description: 对于Servlet的描述,等同于web.xml中< description>标签

displayName: 该Servlet的显示名,通常配合工具使用,等价于web.xml中< display-name>标签

smallIcon和largeIcon: 表示的是Servlet的显示图标,即标签页左侧的小图标。这里只是表示两个尺寸的,值为String类型的,即小图标的地址。

使用示例

loadOnStartUp: 即只是Servlet法人加载顺序,当其值为负数时,表示只有在第一次请求这个Servlet,才会被加载,当其值为0或者整数时则表示整个应用程序启动时就立即加载,而且 loadOnStartUp 越小的越先被加载。

//一个参数时,默认是value,因此可以也写成@WebServlet("/myser2"))
@WebServlet(value = "/myser2"))   
public class MySecondServlet extends HttpServlet {
    ....
@WebServlet(value = "/myser2",initParams = @WebInitParam(name="tom",value="123"))
public class MySecondServlet extends HttpServlet {
    ....
// 多个初始化参数  initParams={@WebInitParam(...),@WebInitParam(...)...}
@WebServlet(value = "/myser2",initParams = {@WebInitParam(name="username",value="tom"),@WebInitParam(name="password",value="123")})
public class MySecondServlet extends HttpServlet {
    ....
@WebServlet(value = "/myser2",initParams = @WebInitParam(name="tom",value="123"))
public class MySecondServlet extends HttpServlet {
    ....
@WebServlet(value = "/myser2",loadOnStartup = -1)
public class MySecondServlet extends HttpServlet {
    ....

分析总结

无论是基于配置配置式的,还是基于注解式的,都会提供给对应的参数,让引擎来解析为一个Servlet,但是注解的话,应该有个配置啥的来扫描:那就是web.xml中< web-app>标签的metadata-complete属性。

2)< web-app>标签的metadata-complete属性

metadata-complete属性表示部署时当前的配置是否完全,值为true,表示完全,只会应用web.xml的配置,而不会去扫描类似@WebServlet,@WebFilter,@WebListener等注解和web-frame.xml配置。默认值是metadata-complete=false,即不完全,会对项目中类进行扫描,是否有相关的注解配置,同时也会加载web-frame.xml等插件配置。

示例代码

four.jsp链接到映射到/myser4的Servlet

①默认情况:(metadata-complete=false)

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">
</web-app>

MyFourServlet代码

package com.mycat.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet("/myser4")
public class MyFourServlet implements Servlet {
    private ServletRequest servletRequest;
    private ServletConfig servletConfig;
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig=servletConfig;
        System.out.println("Servlet名称:"+servletConfig.getServletName());
        System.out.println("应用上下文路径:"+servletConfig.getServletContext().getContextPath());
    }

    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        this.servletRequest=servletRequest;
        System.out.println("运行方法...");
    }

    @Override
    public String getServletInfo() {
        return servletConfig.getServletContext().getServerInfo();
    }

    @Override
    public void destroy() {}
}

测试结果:(正常运行)

Servlet名称:com.mycat.web.MyFourServlet
应用上下文路径:/my
运行方法…

②自定义值为true情况:(metadata-complete=true)

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" metadata-complete=true
         version="4.0">
</web-app>

MyFourServlet代码

不变

测试结果:(页面运行状态 404 ,运行出错,找不到对应的Servlet)

Type Status Report

Message /my/myser4

Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

3.关于metadata-complete属性使用结论

本意是元数据书否完全(web.xml中),如果需要注解方式定义组件时,显然必须设置为false,也就是默认值

Java Web,除了使用注解方式配置过滤器外,还可以使用web.xml文件进行配置。下面是一个web.xml文件配置全局过滤器的示例: ``` <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebFilterDemo</display-name> <!-- 配置全局过滤器 --> <filter> <filter-name>ShopFilter</filter-name> <filter-class>com.example.ShopFilter</filter-class> </filter> <filter-mapping> <filter-name>ShopFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置Servlet --> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.example.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app> ``` 在以上示例,通过filter标签配置了一个名为ShopFilter的过滤器,并将其应用于所有URL路径。filter-class标签指定了过滤器的实现类。 通过filter-mapping标签将过滤器与URL路径进行映射,这里将ShopFilter过滤器映射到所有URL路径。 需要注意的是,在web.xml文件配置过滤器时,需要在web.xml文件添加`<web-app>`标签的metadata-complete属性,将其设置为true,以确保Web容器能够正确扫描和加载过滤器。 以上示例也包含了一个Servlet的配置和映射,可以在web.xml文件一起配置。通过以上配置,Web容器启动后,所有HTTP请求都会被ShopFilter过滤器拦截并处理,只有URL路径为/hello的请求才会被HelloServlet处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值