当前位置: 移动技术网 > IT编程>开发语言>Java > springmvc处理异步请求的示例

springmvc处理异步请求的示例

2019年07月22日  | 移动技术网IT编程  | 我要评论

springmvc 3.2开始就支持servlet3.0的异步请求。平常我们请求一个controller一般都是同步的,如果在代码执行中,遇到耗时的业务操作,那servlet容器线程就会被锁死,当有其他请求进来的时候就会受堵了。

springmvc3.2之后支持异步请求,能够在controller中返回一个callable或者deferredresult。当返回callable的时候,大概的执行过程如下:

  • 当controller返回值是callable的时候,springmvc就会启动一个线程将callable交给taskexecutor去处理
  • 然后dispatcherservlet还有所有的spring拦截器都退出主线程,然后把response保持打开的状态
  • 当callable执行结束之后,springmvc就会重新启动分配一个request请求,然后dispatcherservlet就重新调用和处理callable异步执行的返回结果,然后返回视图

deferredresult的执行过程和callable差不多,唯一不同的时候,deferredresult是由应用程序其他线程执行返回结果,而callable是由taskexecutor执行返回结果。

springmvc配置异步请求

1.需要在web.xml加上servlet3.0的scheme库

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
...
</web-app>

2.在web.xml的servlet还有filter添加<asyncsupported>true</async-supported>子节点

<!-- springmvc的servlet配置 -->
<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
  <init-param>
    <param-name>contextconfiglocation</param-name>
    <param-value>classpath*:meta-inf/dispatcher-context.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
  <async-supported>true</async-supported>
</servlet>

<!-- 编码拦截 -->
<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>

3.然后就可以在controller中执行异步请求了

利用callable执行异步请求,并返回视图

@requestmapping("/mvc25")
public callable<string> mvc25() {

  return new callable<string>() {
    @override
    public string call() throws exception {
       thread.sleep(2000);
       return "task/task";
    }
  };

}

利用callable执行异步请求,并把请求结果通过@response由httpmessageconverter进行转化返回客户端

@requestmapping("/mvc26")
@responsebody
public callable<string> mvc26() {

  return new callable<string>() {
    @override
    public string call() throws exception {
      thread.sleep(2000);
      return "hello task";
    }
  };

}

可以自定义客户端超时间

@requestmapping("/mvc27")
@responsebody
public webasynctask<string> mvc27() {

  callable<string> callable = new callable<string>() {
    @override
    public string call() throws exception {
      thread.sleep(10000);
      return "hello task";
    }
  };

  return new webasynctask<string>(10000, callable);
}

如果在线程的执行过程中,遇到异常,处理过程和普通请求的一样,你可以用@exceptionhandler来处理或者定义全局的handlerexceptionresolver来处理

@requestmapping("/mvc28")
@responsebody
public callable<string> mvc28() {

  callable<string> callable = new callable<string>() {
    @override
    public string call() throws exception {
      thread.sleep(2000);
      throw new runtimeexception();
    }
  };

  return callable;

}

@exceptionhandler(runtimeexception.class)
@responsebody
public jsonobject handlerexception(){

  jsonobject jsonobject = new jsonobject();
  jsonobject.put("aaa", 123);

  return jsonobject ;
}

还可以通过返回deferredresult返回,deferredresult的作用是返回一个实例给其他线程来处理这个异步请求。

@requestmapping("/mvc29")
@responsebody
public deferredresult<string> mvc29() {

  deferredresult<string> deferredresult = new deferredresult<string>();
  dealinotherthread(deferredresult);
  return deferredresult;

}

private void dealinotherthread(deferredresult<string> deferredresult) {
  try {
    thread.sleep(2000);
  } catch (interruptedexception e) {
    // todo auto-generated catch block
    e.printstacktrace();
  }

  deferredresult.setresult("hello task");
}

dealinotherthread处理完成,setresult的时候就会触发springmvc分配一个request到dispatcherservlet,然后dispatcherservlet处理deferredresult的返回结果,并返回视图。

deferredresult还提供了其他返回来处理线程请求,例如ontimeout(runnable) 还有oncompletion(runnable),ontimeout可以注册一个线程回调,当请求延时的时候的回调函数,oncompletion可以注册一个请求完成的回调函数。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网