Я делаю веб-сервис, используя JavaEE8 (Jax-RS 2.1, Джерси, JsonB).Я создал конечную точку (ресурс в словах Jax-RS), которая возвращает оболочку моей модели + некоторые ссылки, как указано в HATEOAS.Я хочу, чтобы мой Json выглядел следующим образом:
{
"user":{
"id":"2",
"username":"jorg",
"currency":200
},
"links":[
{
"self":"http://localhost:8080/user/2"
},
{
"contest-winned":"http://localhost:8080/contest/winned/23"
}
]
}
Поэтому я сделал мой ресурс похожим на:
@Path("/user")
public class UserEndpoint
{
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getUser()
{
User user = initTestInfo();
UserResourceAssembler userResourceAssembler = new UserResourceAssembler();
UserResource resource = userResourceAssembler.toResource(user);
URI uri = URI.create("http://localhost:8080/user/2");
Link self = Link.fromUri(uri).rel("self").build();
URI uri2 = URI.create("http://localhost:8080/contest/winned/23");
Link contestWinned = Link.fromUri(uri).rel("contest-winned").build();
resource.addLink(self);
resource.addLink(contestWinned );
return Response.ok(resource).build();
}
private User initTestInfo()
{
User user = new User();
user.setCurrency(200);
user.setUsername("jorg");
return user;
}
}
Я использую UserResource в качестве оболочки для хранения ссылок и объекта пользователя.,Я пытаюсь отделить мою модель от моего REST, поэтому я делаю эту обертку.
public class UserResource
{
@JsonbProperty
private List<Link> links = new ArrayList<>();
@JsonbProperty
private User user;
public UserResource(User user)
{
this.user = user;
}
public void addLink(Link link)
{
links.add(link);
}
public List<Link> getLinks()
{
return links;
}
public void setLinks(List<Link> links)
{
this.links = links;
}
public User getUser() {
return this.user;
}
}
Мой класс пользователя следующий.примечание: я пометил как @JsonbTransient два списка в User, потому что я не хочу показывать в моем json.
public class User
{
private long id;
private String username;
private long currency;
@JsonbTransient
private List<ContestReward> contestRewards;
@JsonbTransient
private List<Contest> contests;
public User()
{
contestRewards = new ArrayList<>();
}
public void bid(Auction auction, Payment payment) throws BadPaymentException
{
auction.receiveBid(payment);
}
public void participate(Contest contest, Payment payment) throws AlreadyWonContestException, BadPaymentException
{
contest.addPayment(payment);
}
public void give(int money)
{
this.currency += money;
}
public void deduct(int money)
{
this.currency -= money;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public List<Contest> getContests()
{
return contests;
}
public List<ContestReward> getContestRewards()
{
return contestRewards;
}
public long getCurrency()
{
return currency;
}
public void setCurrency(long currency)
{
this.currency = currency;
}
public boolean isWinner(ContestReward contestReward)
{
if ( ! contestRewards.contains(contestReward))
return false;
return contestRewards.get(contestRewards.indexOf(contestReward)).hasWinner(this);
}
public boolean isCreator(ContestReward contestReward)
{
return contestReward.getCreator().equals(this);
}
}
Если я добавлю @JsonBTransient, я получу только ссылку в моем json, но если я удалю это, я получу следующую ошибку стека:
javax.servlet.ServletException: java.lang.IllegalArgumentException: wrong number of arguments
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:432)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
java.lang.IllegalArgumentException: wrong number of arguments
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.eclipse.yasson.internal.model.GetFromGetter.internalGetValue(GetFromGetter.java:28)
org.eclipse.yasson.internal.model.GetValueCommand.getValue(GetValueCommand.java:34)
org.eclipse.yasson.internal.model.ReflectionPropagation.getValue(ReflectionPropagation.java:72)
org.eclipse.yasson.internal.model.PropertyModel.getValue(PropertyModel.java:257)
org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:76)
org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:59)
org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:92)
org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:59)
org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
org.eclipse.yasson.internal.Marshaller.serializeRoot(Marshaller.java:118)
org.eclipse.yasson.internal.Marshaller.marshall(Marshaller.java:76)
org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:98)
org.glassfish.jersey.jsonb.internal.JsonBindingProvider.writeTo(JsonBindingProvider.java:118)
org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266)
org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251)
org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109)
org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85)
org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1135)
org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662)
org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:395)
org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:385)
org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:280)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
org.glassfish.jersey.internal.Errors.process(Errors.java:316)
org.glassfish.jersey.internal.Errors.process(Errors.java:298)
org.glassfish.jersey.internal.Errors.process(Errors.java:268)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Чего мне не хватает?Если вам нужна дополнительная информация, которую я могу предоставить.
Заранее спасибо, извините за мой английский.Ура!