# Content Type: text/html



## Acasta89 (28. Feb 2011)

Hallo zusammen,

beschäftige mich momentan mit REST + Java + NetBeans. Für den Anfang habe ich die Wizards benutzt um den RESTful Webservice und den Java Client zu erstellen. Ich bin da nicht der Oberprofi und möchte eigentlich nur ein GET abschicken, dass mir eine Ressource als text/html zurückgibt. Aber ich bekomme daraufhin immer die Meldung "406 - Not Acceptable". XML und JSON funktioniert problemlos, da es anscheinend der Standard ist.

Habt ihr eine Idee was ich als nächstes machen kann?


----------



## tagedieb (28. Feb 2011)

Sieh hier im J2EE Tutorial



> *The @Produces Annotation*The @Produces annotation is used to specify the MIME media types or representations a resource can produce and send back to the client. If @Produces is applied at the class level, all the methods in a resource can produce the specified MIME types by default. If applied at the method level, the annotation overrides any @Produces annotations applied at the class level.
> 
> If no methods in a resource are able to produce the MIME type in a client request, the JAX-RS runtime sends back an HTTP “406 Not Acceptable” error.


----------



## Acasta89 (10. Mrz 2011)

Sorry für die verspätete Antwort. Muss nebenbei eine Arbeit über REST schreiben und habe mich vorerst nicht mehr mit diesem Problem beschäftigt. 

Ich habe nun die @Produces nicht über die Methode gemacht, sondern über die gesamte Klasse. Nun bekomme ich aber folgende Meldung:


```
SCHWERWIEGEND: A message body writer for Java type, class converter.CustomersConverter, and MIME media type, text/plain, was not found
SCHWERWIEGEND: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException
        at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:268)
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1029)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:941)
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:932)
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:384)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:451)
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:632)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:619)
```

Es gibt ja auch diese MessageBodyReader und Writer, die mit Sicherheit der Schlüssel sind. Aber das Tutorial verstehe ich an der Stelle nicht. Hat jemand von euch schonmal eine Resource als html Ansicht über JAX-RS hinbekommen?


----------



## tagedieb (10. Mrz 2011)

Am besten du postest mal deinen Code


----------



## Acasta89 (10. Mrz 2011)

Der Code ist von den NetBeans Wizards erstellt:

Das ist der Code für die Customers Ressource:


```
@Path("/customers/")
@Stateless
@Produces({"application/xml", "application/json", "text/html"})
public class CustomersResource {
    @javax.ejb.EJB
    private CustomerResource customerResource;
    @Context
    protected UriInfo uriInfo;
    @PersistenceContext(unitName = "HelloRestPU")
    protected EntityManager em;
  
    /** Creates a new instance of CustomersResource */
    public CustomersResource() {
    }

    /**
     * Get method for retrieving a collection of Customer instance in XML format.
     *
     * @return an instance of CustomersConverter
     */
    @GET
    
    public CustomersConverter get(@QueryParam("start")
                                  @DefaultValue("0")
    int start, @QueryParam("max")
               @DefaultValue("10")
    int max, @QueryParam("expandLevel")
             @DefaultValue("1")
    int expandLevel, @QueryParam("query")
                     @DefaultValue("SELECT e FROM Customer e")
    String query) {
        return new CustomersConverter(getEntities(start, max, query), uriInfo.getAbsolutePath(), expandLevel);
    }

    /**
     * Post method for creating an instance of Customer using XML as the input format.
     *
     * @param data an CustomerConverter entity that is deserialized from an XML stream
     * @return an instance of CustomerConverter
     */
    @POST
    @Consumes({"application/xml", "application/json"})
    public Response post(CustomerConverter data) {
        Customer entity = data.resolveEntity(em);
        createEntity(data.resolveEntity(em));
        return Response.created(uriInfo.getAbsolutePath().resolve(entity.getIdcustomer() + "/")).build();
    }

    /**
     * Returns a dynamic instance of CustomerResource used for entity navigation.
     *
     * @return an instance of CustomerResource
     */
    @Path("{idcustomer}/")
    public CustomerResource getCustomerResource(@PathParam("idcustomer")
    Integer id) {
        customerResource.setId(id);
        customerResource.setEm(em);
        return customerResource;
    }

    /**
     * Returns all the entities associated with this resource.
     *
     * @return a collection of Customer instances
     */
    protected Collection<Customer> getEntities(int start, int max, String query) {
        return em.createQuery(query).setFirstResult(start).setMaxResults(max).getResultList();
    }

    /**
     * Persist the given entity.
     *
     * @param entity the entity to persist
     */
    protected void createEntity(Customer entity) {
        em.persist(entity);
    }
}
```

Und das der Converter zu der Ressource:


```
@XmlRootElement(name = "customers")
public class CustomersConverter {
    private Collection<Customer> entities;
    private Collection<CustomerConverter> items;
    private URI uri;
    private int expandLevel;
  
    /** Creates a new instance of CustomersConverter */
    public CustomersConverter() {
    }

    /**
     * Creates a new instance of CustomersConverter.
     *
     * @param entities associated entities
     * @param uri associated uri
     * @param expandLevel indicates the number of levels the entity graph should be expanded
     */
    public CustomersConverter(Collection<Customer> entities, URI uri, int expandLevel) {
        this.entities = entities;
        this.uri = uri;
        this.expandLevel = expandLevel;
        getCustomer();
    }

    /**
     * Returns a collection of CustomerConverter.
     *
     * @return a collection of CustomerConverter
     */
    @XmlElement
    public Collection<CustomerConverter> getCustomer() {
        if (items == null) {
            items = new ArrayList<CustomerConverter>();
        }
        if (entities != null) {
            items.clear();
            for (Customer entity : entities) {
                items.add(new CustomerConverter(entity, uri, expandLevel, true));
            }
        }
        return items;
    }

    /**
     * Sets a collection of CustomerConverter.
     *
     * @param a collection of CustomerConverter to set
     */
    public void setCustomer(Collection<CustomerConverter> items) {
        this.items = items;
    }

    /**
     * Returns the URI associated with this converter.
     *
     * @return the uri
     */
    @XmlAttribute
    public URI getUri() {
        return uri;
    }

    /**
     * Returns a collection Customer entities.
     *
     * @return a collection of Customer entities
     */
    @XmlTransient
    public Collection<Customer> getEntities() {
        entities = new ArrayList<Customer>();
        if (items != null) {
            for (CustomerConverter item : items) {
                entities.add(item.getEntity());
            }
        }
        return entities;
    }
}
```

Dann gibt es nochmal für eine einzige Ressource also nur Customer:


```
@Stateless
public class CustomerResource {
    @Context
    protected UriInfo uriInfo;
    protected EntityManager em;
    protected Integer id;
  
    /** Creates a new instance of CustomerResource */
    public CustomerResource() {
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    /**
     * Get method for retrieving an instance of Customer identified by id in XML format.
     *
     * @param id identifier for the entity
     * @return an instance of CustomerConverter
     */
    @GET
    @Produces({"application/xml", "application/json"})
    public CustomerConverter get(@QueryParam("expandLevel")
                                 @DefaultValue("1")
    int expandLevel) {
        return new CustomerConverter(getEntity(), uriInfo.getAbsolutePath(), expandLevel);
    }

    /**
     * Put method for updating an instance of Customer identified by id using XML as the input format.
     *
     * @param id identifier for the entity
     * @param data an CustomerConverter entity that is deserialized from a XML stream
     */
    @PUT
    @Consumes({"application/xml", "application/json"})
    public void put(CustomerConverter data) {
        updateEntity(getEntity(), data.resolveEntity(em));
    }

    /**
     * Delete method for deleting an instance of Customer identified by id.
     *
     * @param id identifier for the entity
     */
    @DELETE
    public void delete() {
        deleteEntity(getEntity());
    }

    /**
     * Returns an instance of Customer identified by id.
     *
     * @param id identifier for the entity
     * @return an instance of Customer
     */
    protected Customer getEntity() {
        try {
            return (Customer) em.createQuery("SELECT e FROM Customer e where e.idcustomer = :idcustomer").setParameter("idcustomer", id).getSingleResult();
        } catch (NoResultException ex) {
            throw new WebApplicationException(new Throwable("Resource for " + uriInfo.getAbsolutePath() + " does not exist."), 404);
        }
    }

    /**
     * Updates entity using data from newEntity.
     *
     * @param entity the entity to update
     * @param newEntity the entity containing the new data
     * @return the updated entity
     */
    private Customer updateEntity(Customer entity, Customer newEntity) {
        entity = em.merge(newEntity);
        return entity;
    }

    /**
     * Deletes the entity.
     *
     * @param entity the entity to deletle
     */
    private void deleteEntity(Customer entity) {
        em.remove(entity);
    }
}
```

Und wieder der dazugehörige Konverter:


```
@XmlRootElement(name = "customer")
public class CustomerConverter {
    private Customer entity;
    private URI uri;
    private int expandLevel;
  
    /** Creates a new instance of CustomerConverter */
    public CustomerConverter() {
        entity = new Customer();
    }

    /**
     * Creates a new instance of CustomerConverter.
     *
     * @param entity associated entity
     * @param uri associated uri
     * @param expandLevel indicates the number of levels the entity graph should be expanded@param isUriExtendable indicates whether the uri can be extended
     */
    public CustomerConverter(Customer entity, URI uri, int expandLevel, boolean isUriExtendable) {
        this.entity = entity;
        this.uri = (isUriExtendable) ? UriBuilder.fromUri(uri).path(entity.getIdcustomer() + "/").build() : uri;
        this.expandLevel = expandLevel;
    }

    /**
     * Creates a new instance of CustomerConverter.
     *
     * @param entity associated entity
     * @param uri associated uri
     * @param expandLevel indicates the number of levels the entity graph should be expanded
     */
    public CustomerConverter(Customer entity, URI uri, int expandLevel) {
        this(entity, uri, expandLevel, false);
    }

    /**
     * Getter for idcustomer.
     *
     * @return value for idcustomer
     */
    @XmlElement
    public Integer getIdcustomer() {
        return (expandLevel > 0) ? entity.getIdcustomer() : null;
    }

    /**
     * Setter for idcustomer.
     *
     * @param value the value to set
     */
    public void setIdcustomer(Integer value) {
        entity.setIdcustomer(value);
    }

    /**
     * Getter for name.
     *
     * @return value for name
     */
    @XmlElement
    public String getName() {
        return (expandLevel > 0) ? entity.getName() : null;
    }

    /**
     * Setter for name.
     *
     * @param value the value to set
     */
    public void setName(String value) {
        entity.setName(value);
    }

    /**
     * Getter for adress.
     *
     * @return value for adress
     */
    @XmlElement
    public String getAdress() {
        return (expandLevel > 0) ? entity.getAdress() : null;
    }

    /**
     * Setter for adress.
     *
     * @param value the value to set
     */
    public void setAdress(String value) {
        entity.setAdress(value);
    }

    /**
     * Getter for phone.
     *
     * @return value for phone
     */
    @XmlElement
    public BigInteger getPhone() {
        return (expandLevel > 0) ? entity.getPhone() : null;
    }

    /**
     * Setter for phone.
     *
     * @param value the value to set
     */
    public void setPhone(BigInteger value) {
        entity.setPhone(value);
    }

    /**
     * Returns the URI associated with this converter.
     *
     * @return the uri
     */
    @XmlAttribute
    public URI getUri() {
        return uri;
    }

    /**
     * Sets the URI for this reference converter.
     *
     */
    public void setUri(URI uri) {
        this.uri = uri;
    }

    /**
     * Returns the Customer entity.
     *
     * @return an entity
     */
    @XmlTransient
    public Customer getEntity() {
        if (entity.getIdcustomer() == null) {
            CustomerConverter converter = UriResolver.getInstance().resolve(CustomerConverter.class, uri);
            if (converter != null) {
                entity = converter.getEntity();
            }
        }
        return entity;
    }

    /**
     * Returns the resolved Customer entity.
     *
     * @return an resolved entity
     */
    public Customer resolveEntity(EntityManager em) {
        return entity;
    }
}
```

Meine Testversuche mache ich momentan mit der Klasse CustomersResource (also erwarte ich eine Liste von Customern)


----------

