SpringBoot修改请求参数和返回结果
注:本文基本上照抄自:https://www.codenong.com/cs107098749/,记录一下方便自己之后再找而已。
1.修改请求参数
1.1.自定义HttpServletRequest的包装类
Spring 中的 request.getInputStream()和 request.getReader()只能被读取一次,而@RequestBody注解底层也是通过流来请求数据,所以需要把拦截器中的数据流保存下来,让 controller 层可以读取的数据
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
/**
* @author tianxc
* @title: RequestWrapper
* @projectName mycim-module
* @description:
* @date 2022/4/14 11:25
*/
public class RequestWrapper extends HttpServletRequestWrapper {
private String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
// 赋值给body字段
public void setBody(String body) {
this.body = body;
}
1.2.自定义过滤器,将HttpServletRequest替换成自定义的包装类
1.3.自定义拦截器
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mycim.framework.logging.Logger;
import com.mycim.framework.logging.LoggerFactory;
import com.mycim.webapp.wrapper.RequestWrapper;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author tianxc
* @title: LoginInterceptor
* @projectName mycim-module
* @description:
* @date 2022/4/14 10:47
*/
@Component
public class RequestParamInterceptor implements HandlerInterceptor {
private final Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(handler);
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod)handler;
pushRequest2Body(request, handlerMethod);
return true;
}
private void pushRequest2Body(HttpServletRequest request, HandlerMethod handlerMethod) {
try{
MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
if(ArrayUtils.isEmpty(methodParameters)) {
return;
}
if(request instanceof RequestWrapper){
RequestWrapper requestWrapper = (RequestWrapper)request;
String body = requestWrapper.getBody();
JSONObject param = JSONObject.parseObject(body).getJSONObject("body");
requestWrapper.setBody(JSON.toJSONString(param));
}
}catch (Exception e){
logger.warn("fill userInfo to request body Error ", e);
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2.修改返回参数
2.1.自定义返回值拦截器
因为SpringBoot默认的ResponseBody的处理程序就是HandlerMethodReturnValueHandler,所以我们自己写的HandlerMethodReturnValueHandler通常无法生效,
非要使用HandlerMethodReturnValueHandler,那么只能替换掉默认的,
如果只是想对Controller的所有返回值进行封装,产生上面的效果,使用ResponseBodyAdvice会更加简单一些
import com.mycim.webapp.Response;
import com.mycim.webapp.ResponseMsgBuilder;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* @author tianxc
* @title: InterceptResponse
* @projectName mycim-module
* @description:
* @date 2022/4/14 11:14
*/
@ControllerAdvice
public class InterceptResponse implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof Response) {
return body;
}
return ResponseMsgBuilder.buildSuccessResponse(body);
}
}
原文:https://www.codenong.com/cs107098749/