Spring 4.2.4.RELEASE MVC 学习笔记 - 8.1 - text/gson(咋个办呢 zgbn)
2016-03-08 12:30
399 查看
Spring 4.2.4.RELEASE MVC 学习笔记 - 8.1 - text/gson
为了学习spring mvc框架整合fasterxml jackson工具,实现Restfull模式api实现对json、xml的支持。我们需要对之前对gson支持做一些改动,以免混淆视听。修改测试请求URL
修改原来的user.html页面中的测试URL,将/api/userAdd.json修改为/api/userAdd.gson,/api/userQuery.json修改为/api/userQuery.gson。因为在Spring mvc 整合 fasterxml jackson工具的时候,框架上默认支持的一种情况就是以*.json为后缀的请求,这样修改避免弄混。/framework_spring/src/main/webapp/user.html
<div class="vform"> <div class="h1">HTTP POST 添加用户 /api/userAdd.gson</div> <form action="/api/userAdd.gson" method="post"> <div> <label>用户名:<input name="username" value="xiaohong" /></label> </div> <div> <label> 姓名:<input name="name" value="小红" /></label> </div> <div> <label>年龄:<input name="age" value="22" /></label> </div> <div> <label>性别:<select name="sex"><option value="0" selected="selected">女</option></select></label> </div> <div> <button type="submit">添加新用户</button> </div> </form> <hr /> </div> <div class="vform"> <div class="h1">HTTP GET 查询用户 /api/userQuery.gson</div> <form action="/api/userQuery.gson" method="get"> <div> <label> 用户名:<input name="username" value="xiaohong" /></label> </div> <div> <button type="submit">查询</button> </div> </form> <hr /> </div> <div class="clearfloat"></div> </div>
修改UserController处理方法
修改原来UserController类中的方法userAddJson方法为userAddGson,同时修改对应的注解。详细参见下面的代码。修改方法名字,属于个人习惯问题。
修改@RequestMapping注解,path = “/userAdd.gson”、produces = “text/gson; charset=UTF-8”,需要重点说明一下,path用于接收userAdd.gson过来的请求,produces则通过此信息控制调用自定义的Gson数据解析器解析数据。
cn.vfire.framework.spring.mvc.controller.UserController
@RequestMapping(path = "/userAdd.gson", method = RequestMethod.POST, produces = "text/gson; charset=UTF-8") @ResponseBody public Result userAddGson(UserMode user) { XModelAndView modeView = new XModelAndView(); modeView.addObject("user", user); System.out.println(String.format("添加用户%s完成", user.getName())); return modeView.toResult(); } @RequestMapping(path = "/userQuery.gson", method = RequestMethod.GET, produces = "text/gson; charset=UTF-8") @ResponseBody public Result userQueryGson(String username) { XModelAndView modeView = new XModelAndView(); UserMode user = new UserMode(); { user.setUsername(username); user.setName("小红"); user.setAge(22); user.setSex(0); } modeView.addObject("user", user); System.out.println(String.format("查询用户名为%s用户 信息成功", user.getUsername())); return modeView.toResult(); }
修改自定义数据解析器GSONHttpMessageConverte
修改原自定义Gson数据解析器GSONHttpMessageConverte类的构造方法,指定该解析器只处理MediaType=”text/gson; charset=UTF-8”的请求Requeset和应答Response。cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte
public GSONHttpMessageConverte(Charset defaultCharset) { super(new MediaType("text", "gson", defaultCharset)); this.availableCharsets = DEFAULT_CHARSET; this.dateFormat = DEFAULT_DATEFORMAT; log.debug(String.format("注册自定义%s数据解析器,解析MediaType类型为%s。",GSONHttpMessageConverte.class.getName(),"application/json")); log.debug(String.format("默认处理字符集%s。",DEFAULT_CHARSET)); log.debug(String.format("默认处理日期类型数据格式化%s。",DEFAULT_DATEFORMAT)); }
PS:我偷偷的在这个类的方法中追加了日志打印,下面我还是列出该类的全部代码共大家参考把。
cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte
package cn.vfire.framework.spring.mvc.converter; import java.io.IOException; import java.lang.reflect.Type; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import lombok.Getter; import lombok.Setter; import org.apache.log4j.Logger; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.AbstractHttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.util.StreamUtils; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; public class GSONHttpMessageConverte extends AbstractHttpMessageConverter<Object> { private static final Logger log = Logger.getLogger(GSONHttpMessageConverte.class); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final String DEFAULT_MEDIATYPE = "text/gson" ; public static final String DEFAULT_DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; private GsonBuilder gsonBuilder = new GsonBuilder(); @Getter @Setter public Charset charset = DEFAULT_CHARSET ; private List<MediaType> mediaTypes = new LinkedList<MediaType>() ; @Getter @Setter private String dateFormat = DEFAULT_DATEFORMAT; @Getter @Setter private boolean writeAcceptCharset = true; @Getter @Setter private boolean excludeFieldsWithoutExposeAnnotation = false; public GSONHttpMessageConverte() { this.setCharset(DEFAULT_CHARSET); this.setMediaTypes(DEFAULT_MEDIATYPE); this.setDateFormat(DEFAULT_DATEFORMAT); log.debug(String.format("注册自定义%s数据解析器,解析MediaType类型为%s。", GSONHttpMessageConverte.class.getName(), this.charset.toString())); log.debug(String.format("默认处理字符集%s。", DEFAULT_CHARSET)); log.debug(String.format("默认处理日期类型数据格式化%s。", DEFAULT_DATEFORMAT)); } protected List<Charset> getAcceptedCharsets() { List<Charset> charsetList = new ArrayList<Charset>(1); charsetList.add(this.charset); return charsetList; } @Override protected Long getContentLength(Object t, MediaType contentType) throws IOException { Long contentLength = super.getContentLength(t, contentType); log.debug("进入自定义" + GSONHttpMessageConverte.class.getName() + "数据解析器,内容长度为" + contentLength + "。"); return contentLength; } private Charset getContentTypeCharset(MediaType contentType) { if (contentType != null && contentType.getCharSet() != null) { return contentType.getCharSet(); } else { return this.charset; } } @Override public List<MediaType> getSupportedMediaTypes() { return Collections.unmodifiableList(this.mediaTypes); } @Override protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { Charset charset = this.getContentTypeCharset(inputMessage.getHeaders().getContentType()); Object rs = StreamUtils.copyToString(inputMessage.getBody(), charset); log.debug(String.format("进入自定义%s数据解析器,处理字符集%s,读取数据流到到对象%s。", GSONHttpMessageConverte.class.getName(), String.valueOf(charset), String.valueOf(rs))); return rs; } public void setMediaTypes(List<String> mediaTypes) { if(mediaTypes!=null && mediaTypes.isEmpty()==false){ for(String media : mediaTypes){ this.setMediaTypes(media); } } } public void setMediaTypes(String mediaTypes) { if(this.mediaTypes.indexOf(mediaTypes)==-1){ MediaType mt = MediaType.valueOf(mediaTypes); this.mediaTypes.add(new MediaType(mt.getType(),mt.getSubtype(),this.charset)) ; } } @Override protected boolean supports(Class<?> clazz) { return true; } private String toJson(Object o) { try { if (this.excludeFieldsWithoutExposeAnnotation) { this.gsonBuilder = this.gsonBuilder.excludeFieldsWithoutExposeAnnotation(); } Type genericType = TypeToken.get(o.getClass()).getType(); Gson gson = gsonBuilder.setDateFormat(this.dateFormat).create(); String json = gson.toJson(o, genericType); if (json == null || "".equals(json.trim())) { json = "{}"; } return json; } catch (Exception e) { e.printStackTrace(); } return ""; } @Override protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { if (this.writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset(this.getAcceptedCharsets()); } Charset charset = this.getContentTypeCharset(outputMessage.getHeaders().getContentType()); StreamUtils.copy(this.toJson(o), charset, outputMessage.getBody()); log.debug(String.format("进入自定义%s数据解析器,处理字符集%s,解析对象%s到Json。", GSONHttpMessageConverte.class.getName(), String.valueOf(charset), String.valueOf(o))); } }
测试
测试表单
后台日志
添加用户小红完成 @DEBUG|2016-03-08 12:28:28,755|cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte.getContentLength(GSONHttpMessageConverte.java:72)|http-bio-8000-exec-6 Info:进入自定义cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte数据解析器,内容长度为null。 @DEBUG|2016-03-08 12:28:28,758|cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte.writeInternal(GSONHttpMessageConverte.java:135)|http-bio-8000-exec-6 Info:进入自定义cn.vfire.framework.spring.mvc.converter.GSONHttpMessageConverte数据解析器,处理字符集UTF-8,解析对象cn.vfire.framework.spring.mvc.view.Result@1aa8430a到Json。
结果页面
相关文章推荐
- Leetcode:9. Palindrome Number(JAVA)
- Java中数据存储在哪?以及equals和==的区别
- java.lang.IndexOutOfBondsException:setSpan(3..3) ends beyond length 2
- 转载 java_web开发入门
- Canal+Otter - Canal篇(1)
- Java并发编程(十六):线程间协作的两种方式:wait、notify、notifyAll和Condition(转载)
- Java并发编程(十五):Timer和TimerTask(转载)
- Java核心技术学习笔记之五——Java集合
- java类加载 运行机制
- Java并发编程(十四):Callable、Future和FutureTask(转载)
- Java并发编程(十三):CountDownLatch、CyclicBarrier和Semaphore(转载)
- java反射机制
- Java并发编程(十二):线程池的使用(转载)
- 关于MyEclipse破解时找不到Common的解决方法
- Java并发编程(十一):阻塞队列(转载)
- Java中的Exception和RuntimeException的区别
- Java中避免NullPointerException的一些方法
- Spring 整合Quartz两种方式比较(JobDetailBean和MethodInvokingJobDetailFactoryBean方式)
- Java并发编程(十):并发容器之CopyOnWriteArrayList(转载)
- Java开发中的23种设计模式详解