上篇文章介绍了程序整合的准备工作、结合MarshallingView视图完成jaxb2转换XML、xStream转换XML工作,这次将介绍castor、jibx转换XML。 还有MappingJacksonView用Jackson转换JSON,自己拓展AbstractView定义Jsonlib的视图完成JSON-lib转换JSON。 上一篇文章:http://www.cnblogs.com/hoojo/archive/2011/04/29/2032571.html
四、 用Castor转换XML 1、 castor可以通过一个mapping.xml文件对即将转换的Java对象进行描述,然后可以将Java对象按照描述的情况输出XML内容。利用castor转换xml需要添加如下jar包: 如果你还不清楚castor,可以阅读: for csblogs:http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html for csdn:http://blog.csdn.net/IBM_hoojo/archive/2011/04/25/6360916.aspx 2、 你需要在dispatcher.xml中添加castor的相关视图,配置如下: <-- 继承MarshallingView,重写locateToBeMarshalled方法; 解决对象添加到ModelAndView中,转换后的xml是BindingResult信息的bug --> <bean name="castorMarshallingView" class="com.hoo.veiw.xml.OverrideMarshallingView"> <property name="marshaller"> <bean class="org.springframework.oxm.castor.CastorMarshaller"> <property name="mappingLocations"> <array> <value>classpath:mapping.xml</value> </array> </property> <property name="encoding" value="UTF-8"/> </bean> </property> </bean> mapping.xml配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http:///mapping.dtd"> <mapping> <class name="com.hoo.entity.Account" auto-complete="true"> <map-to xml="Account"/> <field name="id" type="integer"> <bind-xml name="id" node="attribute" /> </field> <field name="name" type="string"> <bind-xml name="name" node="element" /> </field> <field name="email" type="string"> <bind-xml name="email" node="element" /> </field> <field name="address" type="string"> <bind-xml name="address" node="element" /> </field> <field name="brithday" type="com.hoo.entity.Brithday"> <bind-xml name="生日" node="element" /> </field> </class> <class name="com.hoo.entity.Brithday" auto-complete="true"> <map-to xml="brithday" /> <field name="brithday" type="string"> <bind-xml name="brithday" node="attribute" /> </field> </class> <class name="com.hoo.entity.MapBean" auto-complete="true"> <field name="map" collection="map"> <bind-xml name="map"> <class name="org.exolab.castor.mapping.MapItem"> <field name="key" type="java.lang.String"> <bind-xml name="key" node="attribute" /> </field> <field name="value" type="com.hoo.entity.Account"> <bind-xml name="value" auto-naming="deriveByClass"/> </field> </class> </bind-xml> </field> </class> <class name="com.hoo.entity.ListBean" auto-complete="true"> <map-to xml="listBean"/> <field name="list" collection="arraylist" type="com.hoo.entity.Account"> <bind-xml name="beans" auto-naming="deriveByClass"/> </field> <field name="name" type="string"/> </class> <class name="com.hoo.entity.AccountArray" auto-complete="true"> <map-to xml="account-array"/> <field name="size" type="int" /> <field name="accounts" collection="array" type="com.hoo.entity.Account"> <bind-xml name="accounts" auto-naming="deriveByClass"/> </field> </class> </mapping> 关于mapping.xml配置的介绍,你可以参考http://www.cnblogs.com/hoojo/archive/2011/04/25/2026819.html 这篇文章的第三栏目。 3、 在使用Spring的MarshallingView的时候,转换的xml结果有时候会带有BindingResult对象的信息。所以解决办法是重写MarshallingView里面的locateToBeMarshalled方法,这样就可以解决了。下面是重新MarshallingView的class代码: package com.hoo.veiw.xml; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.BeansException; import org.springframework.oxm.Marshaller; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.view.xml.MarshallingView; /** * <b>function:</b>继承MarshallingView,重写locateToBeMarshalled方法; * 解决对象添加到ModelAndView中,转换后的xml是BindingResult信息的bug * @author hoojo * @createDate 2010-11-29 下午05:58:45 * @file OverrideMarshallingView.java * @package com.hoo.veiw.xml * @project Spring3 * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class OverrideMarshallingView extends MarshallingView { private Marshaller marshaller; private String modelKey; public OverrideMarshallingView() { super(); } public OverrideMarshallingView(Marshaller marshaller) { super(marshaller); this.marshaller = marshaller; } public void setMarshaller(Marshaller marshaller) { super.setMarshaller(marshaller); this.marshaller = marshaller; } public void setModelKey(String modelKey) { super.setModelKey(modelKey); this.modelKey = modelKey; } @Override protected void initApplicationContext() throws BeansException { super.initApplicationContext(); } @SuppressWarnings("unchecked") @Override protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { super.renderMergedOutputModel(model, request, response); } @SuppressWarnings("unchecked") @Override protected Object locateToBeMarshalled(Map model) throws ServletException { if (modelKey != null) { Object o = model.get(modelKey); if (!this.marshaller.supports(o.getClass())) { throw new ServletException("Model object [" + o + "] retrieved via key [" + modelKey + "] is not supported by the Marshaller"); } return o; } for (Object o : model.values()) { //解决对象添加到ModelAndView中,转换后的xml是BindingResult信息的bug if (o instanceof BindingResult) { continue; } if (this.marshaller.supports(o.getClass())) { return o; } } return null; } } 4、 下面来看看Castor来转换普通JavaBean package com.hoo.controller; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.hoo.entity.Account; import com.hoo.entity.Brithday; import com.hoo.entity.ListBean; import com.hoo.entity.MapBean; import com.hoo.entity.User; /** * <b>function:</b>利用MarshallingView视图,配置CastorMarshaller将Java对象转换XML * @author hoojo * @createDate 2011-4-28 上午10:14:43 * @file CastorMarshallingViewController.java * @package com.hoo.controller * @project SpringMVC4View * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ @Controller @RequestMapping("/castor/view") public class CastorMarshallingViewController { @RequestMapping("/doBeanXMLCastorView") public ModelAndView doBeanXMLCastorView() { System.out.println("#################ViewController doBeanXMLCastorView##################"); ModelAndView mav = new ModelAndView("castorMarshallingView"); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("haha"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); Map<String, Object> map = new HashMap<String, Object>(); map.put("day", day); map.put("account", bean); mav.addObject(bean);//重写MarshallingView的locateToBeMarshalled方法 //mav.addObject(BindingResult.MODEL_KEY_PREFIX, bean); //mav.addObject(BindingResult.MODEL_KEY_PREFIX + "account", bean); return mav; } } Account在mapping配置文件中有进行配置描述。 在浏览器中请求http://localhost:8080/SpringMVC4View/castor/view/doBeanXMLCastorView.do 就可以看到结果了,结果如下: <?xml version="1.0" encoding="UTF-8"?> <Account id="1"><name>haha</name><email>email</email><address>北京</address><生日 brithday="2010-11-22"/></Account> 5、 转换Map集合 @RequestMapping("/doMapXMLCastorView") public ModelAndView doMapXMLCastorView() { System.out.println("#################ViewController doMapXMLCastorView##################"); ModelAndView mav = new ModelAndView("castorMarshallingView"); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("haha"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); Map<String, Object> map = new HashMap<String, Object>(); map.put("day", day); map.put("account", bean); MapBean differ = new MapBean(); differ.setMap(map); mav.addObject(differ); return mav; } 在浏览器中请求http://localhost:8080/SpringMVC4View/castor/view/doMapXMLCastorView.do 结果如下: <?xml version="1.0" encoding="UTF-8"?> <map-bean><map key="account"><Account id="1"><name>haha</name><email>email</email> <address>北京</address><生日 brithday="2010-11-22"/></Account></map> <map key="day"><brithday brithday="2010-11-22"/></map></map-bean> 6、 转换List集合 @RequestMapping("/doListXMLCastorView") public ModelAndView doListXMLCastorView() { System.out.println("#################ViewController doListXMLCastorView##################"); ModelAndView mav = new ModelAndView("castorMarshallingView"); List<Object> beans = new ArrayList<Object>(); for (int i = 0; i < 3; i++) { Account bean = new Account(); bean.setAddress("address#" + i); bean.setEmail("email" + i + "@12" + i + ".com"); bean.setId(1 + i); bean.setName("haha#" + i); Brithday day = new Brithday(); day.setBrithday("2010-11-2" + i); bean.setBrithday(day); beans.add(bean); User user = new User(); user.setAddress("china GuangZhou# " + i); user.setAge(23 + i); user.setBrithday(new Date()); user.setName("jack#" + i); user.setSex(Boolean.parseBoolean(i + "")); beans.add(user); } ListBean listBean = new ListBean(); listBean.setList(beans); mav.addObject(listBean); return mav; } 在WebBrowser中请求http://localhost:8080/SpringMVC4View/castor/view/doListXMLCastorView.do <?xml version="1.0" encoding="UTF-8"?> <listBean><Account id="1"><name>haha#0</name><email>email0@120.com</email> <address>address#0</address><生日 brithday="2010-11-20"/></Account> <user xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:java="http://java." age="23" sex="false" xsi:type="java:com.hoo.entity.User"> <address>china GuangZhou# 0</address><name>jack#0</name><brithday>2011-04-28T14:41:56.703+08:00</brithday></user> <Account id="2"><name>haha#1</name> <email>email1@121.com</email><address>address#1</address><生日 brithday="2010-11-21"/></Account> <user xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:java="http://java." age="24" sex="false" xsi:type="java:com.hoo.entity.User"> <address>china GuangZhou# 1</address><name>jack#1</name><brithday>2011-04-28T14:41:56.703+08:00</brithday></user> <Account id="3"><name>haha#2</name><email>email2@122.com</email> <address>address#2</address><生日 brithday="2010-11-22"/></Account> <user xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:java="http://java." age="25" sex="false" xsi:type="java:com.hoo.entity.User"> <address>china GuangZhou# 2</address><name>jack#2</name> <brithday>2011-04-28T14:41:56.703+08:00</brithday></user></listBean> 7、 转换对象数组 @RequestMapping("/doArrayXMLCastorView") public ModelAndView doArrayXMLCastorView() { System.out.println("#################ViewController doArrayXMLCastorView##################"); ModelAndView mav = new ModelAndView("castorMarshallingView"); Object[] beans = new Object[3]; for (int i = 0; i < 2; i++) { Account bean = new Account(); bean.setAddress("address#" + i); bean.setEmail("email" + i + "@12" + i + ".com"); bean.setId(1 + i); bean.setName("haha#" + i); Brithday day = new Brithday(); day.setBrithday("2010-11-2" + i); bean.setBrithday(day); beans[i] = bean; } User user = new User(); user.setAddress("china GuangZhou# "); user.setAge(23); user.setBrithday(new Date()); user.setName("jack#"); user.setSex(true); beans[2] = user; mav.addObject(beans); return mav; } 在WebBrowser中请求http://localhost:8080/SpringMVC4View/castor/view/doArrayXMLCastorView.do 结果输出: <?xml version="1.0" encoding="UTF-8"?> <array><Account xmlns:xsi="http://www./2001/XMLSchema-instance" id="1" xsi:type="Account"> <name>haha#0</name><email>email0@120.com</email><address>address#0</address><生日 brithday="2010-11-20"/></Account> <Account xmlns:xsi="http://www./2001/XMLSchema-instance" id="2" xsi:type="Account"><name>haha#1</name> <email>email1@121.com</email><address>address#1</address><生日 brithday="2010-11-21"/> </Account><user xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns:java="http://java." age="23" sex="true" xsi:type="java:com.hoo.entity.User"> <address>china GuangZhou# </address><name>jack#</name> <brithday>2011-04-28T14:43:43.593+08:00</brithday></user></array> 结果和List集合有点类似。 总结,使用castor可以转换普通不经过封装的Java类型,但是Map对象则需要进行简单对象封装,然后在mapping中进行描述才行。Castor和其他的框架不同的是,可以在xml配置中进行转换对象的描述规则。
五、 用Jibx转换XML 1、 jibx可以完成Java对象到xml的转换,但是它需要bind.xml的配置以及多个工具类生成Jibx_BindList信息。稍微有那么点复杂,如果在Spring中利用Jibx的话,需要添加如下jar包: 如果你还不少很了解jibx转换xml这方面的知识,可以阅读: For cnblogs:http://www.cnblogs.com/hoojo/archive/2011/04/27/2030205.html For csdn:http://blog.csdn.net/IBM_hoojo/archive/2011/04/27/6366333.aspx 2、 下面你需要在dispatcher.xml中添加如下内容 <-- 需要先编译生成bind.xml,然后再进行绑定编译生成jibx_bandList和运行所需的class --> <bean name="jibxMarshallingView" class="org.springframework.web.servlet.view.xml.MarshallingView"> <property name="marshaller"> <bean class="org.springframework.oxm.jibx.JibxMarshaller"> <property name="targetClass" value="com.hoo.entity.Account"/> </bean> </property> </bean> 注意targetClass目标对象不能为空,必须配置。这个class就是你的对象从xml转换到Java对象的那个对象类型。这里不需要从xml转换到Java,暂时就这样配置就可以了。 3、 下面需要用到Account、User、ListBean、MapBean,除了User对象的代码没有提供,其他的都提供了。下面看看User对象的代码: package com.hoo.entity; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private static final long serialVersionUID = 8606788203814942679L; private String name; private int age; private boolean sex; private String address; private Date brithday; @Override public String toString() { return this.name + "#" + this.sex + "#" + this.address + "#" + this.brithday; } } 4、 下面需要用rg.jibx.binding.BindingGenerator工具类为我们生成bind.xml内容,命令如下: 首先在dos命令控制台进入到当前工程的WEB-INF目录,然后输入命令: E:\Study\SpringMVC4View\WebRoot\WEB-INF>java -cp classes;lib/jibx-tools.jar;lib/log4j-1.2.16.jar org.jibx.binding.BindingGenerator -f bind.xml com.hoo.entity.Account com.hoo.entity.User com.hoo.entity.ListBean com.hoo.entity.MapBean 用空格分开要转换到bind.xml中的JavaBean,运行上面的命令你可以看到如下结果: Running binding generator version 0.4 Warning: field list requires mapped implementation of item classes Warning: reference to interface or abstract class java.util.Map requires mapped implementation 生成bind.xml内容如下: <?xml version="1.0" encoding="UTF-8"?> <binding value-style="attribute"> <mapping class="com.hoo.entity.Account" name="account"> <value name="id" field="id"/> <value style="element" name="name" field="name" usage="optional"/> <value style="element" name="email" field="email" usage="optional"/> <value style="element" name="address" field="address" usage="optional"/> <structure field="brithday" usage="optional" name="brithday"> <value style="element" name="brithday" field="brithday" usage="optional"/> </structure> </mapping> <mapping class="com.hoo.entity.User" name="user"> <value style="element" name="name" field="name" usage="optional"/> <value name="age" field="age"/> <value name="sex" field="sex"/> <value style="element" name="address" field="address" usage="optional"/> <value name="brithday" field="brithday" usage="optional"/> </mapping> <mapping class="com.hoo.entity.ListBean" name="list-bean"> <value style="element" name="name" field="name" usage="optional"/> <collection field="list" usage="optional" factory="org.jibx.runtime.Utility.arrayListFactory"/> </mapping> <mapping class="com.hoo.entity.MapBean" name="map-bean"> <structure field="map" usage="optional"/> </mapping> </binding> 这样还没有完,Map要经过特殊出来。我们要修改下MapBean的配置,修改后如下: <mapping class="com.hoo.entity.MapBean" name="map-bean"> <structure field="map" usage="optional" marshaller="com.hoo.util.HashMapper" unmarshaller="com.hoo.util.HashMapper"/> </mapping> HashMapper代码如下: package com.hoo.util; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.jibx.runtime.IAliasable; import org.jibx.runtime.IMarshallable; import org.jibx.runtime.IMarshaller; import org.jibx.runtime.IMarshallingContext; import org.jibx.runtime.IUnmarshaller; import org.jibx.runtime.IUnmarshallingContext; import org.jibx.runtime.JiBXException; import org.jibx.runtime.impl.MarshallingContext; import org.jibx.runtime.impl.UnmarshallingContext; /** * <b>function:</b>http://www./Open-Source/Java/XML/JiBX/tutorial/example21/HashMapper.java.htm * @file HashMapper.java * @package com.hoo.util * @project WebHttpUtils * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class HashMapper implements IMarshaller, IUnmarshaller, IAliasable { private static final String SIZE_ATTRIBUTE_NAME = "size"; private static final String ENTRY_ELEMENT_NAME = "entry"; private static final String KEY_ATTRIBUTE_NAME = "key"; private static final int DEFAULT_SIZE = 10; private String m_uri; private int m_index; private String m_name; public HashMapper() { m_uri = null; m_index = 0; m_name = "hashmap"; } public HashMapper(String uri, int index, String name) { m_uri = uri; m_index = index; m_name = name; } /* (non-Javadoc) * @see org.jibx.runtime.IMarshaller#isExtension(int) */ public boolean isExtension(int index) { return false; } /* (non-Javadoc) * @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object, * org.jibx.runtime.IMarshallingContext) */ @SuppressWarnings("unchecked") public void marshal(Object obj, IMarshallingContext ictx) throws JiBXException { // make sure the parameters are as expected if (!(obj instanceof HashMap)) { throw new JiBXException("Invalid object type for marshaller"); } else if (!(ictx instanceof MarshallingContext)) { throw new JiBXException("Invalid object type for marshaller"); } else { // start by generating start tag for container MarshallingContext ctx = (MarshallingContext)ictx; HashMap map = (HashMap)obj; ctx.startTagAttributes(m_index, m_name). attribute(m_index, SIZE_ATTRIBUTE_NAME, map.size()). closeStartContent(); // loop through all entries in hashmap Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); ctx.startTagAttributes(m_index, ENTRY_ELEMENT_NAME); if (entry.getKey() != null) { ctx.attribute(m_index, KEY_ATTRIBUTE_NAME, entry.getKey().toString()); } ctx.closeStartContent(); if (entry.getValue() instanceof IMarshallable) { ((IMarshallable)entry.getValue()).marshal(ctx); ctx.endTag(m_index, ENTRY_ELEMENT_NAME); } else { throw new JiBXException("Mapped value is not marshallable"); } } // finish with end tag for container element ctx.endTag(m_index, m_name); } } /* (non-Javadoc) * @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext) */ public boolean isPresent(IUnmarshallingContext ctx) throws JiBXException { return ctx.isAt(m_uri, m_name); } /* (non-Javadoc) * @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object, * org.jibx.runtime.IUnmarshallingContext) */ @SuppressWarnings("unchecked") public Object unmarshal(Object obj, IUnmarshallingContext ictx) throws JiBXException { // make sure we're at the appropriate start tag UnmarshallingContext ctx = (UnmarshallingContext)ictx; if (!ctx.isAt(m_uri, m_name)) { ctx.throwStartTagNameError(m_uri, m_name); } // create new hashmap if needed int size = ctx.attributeInt(m_uri, SIZE_ATTRIBUTE_NAME, DEFAULT_SIZE); HashMap map = (HashMap)obj; if (map == null) { map = new HashMap(size); } // process all entries present in document ctx.parsePastStartTag(m_uri, m_name); while (ctx.isAt(m_uri, ENTRY_ELEMENT_NAME)) { Object key = ctx.attributeText(m_uri, KEY_ATTRIBUTE_NAME, null); ctx.parsePastStartTag(m_uri, ENTRY_ELEMENT_NAME); Object value = ctx.unmarshalElement(); map.put(key, value); ctx.parsePastEndTag(m_uri, ENTRY_ELEMENT_NAME); } ctx.parsePastEndTag(m_uri, m_name); return map; } public boolean isExtension(String arg0) { return false; } } 然后,再编译下就可以了。命令如下: E:\Study\SpringMVC4View\WebRoot\WEB-INF>java -cp classes;lib/jibx-bind.jar org.jibx.binding.Compile -v bind.xml 这样你就可以启动tomcat服务器,没有错误就ok了。 5、 转换JavaBean到XML package com.hoo.controller; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.hoo.entity.Account; import com.hoo.entity.Brithday; import com.hoo.entity.ListBean; import com.hoo.entity.MapBean; import com.hoo.entity.User; /** * <b>function:</b>利用Jibx和JibxMarshaller转换Java对象到XML * @author hoojo * @createDate 2011-4-28 下午03:05:11 * @file JibxMarshallingViewController.java * @package com.hoo.controller * @project SpringMVC4View * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ @Controller @RequestMapping("/jibx/view") public class JibxMarshallingViewController { @RequestMapping("/doXMLJibxView") public ModelAndView doXMLJibxView() { System.out.println("#################ViewController doXMLJibxView##################"); ModelAndView mav = new ModelAndView("jibxMarshallingView"); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("haha"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); mav.addObject("中国"); mav.addObject(bean); return mav; } } 上面的ModelAndView配置的视图就是我们在dispatcher中配置过的视图 在WebBrowser中请求http://localhost:8080/SpringMVC4View/jibx/view/doXMLJibxView.do 结果如下: <?xml version="1.0"?><account id="1"><name>haha</name><email>email</email><address>北京</address> <brithday><brithday>2010-11-22</brithday></brithday></account> 6、 转换List到XML /** * <b>function:</b>转换带有List属性的JavaBean * @author hoojo * @return */ @RequestMapping("/doListXMLJibx") public ModelAndView doListXMLJibxView() { System.out.println("#################ViewController doListXMLJibxView##################"); ModelAndView mav = new ModelAndView("jibxMarshallingView"); List<Object> beans = new ArrayList<Object>(); for (int i = 0; i < 3; i++) { Account bean = new Account(); bean.setAddress("address#" + i); bean.setEmail("email" + i + "@12" + i + ".com"); bean.setId(1 + i); bean.setName("haha#" + i); Brithday day = new Brithday(); day.setBrithday("2010-11-2" + i); bean.setBrithday(day); beans.add(bean); User user = new User(); user.setAddress("china GuangZhou# " + i); user.setAge(23 + i); user.setBrithday(new Date()); user.setName("jack#" + i); user.setSex(Boolean.parseBoolean(i + "")); beans.add(user); } ListBean list = new ListBean(); list.setList(beans); mav.addObject(list); return mav; } 在浏览器中请求http://localhost:8080/SpringMVC4View/jibx/view/doListXMLJibx.do 结果如下: <?xml version="1.0"?><list-bean><account id="1"><name>haha#0</name><email>email0@120.com</email><address>address#0</address> <brithday><brithday>2010-11-20</brithday></brithday></account> <user age="23" sex="false" brithday="2011-04-28T08:27:23.046Z"><name>jack#0</name><address>china GuangZhou# 0</address></user> <account id="2"><name>haha#1</name><email>email1@121.com</email><address>address#1</address><brithday> <brithday>2010-11-21</brithday></brithday></account><user age="24" sex="false" brithday="2011-04-28T08:27:23.046Z"> <name>jack#1</name><address>china GuangZhou# 1</address></user> <account id="3"><name>haha#2</name><email>email2@122.com</email><address>address#2</address> <brithday><brithday>2010-11-22</brithday></brithday></account> <user age="25" sex="false" brithday="2011-04-28T08:27:23.046Z"><name>jack#2</name> <address>china GuangZhou# 2</address></user></list-bean> 7、 转换Map到XML /** * <b>function:</b>转换带有Map属性的JavaBean * @author hoojo * @return */ @RequestMapping("/doMapXMLJibx") public ModelAndView doMapXMLJibxView() { System.out.println("#################ViewController doMapXMLJibxView##################"); ModelAndView mav = new ModelAndView("jibxMarshallingView"); MapBean mapBean = new MapBean(); Map<String, Object> map = new HashMap<String, Object>(); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("jack"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); map.put("NO1", bean); bean = new Account(); bean.setAddress("china"); bean.setEmail("tom@125.com"); bean.setId(2); bean.setName("tom"); day = new Brithday("2011-11-22"); bean.setBrithday(day); map.put("NO2", bean); mapBean.setMap(map); mav.addObject(mapBean); return mav; } 在浏览器中请求:http://localhost:8080/SpringMVC4View/jibx/view/doMapXMLJibx.do 结果如下: <?xml version="1.0"?> <map-bean><hashmap size="2"><entry key="NO2"><account id="2"><name>tom</name><email>tom@125.com</email><address>china</address> <brithday><brithday>2011-11-22</brithday></brithday></account> </entry><entry key="NO1"><account id="1"><name>jack</name><email>email</email><address>北京</address> <brithday><brithday>2010-11-22</brithday></brithday></account></entry></hashmap></map-bean> 总结,jibx应用比较广,在WebService中都有使用jibx。Jibx速度比较快,就是在开始部署使用的时候需要写bind.xml文件。不过官方提供了工具类,这个也不麻烦。
六、 Jackson转换Java对象 1、 jackson有专门的视图MappingJacksonJsonView,只需用配置这个视图就可以完成转换json了。使用jackson需要添加如下jar包: 如果你对Jackson转换Java对象还没有什么了解的话,你可以参考: For cnblogs:http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html For csdn:http://blog.csdn.net/IBM_hoojo/archive/2011/04/22/6340762.aspx 2、 然后需要在dispatcher.xml中添加视图配置,配置如下: <bean name="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"> <property name="encoding"> <value type="org.codehaus.jackson.JsonEncoding">UTF8</value> </property> <property name="contentType" value="text/html;charset=UTF-8"/> </bean> 3、 将Java对象转换JSON package com.hoo.controller; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.hoo.entity.Account; import com.hoo.entity.Brithday; import com.hoo.entity.User; /** * <b>function:</b>用MappingJacksonJsonView视图和Jackson转换Json * @author hoojo * @createDate 2011-4-28 下午04:52:23 * @file JacksonJsonViewController.java * @package com.hoo.controller * @project SpringMVC4View * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ @Controller @RequestMapping("/jackson/view") public class JacksonJsonViewController { /** * <b>function:</b>转换普通Java对象 * @author hoojo * @createDate 2011-4-28 下午05:14:18 * @return */ @RequestMapping("/doBeanJsonView") public ModelAndView doBeanJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonView"); User user = new User(); user.setAddress("china GuangZhou"); user.setAge(23); user.setBrithday(new Date()); user.setName("jack"); user.setSex(true); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("haha"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); mav.addObject(bean); return mav; } } 上面使用了刚才我们配置的jsonView视图,通过这个视图就可以将ModelAndView中的数据转换成JSON数据。 在浏览器中请求:http://localhost:8080/SpringMVC4View/jackson/view/doBeanJsonView.do 结果如下: {"account":{"address":"北京","name":"haha","id":1,"email":"email","brithday":{"brithday":"2010-11-22"}}} 4、 转换Map到JSON /** * <b>function:</b>转换Map集合 * @author hoojo * @createDate 2011-4-28 下午05:14:33 * @return */ @RequestMapping("/doMapJsonView") public ModelAndView doMapJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonView"); User user = new User(); user.setAddress("china GuangZhou"); user.setAge(23); user.setBrithday(new Date()); user.setName("jack"); user.setSex(true); Map<String, Object> map = new HashMap<String, Object>(); map.put("user", user); map.put("success", true); mav.addObject(map); mav.addObject("title", "ViewController doBeanJsonView"); return mav; } 在WebBrowser中请求:http://localhost:8080/SpringMVC4View/jackson/view/doMapJsonView.do 结果如下: {"hashMap":{"success":true,"user":{"address":"china GuangZhou","name":"jack","age":23,"sex":true,"brithday":1303982296953}}, "title":"ViewController doBeanJsonView"} 5、 转换List到JSON /** * <b>function:</b>转换List集合 * @author hoojo * @createDate 2011-4-28 下午05:14:54 * @return */ @RequestMapping("/doListJsonView") public ModelAndView doListJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonView"); List<User> list = new ArrayList<User>(); for (int i = 0; i < 3; i++) { User user = new User(); user.setAddress("china GuangZhou#" + i); user.setAge(23 + i); user.setBrithday(new Date()); user.setName("jack_" + i); user.setSex(true); list.add(user); } mav.addObject(list); return mav; } 在浏览器中请求http://localhost:8080/SpringMVC4View/jackson/view/doListJsonView.do 结果如下: {"userList":[{"address":"china GuangZhou#0","name":"jack_0","age":23,"sex":true,"brithday":1303982399265}, {"address":"china GuangZhou#1","name":"jack_1","age":24,"sex":true,"brithday":1303982399265}, {"address":"china GuangZhou#2","name":"jack_2","age":25,"sex":true,"brithday":1303982399265}]} 总结,spring对jackson提供了专门的视图,整合起来也比较方便。而且jackson也比较简单易用。
七、 JSON-lib转换Java到JSON 1、 Spring没有提供JSON-lib的view视图,不过没有关系。我们可以自己扩展一个,只需用继承AbstractView类,实现里面的方法就可以了。首先你需要了解JSON-lib,如果你还不了解JSON-lib的话,建议阅读: For cnblogs: http://www.cnblogs.com/hoojo/archive/2011/04/21/2023805.html For csdn: http://blog.csdn.net/IBM_hoojo/archive/2011/04/21/6339246.aspx 然后你需要在工程中添加如下jar文件: 2、 因为Spring没有提供view,我们需要自己实现一个。代码如下: package com.hoo.veiw.xml; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONSerializer; import net.sf.json.JsonConfig; import org.springframework.util.CollectionUtils; import org.springframework.validation.BindingResult; import org.springframework.web.servlet.view.AbstractView; /** * <b>function:</b>扩展AbstractView 实现JSON-lib视图 * @author hoojo * @createDate 2011-4-28 下午05:26:43 * @file MappingJsonlibVeiw.java * @package com.hoo.veiw.xml * @project SpringMVC4View * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class MappingJsonlibVeiw extends AbstractView { public static final String DEFAULT_CONTENT_TYPE = "application/json"; public static final String DEFAULT_CHAR_ENCODING = "UTF-8"; private String encodeing = DEFAULT_CHAR_ENCODING; public void setEncodeing(String encodeing) { this.encodeing = encodeing; } private Set<String> renderedAttributes; private JsonConfig cfg = null; public void setCfg(JsonConfig cfg) { this.cfg = cfg; } public MappingJsonlibVeiw() { setContentType(DEFAULT_CONTENT_TYPE); } @Override protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { model = filterModel(model); response.setCharacterEncoding(encodeing); PrintWriter out = response.getWriter(); if (cfg == null) { out.print(JSONSerializer.toJSON(model)); } else { out.print(JSONSerializer.toJSON(model, cfg)); } } /** * Filters out undesired attributes from the given model. * <p>Default implementation removes {@link BindingResult} instances and entries not included in the {@link * #setRenderedAttributes(Set) renderedAttributes} property. */ protected Map<String, Object> filterModel(Map<String, Object> model) { Map<String, Object> result = new HashMap<String, Object>(model.size()); Set<String> renderedAttributes = !CollectionUtils.isEmpty(this.renderedAttributes) ? this.renderedAttributes : model.keySet(); for (Map.Entry<String, Object> entry : model.entrySet()) { if (!(entry.getValue() instanceof BindingResult) && renderedAttributes.contains(entry.getKey())) { result.put(entry.getKey(), entry.getValue()); } } return result; } } 上面的代码不是很复杂,首先我们设置contentType,这个属性在AbstractView这个父类中有setter方法可以完成设置。 然后就是默认的编码格式,这个编码格式设置到response上。默认UTF-8编码。在renderMergedOutputModel方法中可以看到设置。 第三就是filterModule方法,这个方法是得到ModelAndView中我们添加对象,过滤掉BindingResult的信息。 最后就是renderMergedOutputModel方法,这个方法最为核心,但也很简单。过滤model获得要转换的model数据,设置response编码格式。利用response的Writer输出JSON信息,通过JSONSerializer转换Java到JSON。 3、 在dispatcher.xml中配置jsonlibView这个视图 <-- 自定义JSONlib的json视图 --> <bean name="jsonlibView" class="com.hoo.veiw.xml.MappingJsonlibVeiw"> <property name="contentType" value="text/html;charset=UTF-8"/> <property name="encodeing" value="gbk"/> </bean> 4、 转换普通Java对象 package com.hoo.controller; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import com.hoo.entity.Account; import com.hoo.entity.Brithday; import com.hoo.entity.User; /** * <b>function:</b> * @author hoojo * @createDate 2011-4-28 下午05:58:02 * @file JsonlibMappingViewController.java * @package com.hoo.controller * @project SpringMVC4View * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ @Controller @RequestMapping("/jsonlib/view") public class JsonlibMappingViewController { /** * <b>function:</b>转换普通Java对象 * @author hoojo * @createDate 2011-4-28 下午05:14:18 * @return */ @RequestMapping("/doBeanJsonView") public ModelAndView doBeanJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonlibView"); User user = new User(); user.setAddress("china GuangZhou"); user.setAge(23); user.setBrithday(new Date()); user.setName("jack"); user.setSex(true); Account bean = new Account(); bean.setAddress("北京"); bean.setEmail("email"); bean.setId(1); bean.setName("haha"); Brithday day = new Brithday(); day.setBrithday("2010-11-22"); bean.setBrithday(day); mav.addObject(bean); return mav; } } 在WebBrowser中请求http://localhost:8080/SpringMVC4View/jsonlib/view/doBeanJsonView.do 结果如下: {"account":{"address":"北京","brithday":{"brithday":"2010-11-22"},"email":"email","id":1,"name":"haha"}} 5、 转换Map到JSON /** * <b>function:</b>转换Map集合 * @author hoojo * @createDate 2011-4-28 下午05:14:33 * @return */ @RequestMapping("/doMapJsonView") public ModelAndView doMapJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonlibView"); User user = new User(); user.setAddress("china GuangZhou"); user.setAge(23); user.setBrithday(new Date()); user.setName("jack"); user.setSex(true); Map<String, Object> map = new HashMap<String, Object>(); map.put("user", user); map.put("success", true); mav.addObject(map); mav.addObject("title", "ViewController doBeanJsonView"); return mav; } 在WebBrowser中请求http://localhost:8080/SpringMVC4View/jsonlib/view/doMapJsonView.do 结果如下: {"hashMap":{"success":true,"user":{"address":"china GuangZhou","age":23, "brithday":{"date":28,"day":4,"hours":18,"minutes":20,"month":3,"seconds":8, "time":1303986008703,"timezoneOffset":-480,"year":111},"name":"jack","sex":true}}, "title":"ViewController doBeanJsonView"} 发现时间被分解成一个对象了,这里需要用JSONConfig的JsonValueProcessor将brithday过滤下,然后用SimpleDateFormate进行格式转换。 6、 转换List集合 /** * <b>function:</b>转换List集合 * @author hoojo * @createDate 2011-4-28 下午05:14:54 * @return */ @RequestMapping("/doListJsonView") public ModelAndView doListJsonView() { System.out.println("#################ViewController doBeanJsonView##################"); ModelAndView mav = new ModelAndView("jsonlibView"); List<User> list = new ArrayList<User>(); for (int i = 0; i < 3; i++) { User user = new User(); user.setAddress("china GuangZhou#" + i); user.setAge(23 + i); user.setBrithday(new Date()); user.setName("jack_" + i); user.setSex(true); list.add(user); } mav.addObject(list); return mav; } 在浏览器中请求http://localhost:8080/SpringMVC4View/jsonlib/view/doListJsonView.do 结果如下: {"userList":[{"address":"china GuangZhou#0","age":23,"brithday":{"date":28,"day":4,"hours":19,"minutes":2,"month":3,"seconds":54, "time":1303988574328,"timezoneOffset":-480,"year":111},"name":"jack_0","sex":true}, {"address":"china GuangZhou#1","age":24,"brithday":{"date":28,"day":4,"hours":19,"minutes":2,"month":3,"seconds":54, "time":1303988574328,"timezoneOffset":-480,"year":111},"name":"jack_1","sex":true},{"address":"china GuangZhou#2","age":25, "brithday":{"date":28,"day":4,"hours":19,"minutes":2,"month":3,"seconds":54,"time":1303988574328,"timezoneOffset":-480,"year":111}, "name":"jack_2","sex":true}]} |
|