我正试图转移到泽西岛2.0。这给了我杰克逊的痛苦,文档推荐使用Moxy。
我让Moxy为get和post调用工作,其中一切都匹配得很好但是我需要处理可能的未知元素。
// Handle unknown deserialization parameters
@JsonAnySetter
protected void handleUnknown(String key, Object value) {
if (unknownParameters == null) {
unknownParameters = new HashMap<>();
}
unknownParameters.put(key, value);
}
这在改用jersey 2.0之前效果很好,即使它不会引起任何问题,但是当它离开它时也永远不会被调用。
如何在Jersey 2.0中实现此功能?我对Moxy或Jackson很好。
我的依赖
'org.codehaus.jackson:jackson-mapper-asl:1.9.2',
'org.eclipse.persistence:org.eclipse.persistence.moxy:2.5.0',
'org.glassfish.jersey.media:jersey-media-moxy:2.0',
这对我的web.xml没有影响
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
答案 0 :(得分:8)
您可以使用jersey-media-json-jackson
模块而不是MOXy来利用注释(我不确定MOXy是否支持类似功能)。只有几点说明:
com.sun.jersey.api.json.POJOMappingFeature
中删除web.xml
init参数 - Jersey 2.x无法识别此属性(特定于Jersey 1.x)org.glassfish.jersey.media:jersey-media-moxy:2.0
依赖org.glassfish.jersey.media:jersey-media-json-jackson:2.0
依赖项并注册JacksonFeature(见下文)在这些步骤之后,杰克逊应该处理对象&lt; - &gt; JSON(联合国)编组,它应该识别@JsonAnySetter
。
要在您的应用中注册JacksonFeature
,请参阅用户指南(8.1.4 Jackson)中的专用部分:
// Create JAX-RS application.
final Application application = new ResourceConfig()
.packages("org.glassfish.jersey.examples.jackson")
.register(MyObjectMapperProvider.class) // No need to register this provider if no special configuration is required.
.register(JacksonFeature.class);
答案 1 :(得分:4)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
MOXy没有直接相当于杰克逊的@JsonAnySetter
。我已输入以下增强请求以添加此类行为:
以下是一些可能适用于您的用例的MOXy扩展的一些信息。
@XmlVirtualAccessMethods
如果JSON属性不是真的未知,它们就不会作为域模型的属性存在,那么您可以使用MOXy的@XmlVirtualAccessMethods
扩展名(请参阅:http://blog.bdoughan.com/2011/06/extensible-models-with-eclipselink-jaxb.html)。
Java模型
<强> 客户 强>
@XmlVirtualAccess
方法注释用于指定Customer
类是可扩展的。
import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlVirtualAccessMethods;
@XmlVirtualAccessMethods(setMethod = "put")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
private String firstName;
private Address billingAddress;
@XmlTransient
private Map<String, Object> extensions = new HashMap<String, Object>();
public <T> T get(String property) {
return (T) extensions.get(property);
}
public void put(String property, Object value) {
extensions.put(property, value);
}
}
<强> 地址 强>
package forum18068176;
public class Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
映射文档(oxm.xml)
扩展属性的定义在MOXy的映射文档中定义(请参阅:http://blog.bdoughan.com/2011/04/moxys-xml-metadata-in-jax-rs-service.html)。
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum18068176">
<java-types>
<java-type name="Customer">
<xml-type prop-order="firstName lastName billingAddress shippingAddress"/>
<java-attributes>
<xml-element
java-attribute="lastName"
type="java.lang.String"/>
<xml-element
java-attribute="shippingAddress"
type="forum18068176.Address"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
<强>演示强>
下面是一些独立的演示代码,您可以运行它们来查看一切是如何工作的。您需要将MOXy指定为JAXB提供程序(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)。
package forum18068176;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum18068176/oxm.xml");
properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties);
// Unmarshal JSON
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource json = new StreamSource("src/forum18068176/input.json");
Customer customer = unmarshaller.unmarshal(json, Customer.class).getValue();
// Access Extension Properties
String lastName = customer.<String>get("lastName");
Address shippingAddress = customer.<Address>get("shippingAddress");
// Marshal Objects
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(customer, System.out);
}
}
<强> input.json /输出强>
{
"firstName" : "Jane",
"lastName" : "Doe",
"billingAddress" : {
"street" : "1 A Street"
},
"shippingAddress" : {
"street" : "2 B Road"
}
}
XmlAdapter
如果所有未知项都属于同一类型,那么您可以结合使用MOXy的@XmlVariableNode
(请参阅:http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-json-schema.html)和XmlAdapter
来获得所需的结果:
答案 2 :(得分:2)
Jersey 2.0应该可以与来自https://github.com/FasterXML/jackson-jaxrs-providers的未经修改的Jackson 2.x JAX-RS提供商一起使用。由于提供程序使用服务提供程序接口,因此无需通过web.xml配置任何内容。唯一可能的问题来自于为同一媒体类型提供多个提供商。
确保使用2.x(如2.2.2)版本的Jackson依赖项。虽然Jackson 1.x和2.x版本可以共存,但模块之间的依赖关系必须匹配(即,2.2 JAX-RS提供程序依赖于2.2 jackson-core和jackson-databind jar)。