我有一个要通过Jersey RESTful API公开的类。它看起来类似于:
@XmlRootElement
public class Data {
public String firstName;
public String lastName;
}
我的问题是这些字段可能为null,在这种情况下,该字段会从JSON输出中省略。我希望所有字段都可以出现,而不论它们的价值如何。例如,如果lastName为null,则JSON输出为:
{
"firstName" : "Oleksi"
}
而不是我想要的:
{
"firstName" : "Oleksi",
"lastName" : null
}
我有一个看起来像这样的JAXBContextResolver(ContextResolver的实现):
@Provider
public class JAXBContextResolver implements ContextResolver<JAXBContext> {
// internal state
private final JAXBContext context;
private final Set<Class> types;
private final Class[] cTypes = { Data.class };
public JAXBContextResolver()
throws Exception {
types = new HashSet(Arrays.asList(cTypes));
context = new JSONJAXBContext(JSONConfiguration.natural().humanReadableFormatting(true).build(), cTypes);
}
@Override
public JAXBContext getContext(Class<?> objectType) {
return (types.contains(objectType)) ? context : null;
}
}
我一直试图弄清楚如何获得所需的输出,但是我没有运气。我愿意尝试其他ContextResolvers /
Serializers,但我一直找不到能起作用的代码,因此代码示例将是不错的选择。
对于 EclipseLink JAXB(MOXy)
的JSON绑定,正确的映射如下。您可以与您的提供商一起尝试,以查看它是否也可以工作:
@XmlRootElement
public class Data {
@XmlElement(nillable=true)
public String firstName;
@XmlElement(nillable=true)
public String lastName;
}
想要查询更多的信息
更新2
EclipseLink 2.4包含的MOXyJsonProvider
是MessageBodyReader
/
的实现MessageBodyWriter
,您可以直接使用它来利用MOXy的JSON绑定
更新1
以下MessageBodyReader
/ MessageBodyWriter
更适合您:
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import javax.xml.transform.stream.StreamSource;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.ext.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
@Provider
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MOXyJSONProvider implements
MessageBodyReader<Object>, MessageBodyWriter<Object>{
@Context
protected Providers providers;
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
try {
Class<?> domainClass = getDomainClass(genericType);
Unmarshaller u = getJAXBContext(domainClass, mediaType).createUnmarshaller();
u.setProperty("eclipselink.media-type", mediaType.toString());
u.setProperty("eclipselink.json.include-root", false);
return u.unmarshal(new StreamSource(entityStream), domainClass).getValue();
} catch(JAXBException jaxbException) {
throw new WebApplicationException(jaxbException);
}
}
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return true;
}
public void writeTo(Object object, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
try {
Class<?> domainClass = getDomainClass(genericType);
Marshaller m = getJAXBContext(domainClass, mediaType).createMarshaller();
m.setProperty("eclipselink.media-type", mediaType.toString());
m.setProperty("eclipselink.json.include-root", false);
m.marshal(object, entityStream);
} catch(JAXBException jaxbException) {
throw new WebApplicationException(jaxbException);
}
}
public long getSize(Object t, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return -1;
}
private JAXBContext getJAXBContext(Class<?> type, MediaType mediaType)
throws JAXBException {
ContextResolver<JAXBContext> resolver
= providers.getContextResolver(JAXBContext.class, mediaType);
JAXBContext jaxbContext;
if(null == resolver || null == (jaxbContext = resolver.getContext(type))) {
return JAXBContextFactory.createContext(new Class[] {type}, null);
} else {
return jaxbContext;
}
}
private Class<?> getDomainClass(Type genericType) {
if(genericType instanceof Class) {
return (Class<?>) genericType;
} else if(genericType instanceof ParameterizedType) {
return (Class<?>) ((ParameterizedType) genericType).getActualTypeArguments()[0];
} else {
return null;
}
}
}
问题内容: 在1.6.0_16 JDK上工作时,我使用Apache CXF 2.5.2从WSDL生成了存根类,Apache CXF 2.5.2使用了最新的jaxb- api 2.2。我知道可以使用jaxb-api 2.1,但是为了避免兼容性问题,我宁愿使用当前版本。由于我的JDK具有jaxb 2.1,因此构建失败并显示以下消息: 因此,我尝试使用以下依赖项使Maven包括最新的jaxb api和i
问题内容: 和服务: 我的web.xml: 如果我将MediaType.APPLICATION_XML设置为Produces注释,则所有这些工作都可以进行。但是对于JSON,我得到以下异常: 严重:映射的响应异常:500(内部服务器错误)javax.ws.rs.WebApplicationException:com.sun.jersey.api.MessageException:Java类java
问题内容: 我需要在jaxb中将空值显示为空元素。我正在使用jaxb的moxy实现。我找到了这个选项 是否可以在类级别应用任何类似的扩展(对于其中定义的所有元素) 问题答案: 我强烈建议使用不存在节点或使用属性来表示。这与模式验证(即或不是有效的type元素)一起使用时效果最佳。但是,如果不能这样做,那么可以完成用例: 标准JAXB行为 使用标准的API,你可以控制NULL是表示为不存在的节点或与
我有两个XSD,其中一个XSD包含一个元素,该元素可以包含第二个XSD中的元素。基本上,XSD1有一个元素“etta”,它可以包含XSD2中的任何元素。 我使用xjc生成类,当它被反序列化时,元元素将XSD2中的元素作为JAXBElements包含,而不是XSD2中生成的实际类。我在我的程序中包含了这两组类,包信息是正确的。 这就是我定义XSD的方式。我想问题在于我的“任何”元素。 因此,基本上我
我正在用java中的jackson构建一个json体。它会像下面这样 基于不同的 REST URI,json 主体必须忽略某些字段或元素。如何使用杰克逊忽略上述 json 正文中的“学生”部分?当我忽略它时,我应该只能得到 但我得到它如下,这是不正确的- 我有两个带有getters和setters的类,一个作为主语,另一个作为学生。我尝试使用@JsonIgnore,但是它忽略了所有的URI,这是我
问题内容: 我该如何转: 到这个: 或者更确切地说,是否有任何有用的资源可供阅读,以便能够生成该JSON输出?所以我知道我需要将我的数据“转换”为正确的数据结构。之后,就像 谢谢 问题答案: 使用json库。 然后使用以下方法转换数据: 并致电: