Java 如何马歇尔仿制药?
我有一个使用Java、MOXy和Jersey的服务器应用程序。将单个对象编组为JSON非常有效,当我的函数返回包含一些对象的列表(Java 如何马歇尔仿制药?,java,json,generics,jersey,moxy,Java,Json,Generics,Jersey,Moxy,我有一个使用Java、MOXy和Jersey的服务器应用程序。将单个对象编组为JSON非常有效,当我的函数返回包含一些对象的列表(list)时,编组也很有效 但是现在我添加了一个名为Response的类,它包含一些关于函数调用的附加信息,以及一个通用列表,如上图所示。如果我为我拥有的每一个实体创建一个特殊的响应类,封送就可以了,但它并不是很优雅。因此,我将响应类修改为泛型(响应包含一个列表) 但现在编组停止了工作。我在stackoverflow上尝试了一些解决方案,但都不起作用。所以,请帮帮我!
list
)时,编组也很有效
但是现在我添加了一个名为Response的类,它包含一些关于函数调用的附加信息,以及一个通用列表,如上图所示。如果我为我拥有的每一个实体创建一个特殊的响应类,封送就可以了,但它并不是很优雅。因此,我将响应类修改为泛型(响应
包含一个列表
)
但现在编组停止了工作。我在stackoverflow上尝试了一些解决方案,但都不起作用。所以,请帮帮我!谢谢
更新:添加了最小工作样本以指出我的问题
格雷德尔先生
apply plugin: 'java'
apply plugin: 'war'
version = '1.0'
repositories {
mavenCentral()
}
dependencies {
def jerseyVersion = '2.4.1'
compile group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: jerseyVersion
compile group: 'org.glassfish.jersey.media', name: 'jersey-media-moxy', version: jerseyVersion
}
Server.java
package org.minimal.demo.server;
import org.glassfish.jersey.server.ResourceConfig;
import javax.ws.rs.ApplicationPath;
@ApplicationPath("api")
public class Server extends ResourceConfig {
public Server() {
packages("org.minimal.demo.server.api");
register(JsonMoxyConfigurationContextResolver.class);
}
}
JsonMoxyConfigurationContextResolver.java
package org.minimal.demo.server;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import java.util.HashMap;
import java.util.Map;
@Provider
public class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> {
private final MoxyJsonConfig config;
public JsonMoxyConfigurationContextResolver() {
config = new MoxyJsonConfig()
.setIncludeRoot(false)
.setValueWrapper("$")
.setFormattedOutput(true)
.setNamespaceSeparator(':');
}
@Override
public MoxyJsonConfig getContext(Class<?> type) {
return config;
}
}
GenericResponse.java
package org.minimal.demo.server.response;
import java.util.ArrayList;
import java.util.List;
public class GenericResponse<T> {
public List<T> items = new ArrayList<T>();
public String msg;
public GenericResponse() {
}
public GenericResponse(String msg) {
this.msg = msg;
}
public void addItem(T item) {
items.add(item);
}
public List<T> getItems() {
return items;
}
public String getMsg() {
return msg;
}
}
可以通过将具体类指定为JAXB封送器的第二个参数来封送泛型对象。请参阅:在我的上下文中,封送拆收器不是由我实现的,因此我无法指定任何其他类。很抱歉我之前的评论。这是你想要的:谢谢你的帮助,但即使我应用了博客上建议的注释,我还是得到了和以前一样的例外。我遇到了完全相同的问题,你解决过吗?
package org.minimal.demo.server.response;
import java.util.ArrayList;
import java.util.List;
public class GenericResponse<T> {
public List<T> items = new ArrayList<T>();
public String msg;
public GenericResponse() {
}
public GenericResponse(String msg) {
this.msg = msg;
}
public void addItem(T item) {
items.add(item);
}
public List<T> getItems() {
return items;
}
public String getMsg() {
return msg;
}
}
package org.minimal.demo.server.api;
import org.minimal.demo.server.entity.SomeEntity;
import org.minimal.demo.server.response.GenericResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.List;
@Path("/something")
public class SomeApi {
@GET
@Path("/a")
public String simpleString() {
return "SomeApi.simpleString";
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/b")
public SomeEntity getSomeEntity() {
return new SomeEntity(42);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/c")
public List<SomeEntity> getSomeEntityList() {
List<SomeEntity> ret = new ArrayList<SomeEntity>();
ret.add(new SomeEntity(42));
ret.add(new SomeEntity(1337));
return ret;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/d")
public GenericResponse<SomeEntity> getGenericResponse() {
GenericResponse<SomeEntity> ret = new GenericResponse<SomeEntity>("SomeApi.getGenericResponse");
ret.addItem(new SomeEntity(42));
ret.addItem(new SomeEntity(1337));
ret.addItem(new SomeEntity(23));
return ret;
}
}
Dez 12, 2013 9:21:46 PM org.glassfish.jersey.server.ServerRuntime$Responder mapException
WARNING: WebApplicationException cause:
javax.xml.bind.MarshalException
- with linked exception:
[Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred marshalling the object
Internal Exception: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class org.minimal.demo.server.response.GenericResponse was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.]
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:403)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:808)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:243)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:230)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1139)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:557)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:381)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:371)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:262)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:361)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Caused by: Exception [EclipseLink-25003] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: An error occurred marshalling the object
Internal Exception: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class org.minimal.demo.server.response.GenericResponse was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
at org.eclipse.persistence.exceptions.XMLMarshalException.marshalException(XMLMarshalException.java:97)
at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:911)
at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:848)
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:401)
... 41 more
Caused by: Exception [EclipseLink-25007] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor for class org.minimal.demo.server.response.GenericResponse was not found in the project. For JAXB, if the JAXBContext was bootstrapped using TypeMappingInfo[] you must call a marshal method that accepts TypeMappingInfo as an input parameter.
at org.eclipse.persistence.exceptions.XMLMarshalException.descriptorNotFoundInProject(XMLMarshalException.java:139)
at org.eclipse.persistence.internal.oxm.Context$ContextState.getSession(Context.java:143)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:787)
at org.eclipse.persistence.oxm.XMLContext$XMLContextState.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.Context.getSession(Context.java:451)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:356)
at org.eclipse.persistence.oxm.XMLContext.getSession(XMLContext.java:1)
at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:1119)
at org.eclipse.persistence.internal.oxm.XMLMarshaller.marshal(XMLMarshaller.java:869)
... 43 more