gpt4 book ai didi

java - 如何从 POST 请求获取 XML 并在 Servlet Filter 中修改它?

转载 作者:行者123 更新时间:2023-12-02 03:27:30 25 4
gpt4 key购买 nike

我目前正在处理一个需求,在请求到达 Spring Controller 之前,我需要在 servlet 过滤器中获取 XML(来自 POST 请求),然后我需要处理 XML(切断一些空节点/元素) ) 在过滤器中,然后调用应该继续进行。

我尝试了下面的代码(仅附加代码片段),我能够获取请求正文(XML)并能够设置修改后的响应。

    HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (httpRequest.getMethod().equalsIgnoreCase("POST")) {
extractDataFromRequest(httpRequest);
httpResponse.getWriter().write("<root><root>");
}
chain.doFilter(request, wrappedResponse);

public static String extractDataFromRequest(HttpServletRequest request) throws IOException {

String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
return builder.toString();
}

但是,spring 失败并出现以下异常。

Severe: java.lang.IllegalStateException: PWC3997: getReader() has already been called for this request
at org.apache.catalina.connector.Request.getInputStream(Request.java:1178)
at org.apache.catalina.connector.RequestFacade.getInputStream(RequestFacade.java:407)
at org.springframework.http.server.ServletServerHttpRequest.getBody(ServletServerHttpRequest.java:165)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:120)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:100)

我正在寻找专家针对此要求的具体实现。

最佳答案

您不能使用InputStream两次,您需要创建一个包装类来保留InputStream的可重复副本。

public class ReadTwiceHttpServletRequestWrapper extends HttpServletRequestWrapper {

private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

public ReadTwiceHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
try {
IOUtils.copy(request.getInputStream(), outputStream);
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(outputStream.toByteArray())));
}

@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
return new ServletInputStream() {

@Override
public int readLine(byte[] b, int off, int len) throws IOException {
return inputStream.read(b, off, len);
}

@Override
public boolean isFinished() {
return inputStream.available() > 0;
}

@Override
public boolean isReady() {
return true;
}

@Override
public void setReadListener(ReadListener arg0) {
// TODO Auto-generated method stub
}

@Override
public int read() throws IOException {
return inputStream.read();
}
};
}

public void setBody(String body) {
outputStream = new ByteArrayOutputStream();
try {
outputStream.write(body.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public String getBody() {
return new String(outputStream.toByteArray());
}

}

然后您需要使用链中第一个过滤器对其进行初始化。

public class ReadTwiceFilter implements Filter {

@Override
public void destroy() {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {

ReadTwiceHttpServletRequestWrapper readTwiceHttpServletRequestWrapper = new ReadTwiceHttpServletRequestWrapper(
(HttpServletRequest) request);

String newBody = readTwiceHttpServletRequestWrapper.getBody().replace("<soap:studentId>1</soap:studentId>", "<soap:studentId>2</soap:studentId>");
readTwiceHttpServletRequestWrapper.setBody(newBody);

chain.doFilter(readTwiceHttpServletRequestWrapper, response);
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}

}

关于java - 如何从 POST 请求获取 XML 并在 Servlet Filter 中修改它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38614799/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com