Servlet3新增功能
注解
Filter
@WebFilter(filterName = "myFilter", urlPatterns="/*",
dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD})
public class MyFilter implements Filter {
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
Listener
@WebListener
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(final ServletContextEvent ctx) {
System.out.println("init servlet context");
}
@Override
public void contextDestroyed(final ServletContextEvent ctx) {
System.out.println("destroy servlet container");
}
}
Servlet
@WebServlet(name = "myServlet",
urlPatterns = {"/servlet1", "/servlet1/*"},
loadOnStartup = 1,
initParams = {
@WebInitParam(name = "msg", value="test")
})
public class MyServlet extends HttpServlet {
private String msg;
public MyServlet() {
System.out.println("load on startup");
}
@Override
public void init() throws ServletException {
super.init();
msg = this.getInitParameter("msg");
}
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
System.out.println(msg);
}
}
SpringMVC
@Configuration
@ComponentScan(
value = {"com.test.**.service", "com.test.**.dao"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
})
@Configuration
@EnableWebMvc
@ComponentScan(
value = "com.test.**.web.controller",
includeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
})
public class SpringMvcConfiguration {
@Bean
public ViewResolver createInternalResourceViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setContentType("text/html");
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public DefaultServletHttpRequestHandler createDefaultServletHttpRequestHandler() {
return new DefaultServletHttpRequestHandler();
}
}
web.xml 代码配置
public class NoXmlWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootConfiguration.class);
sc.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext springMvcContext = new AnnotationConfigWebApplicationContext();
springMvcContext.register(SpringMvcConfiguration.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(springMvcContext);
ServletRegistration.Dynamic dynamic = sc.addServlet("dispatcherServlet", dispatcherServlet);
dynamic.setLoadOnStartup(1);
dynamic.addMapping("/");
}
}
异步处理
@WebServlet(name = "asyncServlet", urlPatterns = "/async", asyncSupported = true)
private final ExecutorService executorService = Executors.newScheduledThreadPool(2);
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Connection", "Keep-Alive");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("hello async");
out.write("<br/>");
out.flush();
final AsyncContext asyncContext = req.startAsync();
asyncContext.setTimeout(10L * 1000);
executorService.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3L * 1000);
PrintWriter out = asyncContext.getResponse().getWriter();
out.write("over");
asyncContext.complete();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
interceptor
public class MyCallableInterceptor extends CallableProcessingInterceptorAdapter {
@Override
public <T> void beforeConcurrentHandling(final NativeWebRequest request, final Callable<T> task) throws Exception {
System.out.println("=====在startAsyc开启异步 和 提交异步任务到Executor 之前执行");
}
@Override
public <T> void preProcess(final NativeWebRequest request, final Callable<T> task) throws Exception {
System.out.println("在Callable.call运行之前执行");
}
@Override
public <T> void postProcess(final NativeWebRequest request, final Callable<T> task, final Object concurrentResult) throws Exception {
System.out.println("在Callable.call运行之后执行");
}
@Override
public <T> Object handleTimeout(final NativeWebRequest request, final Callable<T> task) throws Exception {
System.out.println("异步任务超时了");
return "error";
}
@Override
public <T> void afterCompletion(final NativeWebRequest request, final Callable<T> task) throws Exception {
System.out.println("异步任务完成了");
}
}
@Controller
public class MyCallableController {
@RequestMapping("/myCallable1")
@ResponseBody
public Callable<String> callable1() {
return new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("====执行Callable call");
return "success";
}
};
}
@RequestMapping("/myCallable2")
@ResponseBody
public Callable<String> callable2() {
return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(31L * 1000);
System.out.println("====执行Callable call");
return "success";
}
};
}
}
/**
* spring实现方式:
* 1、把任务提交给Executor 异步执行;
* 2、执行完成后RequestMappingHandlerAdapter使用内部的 ServletInvocableHandlerMethod包装返回值,即按照非异步方式再执行
*/
@Controller
public class CallableController {
@RequestMapping("/callable1")
public Callable<String> callable1(final Model model) {
return new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2L * 1000);
String viewName = "msg";
model.addAttribute("msg", "hello callable");
return viewName;
}
};
}
@RequestMapping("/callable2")
public Callable<ModelAndView> callable2() {
return new Callable<ModelAndView>() {
@Override
public ModelAndView call() throws Exception {
Thread.sleep(2L * 1000);
ModelAndView mv = new ModelAndView("msg");
mv.addObject("msg", "hello callable");
return mv;
}
};
}
@RequestMapping("/callable3")
@ResponseBody
public Callable<Object> callable3() {
return new Callable<Object>() {
@Override
public Object call() throws Exception {
Thread.sleep(2L * 1000);
return new User(1, "zhang");
}
};
}
}
参考博客
Servlet3新特性详解