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/对象类型的参数啦!

相关文章
|
4月前
|
缓存 安全 Java
Spring Get请求 与post请求
本文详细介绍了Spring框架中GET请求和POST请求的区别及应用场景。GET请求用于从服务器获取资源,参数附在URL末尾,适合查看非敏感信息;POST请求用于向服务器提交数据,参数在请求体中传输,适合处理敏感信息。Spring通过`@GetMapping`和`@PostMapping`注解分别处理这两种请求。此外,文章还提供了示例代码,展示了如何在Spring中实现这两种请求的处理。最后,文章总结了推荐使用POST请求的原因,包括更高的安全性、更大的数据传输量、更好的幂等性及灵活性。
Spring Get请求 与post请求
|
2月前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
57 5
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
159 2
|
3月前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
53 1
Spring MVC——项目创建和建立请求连接
|
3月前
|
存储 Java API
如何使用 Java 记录简化 Spring Data 中的数据实体
如何使用 Java 记录简化 Spring Data 中的数据实体
49 9
|
3月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
43 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
3月前
|
前端开发 Java Spring
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
47 2
|
3月前
|
JSON 前端开发 Java
【Spring】“请求“ 之传递 JSON 数据
【Spring】“请求“ 之传递 JSON 数据
105 2
|
3月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
156 2
|
3月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
280 2