REST java中的通用响应处理
我已经创建了如下的REST响应
@XmlRootElement(name = "customer_info")
@JsonIgnoreProperties(value = { "map" })
public class Customer {
private String name;
private Integer id;
private long time;
private Map<String, Object> map = new TreeMap<>();
@JsonAnyGetter
public Map<String, Object> getMap() {
return map;
}
@JsonAnySetter
public void setMap(String name, Object values) {
this.map.put(name, values);
}
}
我想用附加参数动态创建这个响应。后端返回一个映射,该映射将包含该属性的附加属性
<customer_info>
<name></name>
<id></id>
<!--The below will have dynamic prop based on key-->
<dynamic1></dynamic1>
<dynamic2></dynamic2>
</customer_info>
应用程序配置
ResourceConfig config = new DefaultResourceConfig();
config.add(resources);
Map<String, MediaType> type = config.getMediaTypeMappings()
type.put("json", MediaType.APPLICATION_JSON_TYPE);
type.put("xml", MediaType.APPLICATION_XML_TYPE);
servletHandler.addServlet(new ServletHolder(new ServletContainer(config)), "/*");
当我添加地图时,xml结构如下所示,这是不正确的。我需要上面的xml结构。有人能指导我如何实现这一点吗
此外,XML元素的名称应与映射中的键相同。JSON响应工作正常,但xml结构不正确
<customer_info>
<name></name>
<id></id>
<!--The below will have dynamic prop based on key-->
<map>
<entry>
<key>dummy_param1</key>
<value>11</value>
</entry>
<entry>
<key>dummy_param2</key>
<value>10</value>
</entry>
<map>
</customer_info>
我使用Jersey作为REST框架,并在Jetty服务器上运行。 我正在使用该提供商,并使用springs和REST服务注册它
<bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
<bean class="com.dummy.CustomerService"/>
<bean class="com.dummy.Service2"/>
<bean class="com.dummy.Service3"/>
库gradle配置如下所示:
"org.codehaus.jackson:jackson-core-asl:1.9.2",
"org.codehaus.jackson:jackson-jaxrs:1.9.2",
"org.codehaus.jackson:jackson-mapper-asl:1.9.2",
"org.codehaus.jackson:jackson-xc:1.9.2",
"com.sun.jersey:jersey-client:1.12",
"com.sun.jersey:jersey-core:1.12",
"com.sun.jersey:jersey-json:1.12",
"com.sun.jersey:jersey-server:1.12",
"com.sun.jersey:jersey-servlet:1.12",
"org.codehaus.jettison:jettison:1.1",
"javax.ws.rs:jsr311-api:1.1.1",
"com.sun.jersey.contribs:jersey-apache-client:1.12",
"com.sun.jersey.contribs:jersey-apache-client4:1.12",
"com.sun.jersey.contribs:jersey-multipart:1.12",
"com.sun.jersey:jersey-client:1.12",
"com.sun.jersey:jersey-core:1.12",
"com.sun.jersey:jersey-json:1.12",
"javax.ws.rs:jsr311-api:1.1.1",
"org.codehaus.jackson:jackson-core-asl:1.9.2",
"org.codehaus.jackson:jackson-jaxrs:1.9.2",
"org.codehaus.jackson:jackson-mapper-asl:1.9.2",
"org.codehaus.jackson:jackson-xc:1.9.2",
"javax.servlet:javax.servlet-api:3.1.0",
"org.eclipse.jetty:ecs-jetty-server:9.4.0.v20161208",
"org.eclipse.jetty:jetty-util:9.4.0.v20161208",
"org.eclipse.jetty:jetty-servlet:9.4.0.v20161208",
"org.eclipse.jetty:jetty-servlets:9.4.0.v20161208",
"org.eclipse.jetty:jetty-http:9.4.0.v20161208",
"org.eclipse.jetty:jetty-security:9.4.0.v20161208",
"org.eclipse.jetty:jetty-io:9.4.0.v20161208",
"org.eclipse.jetty:jetty-continuation:9.4.0.v20161208",
"org.eclipse.jetty:jetty-deploy:9.4.0.v20161208",
"org.eclipse.jetty:jetty-webapp:9.4.0.v20161208",
"org.eclipse.jetty:jetty-xml:9.4.0.v20161208"
还有人可以建议如何修复上述问题吗? 提前谢谢
# 1 楼答案
使用JAXB是不可能的,但是如果您想切换到使用Jackson for XML,那么您很容易实现这一点。你需要做的就是用
@JsonAnyGetter
注释bean中的Map
getter。这将导致Jackson将映射键序列化为XML中的普通元素。这是一个测试这将产生以下XML
要使用Jackson for XML,需要执行以下操作:
添加Jackson依赖项并删除(排除)JAXB提供程序
您应该将JAXB提供程序从
jersey-container-servlet
依赖项中排除,该依赖项应该已经存在于您的项目中。这个${jackson2.version}
应该是您当前在项目中使用的任何版本的Jackson。如果你对Jackson没有任何明确的依赖关系,但是正在使用jersey-media-json-jackson
,那么找出吸引你的是什么版本的Jackson。您要确保没有任何冲突的版本您需要向Jersey注册
JacksonJaxbXMLProvider
完成这两件事后,它应该会起作用
使用Jackson for XML最酷的一点是,用于JSON的Jackson注释也可以用于XML,比如
@JsonProperty
。Jackson也理解JAXB注释(大多数)。因此,当您从JAXB迁移到Jackson时,您可能只需要保持JAXB注释不变。就道具顺序而言,它将不适用于动态属性,仅适用于已定义的属性另见
ContextResolver<XmlMapper>
更新
如果无法向项目中添加任何新的依赖项,那么另一种方法就是使用
org.w3c.dom
api(标准Java类)动态创建XML。这将是更冗长和更多的工作,但它会让你得到你想要的。参见this post了解一些解释。下面是一个例子。添加评论应该很容易理解