篇十六:application/json请求
一、Post请求的集中方式
1、基础知识
HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 这几种。其中 POST 一般用来向服务端提交数据,协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
2、application/x-www-form-urlencoded
最常见的 POST 提交数据的方式,典型的key-val键值对
优点:无需转化,在request中直接获取,框架也会将同名属性封装到接收对象中,form表单默认此方式提交请求
缺点:消息包大,耗流量
3、multipart/form-data
最常见的 POST 提交数据的方式,也是典型的key-val键值对,
优点:无需转化,在request中直接获取,框架也会将同名属性封装到接收对象中,支持文件流上传
<form id="form1" runat="server" enctype="multipart/form-data" > </form>
4、application/json
postman设置请求方式

二、application/json请求的解析
使用jackson
1、下载jar包
<dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency>
2、配置spring-context.xml
<!-- json转化器 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list > <ref bean="mappingJacksonHttpMessageConverter" /> </list> </property> </bean> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean>
3、在Controller中用对象接收参数,使用注解@ResponseBody
目前使用@ResponseBody只能获取一次,传输是基于流的
a.使用任意@ResponseBody String msg接收,获取请求的json字符串,然后手动解析获取值
b.使用对象,对象中的同名属性会被赋值,但是限制条件就是必须使用一个对象接收
@ResponseBody
@RequestMapping(value="/NewsAttention" ,method=RequestMethod.POST)
public String saveNewsAttention(HttpServletRequest req,@RequestBody NewsBasic mNewsBasic) {
....
}
三、拦截器中获取application/json的body
public class AppManagerInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpServletRequest req = request; String message = ""; String submitMehtod = req.getMethod(); // GET if (submitMehtod.equals("GET")) { message = new String(req.getQueryString().getBytes("iso-8859-1"),"utf-8").replaceAll("%22", "\""); // POST } else { message = getRequestPostStr(req); } boolean isAppmanager = true; HandlerMethod invocation = (HandlerMethod)handler; if (invocation.getMethod().isAnnotationPresent(AppManagerCheck.class)) { JSONObject json = JSONObject.parseObject(message); //获取用户id String userId = json.getString("userId"); //校验用户是否是APP管理员 if(isAppmanager) { return true; }else{ response.sendRedirect(req.getContextPath()+"/mobile/usereckAppManager"); return false; } } return isAppmanager; } /** * 描述:获取 post 请求的 byte[] 数组 * <pre> * 举例: * </pre> * @param request * @return * @throws IOException */ public static byte[] getRequestPostBytes(HttpServletRequest request) throws IOException { int contentLength = request.getContentLength(); if(contentLength<0){ return null; } byte buffer[] = new byte[contentLength]; for (int i = 0; i < contentLength;) { int readlen = request.getInputStream().read(buffer, i, contentLength - i); if (readlen == -1) { break; } i += readlen; } return buffer; } /** * 描述:获取 post 请求内容 * <pre> * 举例: * </pre> * @param request * @return * @throws IOException */ public static String getRequestPostStr(HttpServletRequest request) throws IOException { byte buffer[] = getRequestPostBytes(request); String charEncoding = request.getCharacterEncoding(); if (charEncoding == null) { charEncoding = "UTF-8"; } return new String(buffer, charEncoding); } }
四、application/json的拦截器
问题:application/json请求的数据存储在六中,整个请求过程中,只能读取一次,拦截器中把校验参数放在body,会使校验一次以后,Controller中获取不到body
方案一:将校验参数存放现在header中,获取header中的值不影响流
java中获取header
//知道Key获取值,当不存在时,返回Null,不报错 private String getUserAgent() { return request.getHeader("user-agent"); } //批量获取headers中的值,封装成键值对 private Map<String, String> getHeadersInfo() { Map<String, String> map = new HashMap<String, String>(); Enumeration headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String key = (String) headerNames.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; }

浙公网安备 33010602011771号