问题描述
我希望有一种灵活的编组方式。单个对象的详细版本和多个对象版本的详细版本。
例如,考虑我的部门模型:
获取/位置/ 1:
< location id ='1'>
< link rel =selfhref =http://example.com/locations/1/>
< link rel =parenthref =http://example.com/serviceareas/1/>
< name> location 01< / name>
< departments>
< department id ='1'>
< link rel =selfhref =http://example.com/departments/1/>
< name> department 01< / name>
< / department>
< department id ='2'>
< link rel =selfhref =http://example.com/departments/2/>
< name> department 02< / name>
< / department>
< department id ='3'>
< link rel =selfhref =http://example.com/departments/3/>
< name> department 03< / name>
< / department>
< / departments>
< / location>
GET / department / 1:
< department id ='1'>
< link rel =selfhref =http://example.com/departments/1/>
< link rel =parenthref =http://example.com/locations/1/>
< name> department 01< / name>
< abbr> dept 01< / abbr>
....
< special>重症监护< / special>
< / department>
有没有办法做到这一点?我需要有单独的实体对象吗?一个引用CRUD操作表而另一个引用列表?
注意:我是领导,以及专家如果您使用的是 EclipseLink JAXB(MOXy) strong>您可以利用外部绑定文档将第二个映射应用于 Department
类。
ContextResolver
在 JAX-RS 环境中,您可以通过 ContextResolver
来利用MOXy的外部绑定文档:
import java.io. *;
import java.util。*;
import javax.ws.rs.Produces;
import javax.ws.rs.ext。*;
import javax.xml.bind。*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
@Provider
@Produces({application / xml,application / json})
公共类DepartmentContextResolver实现ContextResolver< JAXBContext> {
private JAXBContext jc;
public DepartmentContextResolver(){
try {
Map< String,Object> props = new HashMap< String,Object>(1);
props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY,example / bindings.xml);
jc = JAXBContext.newInstance(new Class [] {Department.class},props);
} catch(JAXBException e){
抛出新的RuntimeException(e);
}
}
public JAXBContext getContext(Class<?> clazz){
if(Department.class == clazz){
return jc ;
}
返回null;
}
}
更多信息
外部装订文件
默认情况下,MOXy的外部绑定文档用于扩充带注释的模型,但如果设置 xml-mapping-metadata-complete
标志,它将完全覆盖允许您的注释应用完全不同的映射:
< xml-bindings
xmlns =http://www.eclipse .ORG /的EclipseLink / XSD文件/持续ence / oxm
package-name =example
xml-mapping-metadata-complete =true>
...
< / xml-bindings>
更多信息
更新
此更新旨在解答您在一条评论中提出的一些问题:
是每个 ContextResolver
应该有自己的绑定文件。引入新的 ContextResolver
的主要原因是表示辅助映射。
对于单个 ContextResolver
,您可以在多个绑定文件中表达元数据,但它们将合并为一组映射。这意味着单个 ContentResolver
不能拥有单个类的多个视图。单独的 ContextResolver
用于表示辅助映射。
我建议从类路径加载元数据文件。
你的JAX-RS实现应该拿起 ContextResolver
因为它是用 @Provider
注释的。用于类的 ContextResolver
将取决于您如何实现 getContext
方法:
public JAXBContext getContext(Class<?> clazz){
if(Customer.class == clazz){
return jc;
}
返回null;
}
I'm hoping to have a flexible way of marshalling objects. A verbose version for single objects and a less-verbose version for multiple object versions.
For example, consider my department model:
GET /locations/1:
<location id='1'>
<link rel="self" href="http://example.com/locations/1"/>
<link rel="parent" href="http://example.com/serviceareas/1"/>
<name>location 01</name>
<departments>
<department id='1'>
<link rel="self" href="http://example.com/departments/1"/>
<name>department 01</name>
</department>
<department id='2'>
<link rel="self" href="http://example.com/departments/2"/>
<name>department 02</name>
</department>
<department id='3'>
<link rel="self" href="http://example.com/departments/3"/>
<name>department 03</name>
</department>
</departments>
</location>
GET /department/1:
<department id='1'>
<link rel="self" href="http://example.com/departments/1"/>
<link rel="parent" href="http://example.com/locations/1"/>
<name>department 01</name>
<abbr>dept 01</abbr>
....
<specialty>critical care</specialty>
</department>
Is there a way to do this? Would I need to have separate entity objects? One that references the table for CRUD operations and another for lists?
Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB 2 (JSR-222) expert group.
Your question is tagged EclipseLink
, if you are using EclipseLink JAXB (MOXy) you can take advantage of the external binding document to apply a second mapping to the Department
class.
ContextResolver
In a JAX-RS environment you can leverage MOXy's external binding document through a ContextResolver
:
import java.io.*;
import java.util.*;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
@Provider
@Produces({"application/xml", "application/json"})
public class DepartmentContextResolver implements ContextResolver<JAXBContext> {
private JAXBContext jc;
public DepartmentContextResolver() {
try {
Map<String, Object> props = new HashMap<String, Object>(1);
props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "example/bindings.xml");
jc = JAXBContext.newInstance(new Class[] {Department.class} , props);
} catch(JAXBException e) {
throw new RuntimeException(e);
}
}
public JAXBContext getContext(Class<?> clazz) {
if(Department.class == clazz) {
return jc;
}
return null;
}
}
For More Information
- http://blog.bdoughan.com/2011/04/moxys-xml-metadata-in-jax-rs-service.html
- http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-35.html
External Binding Document
By default MOXy's external binding document is used to augment the annotated model, but if you set the xml-mapping-metadata-complete
flag it will completely override the annotations allowing you to apply a completely different mapping:
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="example"
xml-mapping-metadata-complete="true">
...
</xml-bindings>
For More Information
- http://blog.bdoughan.com/2011/09/mapping-objects-to-multiple-xml-schemas.html
- http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html
UPDATE
This update is to address a number of questions you asked in one of your comments:
Yes each ContextResolver
should have its own binding file. The main reason for introducing a new ContextResolver
is to represent a secondary mapping.
For a single ContextResolver
you can express the metadata across multiple binding files, but they will be combined into a single set of mappings. This means that a single ContentResolver
cannot have multiple views of a single class. A separate ContextResolver
is used to represent a secondary mapping.
I recommend loading the metadata file from the class path.
Your JAX-RS implementation should pick up your ContextResolver
because it is annotated with @Provider
. The ContextResolver
used for a class will depend on how you implement the getContext
method:
public JAXBContext getContext(Class<?> clazz) {
if(Customer.class == clazz) {
return jc;
}
return null;
}
这篇关于使用JAXB灵活编组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!