【Java】Servlet3规范学习笔记

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 {

        //1、根上下文
        AnnotationConfigWebApplicationContext  rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootConfiguration.class);
        sc.addListener(new ContextLoaderListener(rootContext));

        //2、springmvc上下文
        AnnotationConfigWebApplicationContext springMvcContext = new AnnotationConfigWebApplicationContext();
        springMvcContext.register(SpringMvcConfiguration.class);

        //3、DispatcherServlet
        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();
        //1、开启异步
        final AsyncContext asyncContext = req.startAsync();
        //2、设置超时时间,如果不设置如jetty是30000L
        asyncContext.setTimeout(10L * 1000); //设置为0表示永不超时

        //把任务提交给自己的任务队列
        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();
                }
            }
        });

        //4、当前线程可立即返回
    }

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 之前执行");
        //此时可以保存一些数据到异步上下文,如spring security的SecurityContextHolder或Shiro的SecurityUtils(Subject)
    }

    @Override
    public <T> void preProcess(final NativeWebRequest request, final Callable<T> task) throws Exception {
        //此时可以把在beforeConcurrentHandling保存的那些数据绑定到这个线程上(将在一个新线程执行)
        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新特性详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值