SpringMVC异步处理

https://en.wikipedia.org/wiki/Jakarta_Servlet


1 Servlet 3.0 异步处理

1.1 同步请求流程

在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求。即每一次Http请求都由某一个线程从头到尾负责处理。

如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。即便是像Spring、Struts这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet之上的。为了解决这样的问题,Servlet 3.0引入了异步处理,然后在Servlet 3.1中又引入了非阻塞IO来进一步增强异步处理的性能。

1.2 异步请求流程 

/**
 * 1.开启异步处理 asyncSupported=true
 */
// http://localhost:8080/async
@WebServlet(value = "/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
    private final HelloService helloService = new HelloService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("thread name is " + Thread.currentThread().getName());
        System.out.println("doGet start timestamp=" + System.currentTimeMillis());
        //2.开启异步模式
        AsyncContext asyncContext = req.startAsync();
        //3.业务逻辑进行异步处理(开始)
        asyncContext.start(() -> {
            System.out.println("runnable start timestamp=" + System.currentTimeMillis());
            try {
                String res = helloService.sayHello();
                // 异步处理调用结束
                asyncContext.complete();
                //获取到异步的上下文
                //AsyncContext async = req.getAsyncContext();
                //4.获取响应
                ServletResponse response = asyncContext.getResponse();
                response.getWriter().write(res);
                System.out.println("runnable end timestamp=" + System.currentTimeMillis());
            } catch (IOException ignored) {}
        });
        System.out.println("doGet end timestamp=" + System.currentTimeMillis());
    }
}
public class HelloService {
    public String sayHello() {
        System.out.println("exe sayHello thread name is " + Thread.currentThread().getName());
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ignored) {}
        return Thread.currentThread().getName();
    }
}
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

2 SpringMVC异步处理

 

当使用Spring MVC进行异步文件上传时,需要进行以下步骤: 1. 在Spring MVC的配置文件中启用异步支持,可以使用<mvc:annotation-driven>元素或@EnableWebMvc注解来完成。 2. 创建一个控制器方法来处理文件上传请求。该方法应该使用@RequestParam注解来接收文件,并且需要使用@RequestBody注解来指定处理请求体的方式为异步。 3. 创建一个异步任务来处理文件上传操作。可以使用Spring的异步任务支持,即@Async注解来完成。在异步任务中,可以使用Spring的ResourceUtils类将文件保存到指定的位置。 4. 返回一个异步结果对象来表示文件上传的状态。可以使用DeferredResult或ListenableFuture等Spring提供的异步结果对象来完成。 下面是一个示例控制器方法的代码: ``` @RequestMapping(value = "/uploadFile", method = RequestMethod.POST) @ResponseBody public DeferredResult<String> handleFileUpload(@RequestParam("file") MultipartFile file) { DeferredResult<String> deferredResult = new DeferredResult<>(); AsyncTask asyncTask = new AsyncTask(file, deferredResult); asyncTask.execute(); return deferredResult; } ``` 在该示例代码中,handleFileUpload方法使用DeferredResult来表示异步处理的结果,然后创建一个AsyncTask对象来处理文件上传操作。AsyncTask类是一个自定义的异步任务类,其中包含一个execute方法,用于执行文件上传操作。在该方法中,使用ResourceUtils类将文件保存到指定的位置,并最终将文件上传的结果通知给DeferredResult对象。 请注意,在使用Spring MVC进行文件上传时,需要确保上传的文件大小不超过服务器所允许的最大限制。可以通过在Spring MVC的配置文件中配置multipartResolver来设置上传文件的最大大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值