最近springmvc項目升級成springboot寨蹋,發(fā)現(xiàn)以前已經(jīng)接入的一個系統(tǒng)向重構(gòu)后的項目發(fā)送請求時遭赂,項目無法從HttpRequest中獲取報文體羞延。在springmvc項目中通過request.getInputStream();
方式獲取報文體紧显,在springboot中得到inputstream是null,用@RequestBody注解也同樣獲取不到報文层皱。用request.getParameterMap()
確能獲取到key是<?xmlversion=
性锭,value是"1.0" encoding="UTF-8" ?>...
的表單,說明項目將報文按照表單的格式進行了分隔叫胖。
使用抓包軟件對發(fā)送過來的報文抓包進行分析之后發(fā)現(xiàn)草冈,發(fā)來的http請求報文頭里面設(shè)置了Content-type 為x-www-form-urlencoded,然而我們需要解析的是xml報文瓮增。
抓包的報文頭部分
HiddenHttpMethodFilter
解決方案:
1、 禁用這個filter
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
@Bean
public FilterRegistrationBean disableSpringBootHiddenHttpMethodFilter(HiddenHttpMethodFilter filter) {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(filter);
filterRegistrationBean.setEnabled(false);
return filterRegistrationBean;
}
2绷跑、重寫這個filter
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter(){
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(request, response);
}
};
}
一般按照以上兩種方式就可以獲取xml報文了拳恋,但是我發(fā)現(xiàn)使用了我們公司的日志框架之后,還是獲取不到xml報文砸捏,看了我司的自動打印收發(fā)日志的框架之后發(fā)現(xiàn)了如下的代碼:
InputStreamWrapper
都是先獲取表單谬运,再獲取報文體隙赁,于是需要自己加一個過濾器,針對這個路徑先獲取報文體梆暖,創(chuàng)建自己的過濾器伞访,并且注冊到FilterRegistrationBean
,代碼如下:
@Configuration
public class FilterConfiguration {
@Bean
public FilterRegistrationBean requestBodyFilter() {
FilterRegistrationBean filterRegistrationBean = new
FilterRegistrationBean(new RequestBodyFilter());
filterRegistrationBean.setDispatcherTypes(REQUEST);
filterRegistrationBean.setName("inputStreamReplaceServletFilter");
// filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE + 5);
filterRegistrationBean.addUrlPatterns("/oc/charge");
filterRegistrationBean.addUrlPatterns("/oc/query");
return filterRegistrationBean;
}
class InputStreamReplacementHttpRequestWrapper extends HttpServletRequestWrapper {
private String requestBody;
private Map<String, String[]> parameterMap;
public InputStreamReplacementHttpRequestWrapper(HttpServletRequest request)
throws IOException {
super(request);
requestBody = StreamUtils.copyToString(request.getInputStream(), Constant.DEFAULT_CHARSET);
parameterMap = new HashMap<String,String[]>(request.getParameterMap());
parameterMap.put("ocxmldata", new String[] {requestBody});
}
public String getRequestBody() {
return requestBody;
}
@Override
public ServletInputStream getInputStream() throws IOException {
ByteArrayInputStream is = new ByteArrayInputStream(
requestBody.getBytes(Constant.DEFAULT_CHARSET_NAME));
return new ServletInputStream() {
@Override
public int read() throws IOException {
return is.read();
}
@Override
public boolean isFinished() {
return is.available() <= 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public String getParameter(String name) {
String[] values = parameterMap.get(name);
if (values != null) {
if(values.length == 0) {
return "";
}
return values[0];
} else {
return null;
}
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(parameterMap.keySet());
}
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
}
class RequestBodyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
// System.out.println("init RequestBodyFilter");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
// System.out.println("doFilter RequestBodyFilter");
HttpServletRequest req = (HttpServletRequest) request;
request = new InputStreamReplacementHttpRequestWrapper(req);
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
}