Servlet3.0之六:@WebServlet Servlet注解
在spring boot中添加自己的Servlet有两种方法,代码注册Servlet和注解自动注册(Filter和Listener也是如此)。
- 代码注册通过ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得控制。 也可以通过实现 ServletContextInitializer 接口直接注册。
- 在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。
Servlet3.0作为J2EE 6规范一部分,并随J2EE6一起发布,WeFilter是过滤器注解,@WebServlet是Servlet注解,是Servlet3.0的新特性,不需要在web.xml进行配置,简化了配置。
一、servlet介绍
Web开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet、Filter、Listener、Interceptor 等等。这里重点是总结一下Servlet相关知识。在Servlet3.0之后,创建Servlet可以有以下方法:
- 我之前一直是自定义一个类继承HttpServlet,并把类路径配置到在web.xml中来实现得。
- 在servlet3.0以后,我们可以不用再web.xml里面配置servlet,只需要加上代码类上@WebServlet注解就可以修改该servlet的属性了。
二、@WebServlet的使用方法
在servlet3.0以后,我们可以不用再web.xml里面配置servlet,只需要加上@WebServlet注解就可以修改该servlet的属性了。
下面是@WebServlet的属性列表。
属性名 | 类型 | 描述 |
---|---|---|
name | String | 指定Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。 |
value | String[] | 该属性等价于 urlPatterns 属性。两个属性不能同时使用。 |
urlPatterns | String[] | 指定一组 Servlet 的 URL 匹配模式。等价于<url-pattern>标签。 |
loadOnStartup | int | 指定 Servlet 的加载顺序,等价于 <load-on-startup>标签。 |
initParams | WebInitParam[] | 指定一组 Servlet 初始化参数,等价于<init-param>标签。 |
asyncSupported | boolean | 声明 Servlet 是否支持异步操作模式,等价于<async-supported> 标签。 |
description | String | 该 Servlet 的描述信息,等价于 <description>标签。 |
displayName | String | 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name>标签。 |
注解Servlet这个在spring boot自动配置中正好可用。在spring boot中,嵌入式Servlet容器通过扫描注解的方式注册Servlet、Filter和Servlet规范的所有监听器(如HttpSessionListener监听器)。
Spring boot 的主 Servlet 为 DispatcherServlet,其默认的url-pattern为“/”。也许我们在应用中还需要定义更多的Servlet,该如何使用SpringBoot来完成呢?
1、通过代码注册Servlet示例代码:
package com.dxz.demo.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException;import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyServlet extends HttpServlet { private static final long serialVersionUID = -8685285401859800066L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>doGet()<<<<<<<<<<<"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>doPost()<<<<<<<<<<<"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>MyServlet doPost()</h1>"); out.println("</body>"); out.println("</html>"); } } //spring boot启动类 package com.dxz.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import com.dxz.demo.servlet.MyServlet; @SpringBootApplication public class DemoApplication { /** * 使用代码注册Servlet(不需要@ServletComponentScan注解) * @return */ @Bean public ServletRegistrationBean servletRegistrationBean() { return new ServletRegistrationBean(new MyServlet(), "/xs/*");// ServletName默认值为首字母小写,即myServlet } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
结果:
2、使用注解注册Servlet示例代码
package com.dxz.demo.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebInitParam; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name="myservlet2", //不指定name的情况下,name默认值为类全路径,即com.dxz.demo.servlet.MyServlet2 urlPatterns="/xs2/dev", loadOnStartup=1, description="用注解声明Servlet", initParams={//以下都是druid数据源状态监控的参数 @WebInitParam(name="allow",value=""),// IP白名单 (没有配置或者为空,则允许所有访问) @WebInitParam(name="deny",value=""),// IP黑名单 (存在共同时,deny优先于allow) @WebInitParam(name="loginUsername",value="dev"),// 用户名 @WebInitParam(name="loginPassword",value="123456"),// 密码 @WebInitParam(name="resetEnable",value="false")// 禁用HTML页面上的“Reset All”功能 }) public class MyServlet2 extends HttpServlet { private static final long serialVersionUID = -8685285401859800066L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>MyServlet2 doGet()<<<<<<<<<<<"); ServletConfig config= getServletConfig(); System.out.println(config.getInitParameter("loginUsername")); System.out.println(config.getInitParameter("loginPassword")); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println(">>>>>>>>>>MyServlet2 doPost()<<<<<<<<<<<"); resp.setContentType("text/html"); PrintWriter out = resp.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Hello World</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>MyServlet2 doPost()</h1>"); out.println("</body>"); out.println("</html>"); } } package com.dxz.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.DispatcherServlet; import com.dxz.demo.servlet.MyServlet; @ServletComponentScan @SpringBootApplication public class DemoApplication { /** * 修改DispatcherServlet默认配置 * @param dispatcherServlet * @return */ @Bean public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet); registration.getUrlMappings().clear(); registration.addUrlMappings("*.do"); registration.addUrlMappings("*.json"); return registration; } /** * 使用代码注册Servlet(不需要@ServletComponentScan注解) * @return */ @Bean public ServletRegistrationBean servletRegistrationBean() { return new ServletRegistrationBean(new MyServlet(), "/xs/*");// ServletName默认值为首字母小写,即myServlet } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
结果:
注意:
1、Servlet类使用@WebServlet注解;
2、Spring boot的启动类需要增加@ServletComponentScan用于扫描加载Servlet类;
3、其结果是“匹配的优先级是从精确到模糊,复合条件的Servlet并不会都执行
三、修改默认DispatcherServlet的功能
既然系统DispatcherServlet 默认拦截“/”,那么我们是否能做修改呢,答案是肯定的,我们在SpringBootSampleApplication中添加代码:
package com.dxz.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.DispatcherServlet; import com.dxz.demo.servlet.MyServlet; @ServletComponentScan @SpringBootApplication public class DemoApplication { /** * 修改DispatcherServlet默认配置 * @param dispatcherServlet * @return */ @Bean public ServletRegistrationBean dispatcherRegistration(DispatcherServlet dispatcherServlet) { ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet); registration.getUrlMappings().clear(); registration.addUrlMappings("*.do"); registration.addUrlMappings("*.json"); return registration; } /** * 使用代码注册Servlet(不需要@ServletComponentScan注解) * @return */ @Bean public ServletRegistrationBean servletRegistrationBean() { return new ServletRegistrationBean(new MyServlet(), "/xs/*");// ServletName默认值为首字母小写,即myServlet } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
下面的示例是修改url匹配规则。当然,这里可以对DispatcherServlet做很多修改,并非只是UrlMappings。
参考:http://blog.csdn.net/catoop/article/details/50501686