我想使用动态生成的bean作为Jersey REST WS的输出。我不知道在编译时会要求哪些属性。我可以返回一个包含字段列表的bean,但我想尝试返回一个动态创建属性的bean,因为输出会更好一些。
我试图使用cglib构建一个bean实例并将其返回到Jersey框架以编组为JSON / XML。我遇到了下面的问题,如果有人可以提出建议我会很感激。我不知道我是否可以使用泛型魔法或创建自定义处理程序来解决。
使用的库:Tomcat 6.0.18,Java 1.6.0_17,Jersey v1.8,cglib v2.2
SearchWS
@Path("/search")
public class SearchWS
{
private static final Logger log = Logger.getLogger(SearchWS.class.getName());
@POST
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public GenericObject getXML(@Context final HttpServletRequest request, @FormParam("query") final String query)
throws Exception
{
log.debug("Entering");
final IDAO dao = new DAOImpl();
return dao.search(query).getResults().get(0);
}
}
GenericObject bean类
@XmlRootElement(name = "object")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class GenericObject
{
}
DAO从查询中创建键/值对的映射并构建GenericObject子类实例
public GenericObject buildGenericBean(final Map<String, String> propertyValues) throws Exception
{
log.debug("Entering");
BeanGenerator bg = new BeanGenerator();
bg.setSuperclass(GenericObject.class);
bg.setNamingPolicy(new net.sf.cglib.core.NamingPolicy()
{
@Override
public String getClassName(final String prefix, final String source, final Object key, final Predicate names)
{
return prefix + "Impl";
}
});
Set<String> keys = propertyValues.keySet();
for (String nextKey : keys)
{
bg.addProperty(nextKey, String.class);
}
GenericObject bean = (GenericObject) bg.create();
for (String nextKey : keys)
{
setProperty(bean, nextKey, propertyValues.get(nextKey));
}
log.debug("Leaving");
return bean;
}
当客户端请求JSON内容(&#34; application / json&#34;)时,它会根据作为表单参数提交的SQL查询按预期生成一些不错的输出:
{
"country": "DZ",
"title": "foo",
"theme": "foo",
"subject": "foo",
"owner_name": "foo",
"creation_date": "16/05/2013 06:20:10 PM",
"publication_needed": "1",
"language_code": "en",
"modify_date": "21/05/2013 05:08:15 PM",
"classification": "0"
}
将请求的内容类型设置为XML(&#34; application / xml&#34;)会导致以下错误。我曾希望泽西岛能确保产量相等,例如以文本内容作为属性值的属性命名的元素。我不是XML编组专家,所以可能会遗漏一些东西。如何在XML中获得等效输出?
Caused by: com.sun.jersey.api.MessageException: A message body writer for Java class xxx.model.GenericObjectImpl, and Java type class xxx.model.GenericObjectImpl, and MIME media type application/xml was not found
答案 0 :(得分:0)
cglib创建一个子类以创建代理。这意味着Jersey将接收GenericObject
的子类而不是直接实例。但注释XMLRootElement
未声明为@Inherited
,因此即使是GenericObject
,此注释也不会出现在此代理子类中。
由于Jersey没有在实际类型上找到这个注释,它告诉你它不知道如何处理它。遗憾的是,使用cglib解决这个问题并不容易。您可能希望直接尝试其他检测库,例如javassist或ASM。
如果你想直接解决泽西岛的问题。但是,您可以创建自己的编组程序,以检查该类是否为GenericObject
的子类,以便创建默认的XML输出。 (看看泽西岛MessageBodyWriter
寻求帮助。)