0

I have a simple Java RESTful API endpoint which lets Jersey handle the marshalling.

When accept=application/json it works fine and returns expected.

When accept=application/xml it returns 500 server error

In what cases would marshalling work for json but not xml, am I missing something ?

Here's my code:

Resource method:

@GET
@Path("/client/{clientId}/technicalrep")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@WebinarSecurityFilter
@WebinarClientValidationFilter
public Response getTechnicalRepContacts(@PathParam("clientId") Long clientId, @HeaderParam("accept") String accept){

    if (isAcceptInvalid(accept)) {
        return Response.status(Response.Status.PRECONDITION_FAILED).entity(new PlatformApiMessage().withMessage("The header parameter Accept is mandatory")).build();
    }

    List<ClientTechnicalContact> technicalContacs = wccClientService.findClientTechnicalContactsByClientId(clientId);

    if (technicalContacs == null || technicalContacs.size() == 0) {
        return Response.ok(new PlatformApiMessage().withMessage("No Technical Rep Contacts found.")).build();
    } else {
        ClientLevelTechnicalContacts clientLevelTechnicalContacts = new ClientLevelTechnicalContacts(clientId,technicalContacs);
        return Response.ok(clientLevelTechnicalContacts).build();
    }
}

DTO:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ClientLevelTechnicalContacts { 

    private long clientid;

    @XmlElement(name = "technicalcontact")
    private List<ClientTechnicalContact> technicalcontacts;

    public ClientLevelTechnicalContacts(long clientid,List<ClientTechnicalContact> technicalcontacts) {
        this.clientid = clientid;
        this.technicalcontacts = technicalcontacts;
    }

    public long getClientid() {
        return clientid;
    }

    public void setClientid(long clientid) {
        this.clientid = clientid;
    }

    public List<ClientTechnicalContact> getTechnicalcontacts() {
        return technicalcontacts;
    }

    public void setTechnicalcontacts(List<ClientTechnicalContact> technicalcontacts) {
        this.technicalcontacts = technicalcontacts;
    }   
}


@XmlRootElement(name="technicalcontacts")
@XmlAccessorType(XmlAccessType.FIELD)
public class ClientTechnicalContact {

    private long contactid;
    private String contactname;

    public ClientTechnicalContact(){}

    public ClientTechnicalContact(long contactid, String contactname) {
        super();
        this.contactid = contactid;
        this.contactname = contactname;
    }

    public long getContactid() {
        return contactid;
    }
    public void setContactid(long contactid) {
        this.contactid = contactid;
    }
    public String getContactname() {
        return contactname;
    }
    public void setContactname(String contactname) {
        this.contactname = contactname;
    }

}
Esteban Rincon
  • 2,040
  • 3
  • 27
  • 44
  • *"When would JAXB work for Json but not XML?"* Never, since JAXB only does XML. JAXB = Java Architecture for **XML** Binding. Sure, there are JSON processors that can use JAXB *annotations*, as an ease-of-use feature, but JAXB itself can only do XML. – Andreas May 23 '17 at 20:45
  • Since you seem to have a case where that occurs, why not just look at the real error message in the server log file, to find out your example of a case where JSON works and JAXB doesn't, rather than asking an *open-ended question* like this? – Andreas May 23 '17 at 20:48
  • Server is set to development mode, no stacktrace there... Server log files don't show any signs of error to my knowledge. Maybe instead of criticism you could point in the right direction, if I'm asking the question is because I don't know how to solve it, thank you. – Esteban Rincon May 23 '17 at 22:04
  • I was trying to point you in the right direction, which *starts with* getting the *real* error message. Whether your setup was already logging it or not, would be impossible for me to know, since you didn't say anything about it. Don't know what your criticism comment was about, but let me be clear/explicit: Find the real error that has been masked by a generic 500 error code. Since you don't know how, see here: [Why does jersey have no error log when the status is 500?](https://stackoverflow.com/q/27854367/5221149) – Andreas May 23 '17 at 22:25

1 Answers1

0

Dumb mistake, but indeed is necessary for marshalling/unmarshalling to take place.

Every DTO must have a default/empty constructor, or else it won't be able to work, and ClientLevelTechnicalContacts lacks an empty constructor.

I don't understand why there wan't a better stacktrace. Anyways the solution was to place an empty constructor in ClientLevelTechnicalContacts.

Esteban Rincon
  • 2,040
  • 3
  • 27
  • 44