- 从String中转成JSON对象
最近使用json来传递对象,JAXB,基于JAVA annotation,因此代码简洁,所以选用支持JAXB的MOXy,以前一直用google Gson,这个适合手动解析JSON,它在一些很大的JSON对象上速度很快,但是不利于快速开发,且维护复杂,代码不友好。
Gson中的fromJson 方法也可以解析简单对象,如{"type":0,"score":0.0}。但复杂对象,包含数组,内嵌其他对象,我没有成功。
第一次使用MOXy,版本2.5.0,解析JSON出错:
MOXy deserialization exception: A descriptor with default root element was not found in the project
网上查了下,statckoverflow的
上面说是没有指定root属性:
public static <T>T fromJson(StreamSource streamSource, Class<?> cls, boolean hasRoot)
throws JAXBException, ClassCastException {
Map<String, Object> properties = new HashMap<String, Object>(2);
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, hasRoot);//---->这个需要设为false
.createContext(new Class[] { cls }, properties);
Unmarshaller un = jc.createUnmarshaller();
JAXBElement<T> elem = (JAXBElement<T>) un.unmarshal(streamSource,cls);//-->当JSON不含root时,必须指定cls类型。所以,这里必须要用StreamSource,而不能直接用reader,否则没法指定cls类型。
return (T)(elem.getValue());
}
import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import org.eclipse.persistence.jaxb.JAXBContextProperties; public class DtoUtil { @SuppressWarnings("unchecked") public static <T>T fromJson(StreamSource streamSource, Class<?> cls, boolean hasRoot) throws JAXBException, ClassCastException { Map<String, Object> properties = new HashMap<String, Object>(2); properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, hasRoot); JAXBContext jc = org.eclipse.persistence.jaxb.JAXBContextFactory .createContext(new Class[] { cls }, properties); Unmarshaller un = jc.createUnmarshaller(); JAXBElement<T> elem = (JAXBElement<T>) un.unmarshal(streamSource,cls); return (T)(elem.getValue()); } public static <T> String toJson(T obj,Class<?>cls,boolean hasRoot) throws JAXBException, ClassCastException { Map<String, Object> properties = new HashMap<String, Object>(2); properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, hasRoot); JAXBContext jc = org.eclipse.persistence.jaxb.JAXBContextFactory .createContext(new Class[] { cls }, properties); Marshaller marshaller = jc.createMarshaller(); StringWriter writer = new StringWriter(); marshaller.marshal(obj, writer); return writer.toString(); } }
maven dependency:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0</version>
</dependency>
用法,如:
DtoUtil.fromJson(new StreamSource(reader), cls, hasRoot);
DtoUtil.toJson(obj, cls, hasRoot);