- 从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);