我有一个spring boot应用程序。我更改每个post请求的请求正文。是否可以在请求到达控制器之前修改请求正文。请附上一个例子。
我使用HTTP过滤器的答案。
请求Filter.java
@Component
public class RequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
RequestWrapper wrappedRequest = new RequestWrapper((HttpServletRequest) request);
chain.doFilter(wrappedRequest, response);
}
@Override
public void destroy() {
}
}
RequestWrapper。Java语言
public class RequestWrapper extends HttpServletRequestWrapper {
private final String body;
private ObjectMapper objectMapper = new ObjectMapper();
public RequestWrapper(HttpServletRequest request) throws IOException {
// So that other request method behave just like before
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream 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) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
// Store request body content in 'requestBody' variable
String requestBody = stringBuilder.toString();
JsonNode jsonNode = objectMapper.readTree(requestBody);
//TODO -- Update your request body here
//Sample
((ObjectNode) jsonNode).remove("key");
// Finally store updated request body content in 'body' variable
body = jsonNode.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
简短回答是的,但不容易。
详细信息
我知道有三个选项可以在请求“到达”控制器中的处理程序方法之前更改请求体;
既然您已经在使用spring boot,选项3,定制spring HandlerInterceptor,似乎是您的最佳选择。
这里有一个链接到一篇关于spring HandlerInterceptors的Baeldung文章。
Baeldung文章并不是您问题的完整答案,因为您只能一次读取HttpServletRequest返回的InputStrem。
您需要创建一个扩展HttpServletRequest的包装类,并将包装类中的每个请求包装在自定义HandlerInterceptor或自定义过滤器中(这里可能是使用过滤器)。
包装器类
如何包装请求
另一种选择是向HttpServletRequest对象添加一个属性。之后,您可以在Controller类中使用@Request estAtcm注释读取该属性。
在拦截器里
@Component
public class SimpleInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException, IOException {
String parameter = request.getParameter("parameter");
if (parameter == "somevalue") {
request.setAttribute("customAttribute", "value");
}
return true;
}
}
在控制器中
@RestController
@RequestMapping("")
public class SampleController {
@RequestMapping(value = "/sample",method = RequestMethod.POST)
public String work(@RequestBody SampleRequest sampleRequest, @RequestAttribute("customAttribute") String customAttribute) {
System.out.println(customAttribute);
return "This works";
}
}
这具有不修改请求正文的优点。
在到达spring控制器之前,如何从UI端修改请求体中发送的JSON对象? 我尝试添加过滤器,但是一旦我从请求(servletrequest.getReader())读取,然后将请求转发到过滤器链中的下一个过滤器,它就会失败(请求无法到达控制器)。 使用这个,我得到了字符串中的JSON,但我无法弄清楚如何将其放回请求中。
在spring boot中@RequestBody内容到达控制器之前,我如何覆盖它? > 此外,我还搜索了Request estBodyAdviceAdapter。 有几个链接对spring boot不起作用。 如何多次读取request.getInputStream() 如何在Spring引导到达控制器之前修改请求正文 现在,我可以将输入流读入字符串中,进行一些修改并设置回控制器的输入流吗?
我正在使用Java和Spring构建一个RESTAPI,我需要在我的控制器中处理一个POST请求,但我需要从该请求中提取主体,它是一个JSON,也是该请求的“来源”, 我有几个问题:首先是如何获取该请求的来源(我猜是在标题中移动的url?),是否有与@RequestBody类似的注释?。 我的第二个问题是,在这种post方法中,通常应该返回什么对象作为响应。
我正在开发我的第一个基于spring的项目样本。下面是我的dispatcher-servlet.xml的摘录。 我尝试向以下url发布帖子,但它似乎从未到达相应的控制器类: 网址: post<code>{“testID”:“1”} 就是回应。 为什么我得到400错误,尽管一切似乎都在地方?
我正在使用ApacheTiles构建一个带有SEO友好URL和多主题UI的小型Spring Boot应用程序。 我有两个类似的问题 例如map是 通过扩展什么类,我可以访问这个?以及如何阻止请求被Spring Security阻止? 更改controller后的视图名称