HATEOAS REST JsonB сериализует проблемы - PullRequest
0 голосов
/ 13 сентября 2018

Я делаю веб-сервис, используя 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)

Чего мне не хватает?Если вам нужна дополнительная информация, которую я могу предоставить.

Заранее спасибо, извините за мой английский.Ура!

...