使用Spring开发web程序,在大部分情况下,都是通过Spring默认的DispatcherServlet,转发请求到Controller,我们在Controller里处理请求。但有时候,可能有些请求我们不希望通过Spring,而是通过其他Servlet处理。如果是普通的Spring项目,注册Filter和Servlet只需在web.xml时添加filter、filter-mapping、servlet、servlet-mapping,但Spring boot项目里没有web.xml。 Spring boot有两种方法注册Servlet和Filter:代码注册、注解注册。 先写个简单的Servlet:
@Slf4j
public class TestServlet extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
String value=config.getInitParameter("param1");
log.info("param1:{}",value);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("Hello");
out.println("</body>");
out.println("</html>");
}
}
代码注册:
代码注册通过ServletRegistrationBean和FilterRegistrationBean两个类,注册Servlet和Filter。 在Application类里添加注册代码:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ServletRegistrationBean testServletBean() {
ServletRegistrationBean testServletRegistration = new ServletRegistrationBean(new TestServlet(), "/test1/");
Map<String,String> params = new HashMap<>();
params.put("param1","value2");
testServletRegistration.setInitParameters(params);
return testServletRegistration;
}
}
三个参数,servlet实例、url mapping、init-param, Filter也类似,只是用FilterRegistrationBean。 或者,放到一个单独的配置类里:
@Configuration
public class ServletConfiguration {
@Bean
public ServletRegistrationBean testServletBean() {
ServletRegistrationBean testServletRegistration = new ServletRegistrationBean(new TestServlet(), "/test1/");
Map<String,String> params = new HashMap<>();
params.put("param1","value2");
testServletRegistration.setInitParameters(params);
return testServletRegistration;
}
}
建议拆开放到单独的类里,如果所有配置都放Application里,乱。
注解注册
注解注册需要在Servlet类上加上@WebServlet,@WebFilter注解,Application里加上@ServletComponentScan开启Servlet注解扫描。 修改TestServlet
@Slf4j
@WebServlet(urlPatterns = "/test/*",initParams = {
@WebInitParam(name = "param1", value = "value1"),
})
public class TestServlet extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
String value=config.getInitParameter("param1");
log.info("param1:{}",value);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World</title>");
out.println("</head>");
out.println("<body>");
out.println("Hello");
out.println("</body>");
out.println("</html>");
}
}
如果是Filter:
@WebFilter(filterName = "webFilter", urlPatterns = "/*",
initParams = {@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico")
})
public class WebFilter extends Filter {
}
Application:
@SpringBootApplication
@ServletComponentScan
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
怎么选择?
如果是自己实现的Servlet,那么直接加个注解,即可注册。但Servlet不是自己实现的话,用代码注册比较好,否则需要继承原来的Servlet加一个子类。