zoukankan      html  css  js  c++  java
  • Spring MVC 异步测试

    从spring3.2开始,支持servlet3的异步请求,这对于处理耗时的请求如缓慢的数据库查询是非常有好处的,不至于很快的耗光servlet的线程池,影响可扩展性。
    让我们先来了解一下servlet是怎么处理异步操作的:

    1. 通过调用request.startAsync(),ServletRequest就变成异步模式。主要的影响是Servlet、Filter会退出,但是Response保持打开用来完成请求处理。
    2. 调用request.startAsync()返回AsyncContext实例,可进一步控制异步处理。例如,它提供dispatch方法,可 以从应用线程调用以分发请求回Servlet容器。异步调度和forward的方式是相似的,但是异步调度是由应用线程到Servlet容器线程产生的, 而forward的方式是同时发生在相同的Servlet容器线程。
    3. ServletRequest提供当前的DispatcherType,它可以用来在异步调度中区分正在处理的初始请求线程是Servlet还是Filter。

    接着来看一下callable是怎么处理异步操作的:

    1. Controller返回一个Callable实例;
    2. Spring MVC开始异步处理并在一个单独的线程中,提交Callable实例给TaskExecutor处理;
    3. DispatcherServlet和所有的Filter退出请求线程但是response保存打开;
    4. Callable返回结果,Spring MVC分发请求回Servlet容器;
    5. DispatcherServlet重新调用并继续处理从Callable实例中异步返回的结果。

    现在来看一下代码是怎么实现的

    1、pom.xml

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
     
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>3.2.13.RELEASE</version>
    </dependency>
     
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>3.2.13.RELEASE</version>
    </dependency>
     

    2、applicationContext-mvc.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:task="http://www.springframework.org/schema/task"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
           http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
           ">
     
        <context:component-scan base-package="com.test"/>
     
        <mvc:annotation-driven>
            <!-- 配置超时时间 -->
            <mvc:async-support default-timeout="3000">
                <!-- 这里可以配置callable或者deferred-result拦截器 -->
            </mvc:async-support>
        </mvc:annotation-driven>
    </beans>

    3、web.xml  , 当有 很多 filter 时,filter 也一定要添加异步支持

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app
            xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
            version="3.0">
         
        <filter>
            <filter-name>characterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
            <async-supported>true</async-supported>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <param-name>forceEncoding</param-name>
                <param-value>true</param-value>
            </init-param>
        </filter>
    
        <filter-mapping>
            <filter-name>characterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath*:applicationContext-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
            <async-supported>true</async-supported>
        </servlet>
     
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>

    web.xml需要声明web-app_3_0.xsdversion=”3.0″,启用异步支持<async-supported>true</async-supported>
    4、CallableController.java

    package com.test.controller;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;
     
    import java.util.concurrent.Callable;
     
    /**
     * spring实现方式:
     *  1、把任务提交给Executor异步执行
     */
    @Controller
    public class CallableController {
     
        @RequestMapping(value = "/callable1", method = RequestMethod.GET)
        public Callable<String> callable1(final ModelMap modelMap) {
            return new Callable<String>() {
                public String call() throws Exception {
                    Thread.sleep(2 * 1000L); //暂停2秒return "hello callable";
                }
            };
        } 
    }

    5,tomcat 部分,如果 tomcat 部署有 session  分页式缓存插件,则在插件配置的地方,也要添加异步支持:

      

        <!-- redis 缓存支持  --> 
    <Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" asyncSupported="true" /> <Manager className="com.radiadesign.catalina.session.RedisSessionManager" host="localhost" port="6379" database="0" maxInactiveInterval="60" />

    6, 启动服务,测试:

     http://localhost:8088/test/callable1

    
    

    7, rsp:

        hello callable

  • 相关阅读:
    前端开发:如何正确地跨端?
    开源微服务运行时 Dapr 发布 1.0 版本
    Flink 如何实时分析 Iceberg 数据湖的 CDC 数据
    为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?
    Serverless 如何在阿里巴巴实现规模化落地?
    altas(ajax)控件(十三):悬浮菜单HoverMenu
    MasterPage嵌套及MasterPage中的控件和变量的访问
    Linux下将CD音乐提取为mp3的方法和中文乱码问题的解决
    altas(ajax)控件(十四):为下拉控件添加快捷键查找功能的ListSearchExtender
    在atlas(ajax)中请不要使用Response.Write,请使用ClientScript.RegisterClientScriptBlock替换
  • 原文地址:https://www.cnblogs.com/chenzc/p/4536393.html
Copyright © 2011-2022 走看看