如何使用 jersey 编写 XML MessageBodyWriter 提供程序
我不是特别想解决任何问题,而是我正在学习球衣.
I am not trying to solve any problem in particular, but rather I am on a learning path to jersey.
我有一个这样标记的实体类:
I have an entity class marked like this:
@Entity
@Table(name = "myentity")
@XmlRootElement
public class MyEntity implements serializable {
// lots of methods...
}
以及相应的球衣服
@Stateless
@Path("entity")
public class EntityFacade {
@GET
@Path("{param}")
@Produces({"application/xml;charset=UTF-8"})
public List<MyEntity> find(@PathParam("param") String param) {
List entities = entityManager.getResultList(); // retrieve list from db
return entities;
}
}
提供正确的 XML 响应.假设我想编写一个 MessageBodyWriter 来复制相同的行为,这会产生 XML 响应,我该怎么做?
Which give a correct XML response. Supposing I want to write a MessageBodyWriter which replicate same behavior, which is producing an XML response, how could I do that ?
@Provider
public class TrasformerMessageBodyWriter implements MessageBodyWriter<Object> {
@Override
public long getSize(Object o, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
return 0;
}
@Override
public boolean isWriteable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
// return true or false depending if I want to rewrite the response
}
@Override
public void writeTo(Object o, Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException,
WebApplicationException {
// what do I need to write here...
}
}
通过使用@Provider 注释进行标记,我可以看到消息正文编写器被正确调用.
by marking with @Provider annotation I can see the message body writer is correctly invoked.
当调用 writeTo 时,Object o 是 Vector,Type genericType 是 List,但此时我完全不知道如何在 XML 中转换对象.
When writeTo is invoked, Object o is a Vector and Type genericType is a List but at this point I am completely lost on how I could transform the object in XML.
最后,如果 jersey 及其注解已经提供了一切,那么 MessageBodyWriter 有什么用处?
Last, if everything is already provided by jersey and its annotations, how can a MessageBodyWriter be useful ?
我再次重申,这只是一个学术练习.
Again, I am repeating that this is just an academic exercise.
推荐答案
通常人们会使用 MessageBodyWriter
将对象转换为 Jersey 一无所知的数据格式.下面是一个将 TableData
域对象转换为 CSV 的示例:
Typically one would use a MessageBodyWriter
to convert objects to data formats that Jersey knows nothing about. Here's an example of translating a TableData
domain object to CSV:
@Singleton
@Produces("text/csv")
@Provider
public class FederationCsvWriter implements MessageBodyWriter<TableData> {
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return TableData.class.isAssignableFrom(type);
}
@Override
public long getSize(TableData data, Class<?> type, Type genericType, Annotation annotations[], MediaType mediaType) {
return -1;
}
@Override
public void writeTo(TableData data, Class<?> type, Type genericType, Annotation[] annotations,
MediaType mediaType, MultivaluedMap<String, Object> headers, OutputStream out) throws IOException {
Writer osWriter = new OutputStreamWriter(out);
CSVWriter writer = new CSVWriter(osWriter, ',', '"', "
");
if (data.getResultCount() > 0) {
//Write the header
writer.writeNext(data.getResult().get(0).keySet().toArray(new String[data.getResult().get(0).keySet().size()]));
//Write the data
for (ModelData row: data.getResult()) {
writer.writeNext(row.values().toArray(new String[row.values().size()]));
}
}
writer.flush();
}
}
在您的示例中,您可以通过自己检查对象并将结果提供给 OutputStream
来创建 XML,或者您可以使用 JAXB(Jersey 在内部使用)将对象直接编组到 输出流
.就您的练习而言,JAXB 可能更有趣.
In your example you could either create XML by inspecting the object yourself and feeding the result to the OutputStream
or your could use JAXB (which Jersey uses internally) to marshall the objects directly to the OutputStream
. For the purposes of your exercise JAXB is probably more interesting.
相关文章