我正在开发Spring Boot应用程序。我想通过请求正文字段“ Id”修改请求的响应。
我已经在下面实现了,但是在实现时仍会在输出中得到名称。任何在下面实现的建议都会有所帮助:
下面是requestBody:
{
"id" : "123"
}
作为响应,我想将该字段附加到响应ID(请求主体的字段名)。responseBody:
{
"name" : "foo123" //name + id from request
}
MyCustomFilter:
public class TestFilter implements Filter {
@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final PrintStream ps = new PrintStream(baos);
MultiReadHttpServletRequest wrapper = new MultiReadHttpServletRequest((HttpServletRequest) request);
MyRequestWrapper req = new MyRequestWrapper(wrapper);
String userId = req.getId();
chain.doFilter(wrapper, new HttpServletResponseWrapper(res) {
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps)
);
}
@Override
public PrintWriter getWriter() throws IOException {
return new PrintWriter(new DelegatingServletOutputStream(new TeeOutputStream(super.getOutputStream(), ps))
);
}
});
String responseBody = baos.toString();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(responseBody);
String name = node.get("name").astext();
((ObjectNode) node1).put("name", name + userId);
chain.doFilter(wrapper, res);
}
MyRequestWrapper:
public class MyRequestWrapper extends HttpServletRequestWrapper {
private ServletInputStream input;
public MyRequestWrapper(ServletRequest request) {
super((HttpServletRequest)request);
}
public String getId() throws IOException {
if (input == null) {
try {
JSONObject jsonObject = new JSONObject(IOUtils.toString(super.getInputStream()));
String userId = jsonObject.getString("id");
userId = userId.replaceAll("\\D+","");
return userId;
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
}
MultiReadHttpServletRequest.java
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper
{
private byte[] body;
public MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
try {
body = IOUtils.toByteArray(request.getInputStream());
} catch (IOException ex) {
body = new byte[0];
}
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream(), getCharacterEncoding()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStream() {
ByteArrayInputStream wrapperStream = new ByteArrayInputStream(body);
@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 wrapperStream.read();
}
};
}
}
任何建议都值得赞赏。 TIA。Nte:更新后,我看不到更新后的响应作为输出。我仍然只看到名称,但未附加ID。
我在自己的ServletRequest实现中看到的一个问题是,您调用super.getInputStream()
而不是request.getInputStream()
。默认情况下,您自己的请求为空,这就是为什么您超时超时的原因。您必须将呼叫委派给实际的请求:
public class MyRequestWrapper extends HttpServletRequestWrapper {
private ServletInputStream input;
public MyRequestWrapper(ServletRequest request) {
super((HttpServletRequest)request);
}
public String getId() throws IOException {
if (input == null) {
try {
JSONObject jsonObject = new JSONObject(IOUtils.toString(/*DELETEGATE TO ACTUAL REQUEST*/request.getInputStream()));
String userId = jsonObject.getString("id");
userId = userId.replaceAll("\\D+","");
return userId;
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
}