之前写的http传输json进行服务端接口与客户端对接,以及restful实现这篇文章里提到关于json传输接收,我是在controller里来做json解析处理,如果每个地方都要用到json解析,那每个地方都这么写就显得代码很乱,当然也可以抽取到一个工具类里,但又觉得不优雅,假如我们有这么个注解@Json2Bean在controller参数对象中就能自动帮我们把json解析为我们要对象那将多美好呀。那么这里将应用springmvc HandlerMethodArgumentResolver这个接口以及自定义注解来实现一个关于json的解析;
实现步骤如下:
1)自定义注解:
package com.cwh.springmvc.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({java.lang.annotation.ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Json2Bean {
}
2)利用 HandlerMethodArgumentResolver接口实现数据绑定:
package com.cwh.springmvc.resolver;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.cwh.springmvc.Annotation.Json2Bean;
public class Json2BeanArgumentResolver implements HandlerMethodArgumentResolver{
@Override
public boolean supportsParameter(MethodParameter paramMethodParameter) {
// 仅对有fastjson注解有效
return paramMethodParameter.hasParameterAnnotation(Json2Bean.class);
}
@Override
public Object resolveArgument(MethodParameter paramMethodParameter,
ModelAndViewContainer paramModelAndViewContainer,
NativeWebRequest paramNativeWebRequest,
WebDataBinderFactory paramWebDataBinderFactory) throws Exception {
HttpServletRequest request = paramNativeWebRequest.getNativeRequest(HttpServletRequest.class);
// content-type不是json的不处理
if (!request.getContentType().contains("application/json")) {
return null;
}
StringBuffer str = new StringBuffer();
try {
BufferedInputStream in = new BufferedInputStream(request.getInputStream());
int i;
char c;
while ((i=in.read())!=-1) {
c=(char)i;
str.append(c);
}
}catch (Exception ex) {
ex.printStackTrace();
}
JSONObject obj= JSONObject.fromObject(str.toString());
return JSONObject.toBean(obj,paramMethodParameter.getParameterType());
}
}
3)springmvc配置文件配置:
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.cwh.springmvc.resolver.Json2BeanArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
注:这个<mvc:annotation-driven>标签是3.1版本的
4)controller实现应用上@json2Bean这个注解:
@RequestMapping("/getUserByName")
public @ResponseBody User getUserByName(@Json2Bean User userform){
System.out.println(userform);
String name = userform.getUsername();
User user= userservice.getUserByName(name);
return user;
}
5)模拟发送一笔json请求测试:
@Test
public void HttpPostData() {
try {
HttpClient httpclient = new DefaultHttpClient();
String uri = "http://localhost:8080/springMVC/user/getUserByName";
HttpPost httppost = new HttpPost(uri);
//添加http头信息
httppost.addHeader("Content-Type", "application/json");
JSONObject obj = new JSONObject();
obj.put("username", "cwh");
obj.put("password", "password");
httppost.setEntity(new StringEntity(obj.toString()));
HttpResponse response;
response = httpclient.execute(httppost);
//检验状态码,如果成功接收数据
int code = response.getStatusLine().getStatusCode();
System.out.println(code+"code");
if (code == 200) {
String rev = EntityUtils.toString(response.getEntity());//返回json格式: {"id": "","name": ""}
obj= JSONObject.fromObject(rev);
System.out.println(obj.get("username"));
User user = (User)JSONObject.toBean(obj,User.class);
System.out.println("返回数据==="+user.toString());
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
6)测试结果:
ok!这样服务端看起来代码就简洁多了