Http 204 error in REST web service (Jersey)

2019-08-29 10:34发布

问题:

I am using Jersey/Java to develop my REST services. I need to return an XML representation for my CarStore :

 @XmlRootElement
public class CarStore {
 private List<Car> cars;

 public List<Car> getCars() {
  return cars;
 }
 public void setCars(List<Car> cars) {
  this.cars = cars;
 }

Here is my Car object :

@XmlRootElement
> public class Car {
 private String carName;
 private Specs carSpecs;
 private Category carCategory;
 public String getCarName() {
  return carName;
 }
 public void setCarName(String carName) {
  this.carName = carName;
 }
 public Specs getCarSpecs() {
  return carSpecs;
 }
 public void setCarSpecs(Specs carSpecs) {
  this.carSpecs = carSpecs;
 }
 public Category getCarCategory() {
  return carCategory;
 }
 public void setCarCategory(Category carCategory) {
  this.carCategory = carCategory;
 }

}

Specs and Category are enums like this :

    @XmlRootElement
> public enum Category {

 SEDANS, COMPACTS, WAGONS, HATCH_HYBRIDS, SUVS, CONVERTIBLES, COMPARABLE;
}

My resource class is :

    @GET
 @Produces({MediaType.APPLICATION_XML})
 public CarStore getCars()
 {
    return CarStoreModel.instance.getAllCars();
 }

My jersey client is :

WebResource service = client.resource(getBaseURI());
System.out.println(service.path("rest").path("cars").accept(
MediaType.APPLICATION_XML).get(String.class));

I am getting Http 204 error on access alongwith client exception :

com.sun.jersey.api.client.UniformInterfaceException

Any ideas ? Thanks !

EDIT : I have yet not developed the model class...I just initialized some car objects as dummy data and put them in carstore. Showing all the classes here would be very clumsy. BTW, sorry for writing 204 Error..it is just that I am getting an Exception that led me think so.

回答1:

I believe you are getting a UniformInterfaceException because your getCars() function is not returning an HTTP response body. The root problem is that your Car List isn't being converted into XML by JAXB because it is missing the @XmlElement annotation.

Your getCars() function should be:

@GET
@Produces(MediaType.APPLICATION_XML)
public CarStore getCars() {
    // myCarStore is an instance of CarStore        
    return myCarStore.getCars();
}

and your Car List in CarStore should be defined:

@XmlElement(name="car")
private List<Car> cars;


回答2:

I'm guessing the exception is not related to the response code (204) because 204 is a success condition that indicates "No Content."



回答3:

Is what you're returning in xml format? I'm not sure what getAllCars does but you can use something like Fiddler to help you view the traffic and see what is being returned to the client and whether its in proper format etc



回答4:

In your client code, is the resource path correct? Make sure getBaseURI is returning a value.

Perhaps try:

Client client = new Client();
WebResource resource = client.resource(getBaseURI());
CarStore carStore = resource.path("/rest/cars").accept(MediaType.APPLICATION_XML).get(CarStore.class);


回答5:

Aren't you missing a @Path annotation on your resource class?

@GET
@Path("cars")
@Produces({ MediaType.APPLICATION_XML })
public CarStore getCars() {
   return CarStoreModel.instance.getAllCars();
}

Check if the URL at which your REST WS is mounted the one you expect by putting a breakpoint in your getCars() method (or putting a System.out.println) to make sure it actually gets called.



回答6:

It seems there is a hard coded check in Jersey to throw a UniformInterfaceException when a HTTP 204 is returned.

The best solution will be to 'fix' the rest server so it never returns a null. e.g. return an Empty list or a Class with not values set.

Else you will need to catch UniformInterfaceException which is really ugly

    if (getStatus() == 204) {
        throw new UniformInterfaceException(this);
    }

More info here : http://grepcode.com/file/repo1.maven.org/maven2/com.sun.jersey/jersey-client/1.17.1/com/sun/jersey/api/client/ClientResponse.java#ClientResponse.getEntity%28java.lang.Class%2Cjava.lang.reflect.Type%29