最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot實(shí)現(xiàn)異步請(qǐng)求(Servlet 3.0)

 更新時(shí)間:2017年04月26日 14:57:46   作者:catoop  
在spring 3.2 及以后版本中增加了對(duì)請(qǐng)求的異步處理,這篇文章主要介紹了Spring Boot實(shí)現(xiàn)異步請(qǐng)求(Servlet 3.0),感興趣的小伙伴們可以參考一下。

在spring 3.2 及以后版本中增加了對(duì)請(qǐng)求的異步處理,旨在提高請(qǐng)求的處理速度降低服務(wù)性能消耗。

在我們的請(qǐng)求中做了耗時(shí)處理,當(dāng)并發(fā)請(qǐng)求的情況下,為了避免web server的連接池被長(zhǎng)期占用而引起性能問(wèn)題,調(diào)用后生成一個(gè)非web的服務(wù)線程來(lái)處理,增加web服務(wù)器的吞吐量。

為此 Servlet 3.0 新增了請(qǐng)求的異步處理,Spring 也在此基礎(chǔ)上做了封裝處理。

本文還是以代碼例子的方式說(shuō)明如何在 Spring Boot 中應(yīng)用異步請(qǐng)求。

首先說(shuō)一下幾個(gè)要點(diǎn):

1、@WebFilter 和 @WebServlet 注解中的 asyncSupported = true 屬性

異步處理的servlet若存在過(guò)濾器,則過(guò)濾器的注解@WebFilter應(yīng)設(shè)置asyncSupported=true,

否則會(huì)報(bào)錯(cuò) A filter or servlet of the current chain does not support asynchronous operations.

2、@EnableAsync 注解

Spring Boot 默認(rèn)添加了一些攔截 /* 的過(guò)濾器,因?yàn)?/* 會(huì)攔截所有請(qǐng)求,按理說(shuō)我們也要設(shè)置 asyncSupported=true 屬性。因?yàn)檫@些過(guò)濾器都是 Spring Boot 初始化的,所以它提供了 @EnableAsync 注解來(lái)統(tǒng)一配置,該注解只針對(duì) “非 @WebFilter 和 @WebServlet 注解的有效”,所以我們自己定義的 Filter 還是需要自己配置 asyncSupported=true 的。

3、AsyncContext 對(duì)象

獲取一個(gè)異步請(qǐng)求的上下文對(duì)象。

4、asyncContext.setTimeout(20 * 1000L);

我們不能讓異步請(qǐng)求無(wú)限的等待下去,通過(guò) setTimeout 來(lái)設(shè)定最大超時(shí)時(shí)間。

下面通過(guò)兩種方式來(lái)測(cè)試異步任務(wù):

先在 SpringBootSampleApplication 上添加 @EnableAsync 注解。

再檢查所有自定義的Filter,如存在如下兩種情況需要配置 asyncSupported=true

1) 自定義Filter 攔截了 /*

2) 某Filter 攔截了 /shanhy/* ,我們需要執(zhí)行的異步請(qǐng)求的 Servlet 為 /shanhy/testcomet

方法一:原生Servlet方式

package org.springboot.sample.servlet;

import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * HTTP長(zhǎng)連接實(shí)現(xiàn)
 *
 * @author 單紅宇(365384722)
 * @myblog http://blog.csdn.net/catoop/
 * @create 2016年3月29日
 */
@WebServlet(urlPatterns = "/xs/cometservlet", asyncSupported = true)
//異步處理的servlet若存在過(guò)濾器,則過(guò)濾器的注解@WebFilter應(yīng)設(shè)置asyncSupported=true,
//否則會(huì)報(bào)錯(cuò)A filter or servlet of the current chain does not support asynchronous operations.
public class CometServlet extends HttpServlet {

 private static final long serialVersionUID = -8685285401859800066L;

 private final Queue<AsyncContext> asyncContexts = new LinkedBlockingQueue<>();

 private final Thread generator = new Thread("Async Event generator") {

  @Override
  public void run() {
   while (!generator.isInterrupted()) {// 線程有效
    try {
     while (!asyncContexts.isEmpty()) {// 不為空
      TimeUnit.SECONDS.sleep(10);// 秒,模擬耗時(shí)操作
      AsyncContext asyncContext = asyncContexts.poll();
      HttpServletResponse res = (HttpServletResponse) asyncContext.getResponse();
      res.getWriter().write("{\"result\":\"OK - "+System.currentTimeMillis()+"\"}");
      res.setStatus(HttpServletResponse.SC_OK);
      res.setContentType("application/json");
      asyncContext.complete();// 完成
     }
    } catch (InterruptedException e) {
     Thread.currentThread().interrupt();
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }

 };

 @Override
 public void init() throws ServletException {
  super.init();
  generator.start();
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  System.out.println(">>>>>>>>>>CometServlet Request<<<<<<<<<<<");
  doPost(req, resp);
 }

 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  AsyncContext asyncContext = req.startAsync();
  asyncContext.setTimeout(20 * 1000L);
  asyncContexts.offer(asyncContext);
 }

 @Override
 public void destroy() {
  super.destroy();
  generator.interrupt();
 }


}

方法二:Controller 方式

@Controller
public class PageController {

 @RequestMapping("/async/test")
 @ResponseBody
 public Callable<String> callable() {
  // 這么做的好處避免web server的連接池被長(zhǎng)期占用而引起性能問(wèn)題,
  // 調(diào)用后生成一個(gè)非web的服務(wù)線程來(lái)處理,增加web服務(wù)器的吞吐量。
  return new Callable<String>() {
   @Override
   public String call() throws Exception {
    Thread.sleep(3 * 1000L);
    return "小單 - " + System.currentTimeMillis();
   }
  };
 }

}

最后寫(xiě)一個(gè)comet.jsp頁(yè)面測(cè)試:

<%@ page pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
 <title>長(zhǎng)連接測(cè)試</title>
 <script type="text/javascript" src="${pageContext.request.contextPath }/webjarslocator/jquery/jquery.js"></script>
 <script type="text/javascript">
  $(function(){
   function longPolling(){
    $.getJSON('${pageContext.request.contextPath }/xs/cometservlet', function(data){
     console.log(data.result);
     $('#n1').html(data.result);
     longPolling();
    });
   }
   longPolling();

   function longPolling2(){
    $.get('${pageContext.request.contextPath }/async/test', function(data){
     console.log(data);
     $('#n2').html(data);
     longPolling2();
    });
   }
   longPolling2();
  });
 </script>
 </head>

 <body>
 <h1>長(zhǎng)連接測(cè)試</h1>
 <h2 id="n1"></h2>
 <h2 id="n2"></h2>
 </body>
</html>

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用Java實(shí)現(xiàn)百萬(wàn)Excel數(shù)據(jù)導(dǎo)出

    使用Java實(shí)現(xiàn)百萬(wàn)Excel數(shù)據(jù)導(dǎo)出

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)百萬(wàn)Excel數(shù)據(jù)導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-03-03
  • 使用idea搭建一個(gè)spring mvc項(xiàng)目的圖文教程

    使用idea搭建一個(gè)spring mvc項(xiàng)目的圖文教程

    這篇文章主要介紹了使用idea直接創(chuàng)建一個(gè)spring mvc項(xiàng)目的圖文教程,本文通過(guò)圖文并茂的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • mybatis-plus實(shí)現(xiàn)四種lambda表達(dá)式方式

    mybatis-plus實(shí)現(xiàn)四種lambda表達(dá)式方式

    使用了lambda表達(dá)式 可以通過(guò)方法引用的方式來(lái)使用實(shí)體字段名的操作,本文主要介紹了mybatis-plus實(shí)現(xiàn)四種lambda表達(dá)式方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 在Java中使用Moshi?JSON庫(kù)的方法詳解

    在Java中使用Moshi?JSON庫(kù)的方法詳解

    Moshi?是一個(gè)可用于?Java?與?Kotlin?的?JSON?序列化與反序列化庫(kù),其主要使用?Kotlin?編寫(xiě),本文以樣例代碼的方式來(lái)演示該庫(kù)在?Java?中的使用,需要的朋友可以參考下
    2024-04-04
  • SpringAMQP消息隊(duì)列實(shí)戰(zhàn)教程

    SpringAMQP消息隊(duì)列實(shí)戰(zhàn)教程

    這篇文章主要介紹了SpringAMQP消息隊(duì)列的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2024-02-02
  • 關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    這篇文章主要介紹了slf4j_log4j2源碼學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 詳解mybatis三種分頁(yè)方式

    詳解mybatis三種分頁(yè)方式

    本文主要介紹了詳解mybatis三種分頁(yè)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 將springboot項(xiàng)目生成可依賴的jar并引入到項(xiàng)目中的方法

    將springboot項(xiàng)目生成可依賴的jar并引入到項(xiàng)目中的方法

    SpringBoot項(xiàng)目默認(rèn)打包的是可運(yùn)行jar包,也可以打包成不可運(yùn)行的jar包,本文給大家介紹將springboot項(xiàng)目生成可依賴的jar并引入到項(xiàng)目中的方法,感興趣的朋友一起看看吧
    2023-11-11
  • Java實(shí)現(xiàn)高效隨機(jī)數(shù)算法的示例代碼

    Java實(shí)現(xiàn)高效隨機(jī)數(shù)算法的示例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)高效隨機(jī)數(shù)算法的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • MyBatis配置的應(yīng)用與對(duì)比jdbc的優(yōu)勢(shì)

    MyBatis配置的應(yīng)用與對(duì)比jdbc的優(yōu)勢(shì)

    這篇文章主要介紹了MyBatis配置的使用與相對(duì)于jdbc的優(yōu)勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評(píng)論

宜章县| 德兴市| 海口市| 阳泉市| 永康市| 阿拉尔市| 徐州市| 襄樊市| 正宁县| 微山县| 稷山县| 高邑县| 邓州市| 葵青区| 吉林市| 北安市| 陵川县| 通江县| 丽江市| 肥城市| 奉化市| 修文县| 吉隆县| 兴安县| 盐池县| 夏邑县| 九寨沟县| 铜陵市| 界首市| 玉田县| 秦皇岛市| 沁水县| 常德市| 临沭县| 南部县| 辰溪县| 奉节县| 当涂县| 西峡县| 高尔夫| 天门市|