如何从POST请求中获取XML并在Servlet过滤器中对其进行修改?

我目前正在处理一个要求,即在请求到达Spring控制器之前,我需要在servlet过滤器中获取XML(从POST请求中获取),然后需要在XML处理程序中处理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 {

}

}

以上是 如何从POST请求中获取XML并在Servlet过滤器中对其进行修改? 的全部内容, 来源链接: utcz.com/qa/410939.html

回到顶部