最近工作上,需要对网关进行一下改造。之前网关只支持form表单的提交请求。这里我将如何将只支持form表单请求的网关改造成支持application/json请求,毕竟application/json这种请求使用的很多。
form表单请求,在servlet中使用request.getParameter()获取参数。但是默认通过application/json请求提交,使用这种方式是获取不到参数。只能通过request.getInputStream()读流的形式才获取整个提交的内容。并且在读取之后,无法只重新读取里面的内容。
如果可以让application/json像form表单一样可以通过getParameter(), 这样我们的网关可以不用改写旧的代码。其实很简单,只需要我们将流读取出来的数据转换为JSON对象,并重写getParameter()方法, 并且在HttpFilter过滤器注入我们写的这个request,这样我们自己就实现了一个像form表单一样的request了。嘻嘻, 其实通过这个例子。你就指定springmvc是如何支持application/json转换为实体类的了。相关代码如下:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class BodyReaderHttpServletRequestWrapper extends
HttpServletRequestWrapper {
private final byte[] body;
private JSONObject requestParameter;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
System.out.println("-------------------------------------------------");
Enumeration e = request.getHeaderNames() ;
while(e.hasMoreElements()){
String name = (String) e.nextElement();
String value = request.getHeader(name);
System.out.println(name+" = "+value);
}
body = getBodyString(request).getBytes(Charset.forName("UTF-8"));
requestParametere = JSON.parseObject(getBodyString(request));
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
// 重写getParameter方法, 使它可以像form表单一样获取参数
@Override
public String getParameter(String key){
return requestParameter.getString(key);
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
@Override
public String getHeader(String name) {
return super.getHeader(name);
}
@Override
public Enumeration<String> getHeaderNames() {
return super.getHeaderNames();
}
@Override
public Enumeration<String> getHeaders(String name) {
return super.getHeaders(name);
}
/**
* 获取请求Body
*
* @param request
* @return
*/
private static String getBodyString(ServletRequest request) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.URIDereferencer;
import com.yt.util.HttpHelper;
import com.yt.util.JsonHelper;
public class ContentTypeFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest) req;
//判断是否为application/json请求
if(application/json请求){
//注入我们重写的request请求
req = new BodyReaderHttpServletRequestWrapper(hreq);
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
参考文章
http://blog.csdn.net/pyxly1314/article/details/51802652