Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

简介: Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

1、要被拦截的Controller接口


我们需要一个更新用户信息接口,请求方式为POST,参数类型为对象类型(UserInfo),代码如下:

@ResourceprivateUserServiceuserService;
/*** 更新用户信息** @param request* @param userInfo* @return*/@RequestMapping(value="/updateUserInfo", produces="application/json;charset=UTF-8",
method=RequestMethod.POST)
publicJSONObjectupdateUserInfo(HttpServletRequestrequest, @RequestBodyUserInfouserInfo) {
   ...
userService.updateUserInfo(userInfo);  
    ...
}


2、拦截器


我们要在拦截器中拦截该接口,并获取其请求参数UserInfo对象。


如果只是获取普通的请求对象(eg:用户ID -> userId),我们可以直接在拦截器中,通过如下代码即可获取request请求体中的参数数据:

@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto) {
   ......
// user ID为string类型,所以可以直接拿到数据,// 但是如果参数是对象类型/JSON类型数据,则无法通过这种方式获取!StringuserId=request.getParameter("userId");
   .....
}


3、HttpServletRequestWrapper解决这一问题


在拦截器中写一个内部类 RequestWrapper ,让其继承 HttpServletRequestWrapper:

classRequestWrapperextendsHttpServletRequestWrapper {

RequestWrapper 重写父类方法,最终完整的拦截器代码如下:


/*** 拦截器: ** @author csp* @date 2022-01-06 15:36:41*/publicclassUserInterceptorimplementsHandlerInterceptor {
privatefinalstaticLoggerlogger=LoggerFactory.getLogger(UserInterceptor.class);
@ResourceprivateUserServiceuserService;
/*** 前置拦截** @param request* @param response* @param o* @return* @throws Exception*/@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto) throwsException {
// 从request请求体中拿到body中的JSON对象参数RequestWrapperrequestWrapper=newRequestWrapper(request);
StringjsonBody=requestWrapper.getBody();
UserInfouserInfo=JSONObject.toJavaObject(JSONObject.parseObject(jsonBody), UserInfo.class);
// 根据userInfo校验是否具备权限BooleanisAuth=userService.getAuthByUserInfo(userInfo);
if (!isAuth) {
// response响应给浏览器无权限,代码略           ...
returnfalse;
        }
returntrue;
    }
@OverridepublicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto, ModelAndViewmodelAndView) throwsException {}
@OverridepublicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecto, Exceptione) throwsException {}
// RequestWrapper 内部类classRequestWrapperextendsHttpServletRequestWrapper {
privatefinalStringbody;
publicRequestWrapper(HttpServletRequestrequest) {
super(request);
StringBuilderstringBuilder=newStringBuilder();
BufferedReaderbufferedReader=null;
InputStreaminputStream=null;
try {
inputStream=request.getInputStream();
if (inputStream!=null) {
bufferedReader=newBufferedReader(newInputStreamReader(inputStream));
char[] charBuffer=newchar[128];
intbytesRead=-1;
while ((bytesRead=bufferedReader.read(charBuffer)) >0) {
stringBuilder.append(charBuffer, 0, bytesRead);
                    }
                } else {
stringBuilder.append("");
                }
            } catch (IOExceptionex) {
            } finally {
if (inputStream!=null) {
try {
inputStream.close();
                    } catch (IOExceptione) {
e.printStackTrace();
                    }
                }
if (bufferedReader!=null) {
try {
bufferedReader.close();
                    } catch (IOExceptione) {
e.printStackTrace();
                    }
                }
            }
body=stringBuilder.toString();
        }
@OverridepublicServletInputStreamgetInputStream() throwsIOException {
finalByteArrayInputStreambyteArrayInputStream=newByteArrayInputStream(body.getBytes());
ServletInputStreamservletInputStream=newServletInputStream() {
@OverridepublicbooleanisFinished() {
returnfalse;
                }
@OverridepublicbooleanisReady() {
returnfalse;
                }
@OverridepublicvoidsetReadListener(ReadListenerreadListener) {
                }
@Overridepublicintread() throwsIOException {
returnbyteArrayInputStream.read();
                }
            };
returnservletInputStream;
        }
@OverridepublicBufferedReadergetReader() throwsIOException {
returnnewBufferedReader(newInputStreamReader(this.getInputStream()));
        }
publicStringgetBody() {
returnthis.body;
        }
    }
}

这样,就可以在拦截器中,拦截request请求,并获取request请求体中的json/对象类型的参数啦!

相关文章
|
12月前
|
缓存 监控 Java
《深入理解Spring》拦截器(Interceptor)——请求处理的艺术
Spring拦截器是Web开发中实现横切关注点的核心组件,基于AOP思想,可在请求处理前后执行日志记录、身份验证、权限控制等通用逻辑。相比Servlet过滤器,拦截器更贴近Spring容器,能访问Bean和上下文,适用于Controller级精细控制。通过实现`HandlerInterceptor`接口的`preHandle`、`postHandle`和`afterCompletion`方法,可灵活控制请求流程。结合配置类注册并设置路径匹配与执行顺序,实现高效复用与维护。常用于认证鉴权、性能监控、统一异常处理等场景,提升应用安全性与可维护性。
|
12月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
601 1
|
12月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
525 1
|
JSON IDE Java
鸿蒙开发:json转对象插件回来了
首先,我重新编译了插件,进行了上传,大家可以下载最新的安装包进行体验了,还是和以前一样,提供了在线版和IDE插件版,两个选择,最新的版本,除了升级了版本,兼容了最新的DevEco Studio ,还做了一层优化,就是针对嵌套对象和属性的生成,使用方式呢,一年前的文章中有过详细的概述,这里呢也简单介绍一下。
457 4
鸿蒙开发:json转对象插件回来了
|
存储 人工智能 Java
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
|
人工智能 安全 Java
Spring Boot 过滤器 拦截器 监听器
本文介绍了Spring Boot中的过滤器、拦截器和监听器的实现与应用。通过Filter接口和FilterRegistrationBean类,开发者可实现对请求和响应的数据过滤;使用HandlerInterceptor接口,可在控制器方法执行前后进行处理;利用各种监听器接口(如ServletRequestListener、HttpSessionListener等),可监听Web应用中的事件并作出响应。文章还提供了多个代码示例,帮助读者理解如何创建和配置这些组件,适用于构建更高效、安全和可控的Spring Boot应用程序。
1035 0
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
485 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
1904 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
589 12
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
716 12