欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解spring mvc对异步请求的处理

程序员文章站 2024-03-08 17:34:10
在spring mvc3.2及以上版本增加了对请求的异步处理,是在servlet3的基础上进行封装的。 1、修改web.xml

在spring mvc3.2及以上版本增加了对请求的异步处理,是在servlet3的基础上进行封装的。

1、修改web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app version="3.0" 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">
...
</web-app>

1.1、声明version="3.0",声明web-app_3_0.xsd

1.2、为servlet或者filter设置启用异步支持: <async-supported>true</async-supported> ,修改web应用的web.xml

<!-- spring mvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class>
<init-param>
<param-name>contextconfiglocation</param-name>
<param-value>...</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>

2、使controller类支持async

2.1、返回java.util.concurrent.callable来完成异步处理

package org.springframework.samples.mvc.async;
 
import java.util.concurrent.callable;
 
import org.springframework.stereotype.controller;
import org.springframework.ui.model;
import org.springframework.web.bind.annotation.exceptionhandler;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestparam;
import org.springframework.web.bind.annotation.responsebody;
import org.springframework.web.context.request.async.webasynctask;
 
@controller
@requestmapping("/async/callable")
public class callablecontroller {
  @requestmapping("/response-body")
  public @responsebody callable<string> callable() {
 
    return new callable<string>() {
      @override
      public string call() throws exception {
        thread.sleep(2000);
        return "callable result";
      }
    };
  }
 
  @requestmapping("/view")
  public callable<string> callablewithview(final model model) {
 
    return new callable<string>() {
      @override
      public string call() throws exception {
        thread.sleep(2000);
        model.addattribute("foo", "bar");
        model.addattribute("fruit", "apple");
        return "views/html";
      }
    };
  }
 
  @requestmapping("/exception")
  public @responsebody callable<string> callablewithexception(
      final @requestparam(required=false, defaultvalue="true") boolean handled) {
 
    return new callable<string>() {
      @override
      public string call() throws exception {
        thread.sleep(2000);
        if (handled) {
          // see handleexception method further below
          throw new illegalstateexception("callable error");
        }
        else {
          throw new illegalargumentexception("callable error");
        }
      }
    };
  }
 
  @requestmapping("/custom-timeout-handling")
  public @responsebody webasynctask<string> callablewithcustomtimeouthandling() {
 
    callable<string> callable = new callable<string>() {
      @override
      public string call() throws exception {
        thread.sleep(2000);
        return "callable result";
      }
    };
 
    return new webasynctask<string>(1000, callable);
  }
 
  @exceptionhandler
  @responsebody
  public string handleexception(illegalstateexception ex) {
    return "handled exception: " + ex.getmessage();
  }
 
}

2.2、在异步处理完成时返回org.springframework.web.context.request.async.deferredresult其他线程,例如一个jms或一个amqp消息,redis通知等等:

@requestmapping("/quotes")
@responsebody
public deferredresult<string> quotes() {
 deferredresult<string> deferredresult = new deferredresult<string>();
 // add deferredresult to a queue or a map...
 return deferredresult;
}
  
// in some other thread...
deferredresult.setresult(data);
// remove deferredresult from the queue or map

3、spring配置文件的修改

spring mvc的dtd的声明必须大于等于3.2

<mvc:annotation-driven>
<!-- 可不设置,使用默认的超时时间 -->
  <mvc:async-support default-timeout="3000"/>
</mvc:annotation-driven>

 实际使用示例:

function deferred(){
  $.get('quotes.htm',function(data){
    console.log(data);
    deferred();//每次请求完成,再发一次请求,避免客户端定时刷新来获取数据
  });
}

这么做的好处避免web server的连接池被长期占用而引起性能问题,调用后生成一个非web的服务线程来处理,增加web服务器的吞吐量~~

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