首页 > 其他分享 >SpringMVC自定义处理返回值demo和异步处理模式DeferredResult demo

SpringMVC自定义处理返回值demo和异步处理模式DeferredResult demo

时间:2023-10-20 21:11:22浏览次数:45  
标签:web 自定义 SpringMVC demo springframework import DeferredResult org public

搭建自定义返回值处理器demo

新建springboot项目

修改pom.xml

<!-- 新增依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.54</version>
</dependency>

MyResponseBody注解

package com.example.handlermethodreturnvaluehandlerdemo;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyResponseBody {
}

UserController类

package com.example.handlermethodreturnvaluehandlerdemo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class UserController {

    @MyResponseBody
    @GetMapping("/user")
    public int getUser() {
        return 1;
    }
}

MyReturnValueHandler类

package com.example.handlermethodreturnvaluehandlerdemo;

import com.alibaba.fastjson.JSON;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;

public class MyReturnValueHandler implements HandlerMethodReturnValueHandler {

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return returnType.hasMethodAnnotation(MyResponseBody.class);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        mavContainer.setRequestHandled(true);
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        response.getWriter().write(JSON.toJSONString(2));
    }
}

MyReturnValueHandlerRegister类

package com.example.handlermethodreturnvaluehandlerdemo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class MyReturnValueHandlerRegister implements WebMvcConfigurer {
    @Autowired
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;

    @PostConstruct
    public void init(){
        // 注册PropertiesHandlerMethodReturnValueHandler
        List<HandlerMethodReturnValueHandler> handlers = requestMappingHandlerAdapter.getReturnValueHandlers();
        List<HandlerMethodReturnValueHandler> newHandlers = new ArrayList<>(handlers.size() + 1) ;
        newHandlers.addAll(handlers);
        newHandlers.add(new MyReturnValueHandler());
        // 重置Handler对象集合
        requestMappingHandlerAdapter.setReturnValueHandlers(newHandlers);
    }
}

返回2

自定义返回值处理器执行流程

HandlerMethodReturnValueHandler接口处理controller返回值

public interface HandlerMethodReturnValueHandler {
	// 是否支持返回值类型
	boolean supportsReturnType(MethodParameter returnType);
	// 处理返回值
	void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}

debug接口http://127.0.0.1:8080/user

HandlerMethodReturnValueHandler有15种,包括自定义返回值处理器。
每个请求在HandlerMethodReturnValueHandler列表中从前向后遍历,选择一个HandlerMethodReturnValueHandler来处理。
选择过程
第1步:ServletInvocableHandlerMethod类中invokeAndHandle方法

第2步:HandlerMethodReturnValueHandlerComposite类中handleReturnValue方法

搭建异步处理模式DeferredResult demo

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

@RestController
@RequestMapping("/deferredResult")
public class DeferredResultTestController {
    private DeferredResult<String> deferredResult = new DeferredResult<>();

    @RequestMapping("/hold")
    public DeferredResult<String> hold() {
        return deferredResult;
    }

    @RequestMapping("/release")
    public void release() {
        deferredResult.setResult("");
    }
}

调用hold接口后一直卡住,直到调用release接口或者http请求超时。

DeferredResult执行流程

1. 第1次收到请求,保存返回的DeferredResult对象,用于后续访问。
2. tomcat请求线程被回收到线程池中。 
3. tomcat线程每隔1秒遍历waitingProcessors里面的processor,确认是否过期。如果过期了,就把超时默认值写入DeferredResult对象;否则,业务线程把结果写入之前的DeferredResult对象。
4. 内部自动发起第2次请求,再次调用DispatcherServlet,由ResponseBody返回值处理器返回DeferredResult对象中的数据。

参考资料

https://blog.csdn.net/agonie201218/article/details/123954205

标签:web,自定义,SpringMVC,demo,springframework,import,DeferredResult,org,public
From: https://www.cnblogs.com/WJQ2017/p/17778001.html

相关文章

  • TypeError: Object of type 'Animal' is not JSON serializable/ 自定义对象 转json串
     importjsonclassAnimal(object):def__init__(self):self.name='tom'def__repr__(self):returnf'mynameis{self.name}&ilikeapple'd1={'county':'china','name':Ani......
  • Lumen框架 之设置自定义函数
    一、设置1、新建Libs/function.php2、在app.php中引入function.php ......
  • 直播平台源码,Flutter 自定义 虚线 分割线
    直播平台源码,Flutter自定义虚线分割线学习使用Flutter进行虚线自定义控件练习 //自定义虚线(默认是垂直方向)classDashedLindextendsStatelessWidget{ finalAxisaxis;//虚线方向 finaldoubledashedWidth;//根据虚线的方向确定自己虚线的宽度 finald......
  • RK3588编解码之mpp解码demo解析: mpi_dec_test
    1.简介mpi_dec_test是rockchip官方解码demo本篇文章进行mpi_dec_test的代码解析,解码流程解析2.环境介绍硬件环境:ArmSoM-W3RK3588开发板软件版本:OS:ArmSoM-W3Debian113.mpp解码流程解析 mpp_create:获取MppCtx实例以及MppApi结构体mpp_ini......
  • 麒麟系统开发笔记(十三):在国产麒麟系统上编译OSG库、搭建基础开发环境和移植测试Demo
    前言  在国产麒麟系统上实现C++三维仿真,使用OSG技术,其他基于web的技术也是可以但是交互上鼠标拽托等交互相对差一些,所以这块需要斟酌选择到底是何种技术来取舍。  本篇在厂家指定的麒麟系统上编译OSG。 环境系统版本:银河麒麟桌面操作系统V10(SP1)(注意:不对外提供)......
  • 从零用VitePress搭建博客教程(4) – 如何自定义首页布局和主题样式修改?
    接上一节:从零用VitePress搭建博客教程(3)-VitePress页脚、标题logo、最后更新时间等相关细节配置六、首页样式修改有时候觉得自带的样式不好看,想自定义,首先我们在docs/.vitePress新建一个theme文件夹,用来存放自定义布局和主题修改的相关文件,如下所示theme下再新建custom.css......
  • ES 结合nginx 实现自定义词库
    dockerrun-p80:80--namenginx-dnginx:1.10将容器内的配置文件拷贝到当前目录:dockercontainercpnginx:/etc/nginx.修改文件名称:mvnginxconf把这个conf移动到/mydata/nginx下执行命令删除原容器:dockerrmnginx创建新的nginx;执行以下命令dockerrun-......
  • Struct IfDemo02
    packagecom.chen.struct;importjava.util.Scanner;publicclassIfDemo02{publicstaticvoidmain(String[]args){//考试分数大于60分就是及格,小于60分就是不及格。Scannerscanner=newScanner(System.in);System.out.println("请输入成......
  • Struct SwitchDemo01
    packagecom.chen.struct;importjava.util.Scanner;publicclassSwitchDemo01{publicstaticvoidmain(String[]args){//case穿透//switch匹配一个具体的值chargrade='C';switch(grade){case'A':......
  • Struct SequenceDemo01
    packagecom.chen.struct;publicclassSequenceDemo01{publicstaticvoidmain(String[]args){System.out.println("hello1");System.out.println("hello2");System.out.println("hello3");System.o......