简体   繁体   English

向RESTful Web服务添加新方法(错误)

[英]Adding new methods to RESTful web service (error)

I have a MySQL database that has two tables content and message . 我有一个具有两个表contentmessage的MySQL数据库。 I have tried to expose these two tables as a Restful web service using netbeans. 我试图使用netbeans将这两个表公开为Restful Web服务。 I followed this tutorial. 我遵循了本教程。 https://netbeans.org/kb/docs/websvc/rest.html https://netbeans.org/kb/docs/websvc/rest.html

The application works well with the generated methods and classes, but I wanted to add an extra method to get a list of messages by two other parameters "senders" and "receivers". 该应用程序可以很好地与生成的方法和类一起使用,但是我想添加一个额外的方法来通过其他两个参数“发送者”和“接收者”来获取消息列表。 When I add it I get the following error in Glassfish and the server does not start. 当我添加它时,我在Glassfish中收到以下错误,并且服务器无法启动。

The method that I added is named findConversation . 我添加的方法名为findConversation

[#|2013-05-02T00:09:18.609+0300|SEVERE|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=133;_ThreadName=Thread-2;|WebModule[/backendCT]StandardWrapper.Throwable
com.sun.jersey.spi.inject.Errors$ErrorMessagesException     at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)
    at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136)    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:771)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:766)
    at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:488)
    at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:318)
    at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:609)
    at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)   at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1453)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:1093)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:189)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)     at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722) |#]

this is the message class (I have manually added findcoversation NamedQuery) 这是消息类(我已经手动添加了findcoversation NamedQuery)

 package myentities;

 import java.io.Serializable;
 import java.util.Date;
 import javax.persistence.Basic;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.NamedQueries;
 import javax.persistence.NamedQuery;
 import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
 import javax.xml.bind.annotation.XmlRootElement;

 @Entity
 @Table(name = "message")
 @XmlRootElement
 @NamedQueries({
     @NamedQuery(name = "Message.findAll", query = "SELECT m FROM Message m"),
     @NamedQuery(name = "Message.findById", query = "SELECT m FROM Message m WHERE m.id = :id"),
     @NamedQuery(name = "Message.findBySender", query = "SELECT m FROM Message m WHERE m.sender = :sender"),
     @NamedQuery(name = "Message.findByReceiver", query = "SELECT m FROM Message m WHERE m.receiver = :receiver"),
     @NamedQuery(name = "Message.findConversation", query = "SELECT m FROM Message m WHERE m.receiver = :receiver and m.sender = :sender"),
     @NamedQuery(name = "Message.findByMessageHTML", query = "SELECT m FROM Message m WHERE m.messageHTML = :messageHTML"),
     @NamedQuery(name = "Message.findByDate", query = "SELECT m FROM Message m WHERE m.date = :date")})
 public class Message implements Serializable {
     private static final long serialVersionUID = 1L;

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Basic(optional = false)
     @Column(name = "ID")
     private Integer id;

     @Basic(optional = false)
     @NotNull
     @Size(min = 1, max = 20)
     @Column(name = "Sender")
     private String sender;

     @Basic(optional = false)
     @NotNull
     @Size(min = 1, max = 20)
     @Column(name = "Receiver")
     private String receiver;

     @Basic(optional = false)
     @NotNull
     @Size(min = 1, max = 200)
     @Column(name = "MessageHTML")
     private String messageHTML;

     @Basic(optional = false)
     @NotNull
     @Column(name = "Date")
     @Temporal(TemporalType.TIMESTAMP)
     private Date date;

     public Message() {
     }

     public Message(Integer id) {
         this.id = id;
     }

     public Message(Integer id, String sender, String receiver, String messageHTML, Date date) {
         this.id = id;
         this.sender = sender;
         this.receiver = receiver;
         this.messageHTML = messageHTML;
         this.date = date;
     }

     public Integer getId() {
         return id;
     }

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

     public String getSender() {
         return sender;
     }

     public void setSender(String sender) {
         this.sender = sender;
     }

     public String getReceiver() {
         return receiver;
     }

     public void setReceiver(String receiver) {
         this.receiver = receiver;
     }

     public String getMessageHTML() {
         return messageHTML;
     }

     public void setMessageHTML(String messageHTML) {
         this.messageHTML = messageHTML;
     }

     public Date getDate() {
         return date;
     }

     public void setDate(Date date) {
         this.date = date;
     }

     @Override
     public int hashCode() {
         int hash = 0;
         hash += (id != null ? id.hashCode() : 0);
         return hash;
     }

     @Override
     public boolean equals(Object object) {
         // TODO: Warning - this method won't work in the case the id fields are not set
         if (!(object instanceof Message)) {
             return false;
         }
         Message other = (Message) object;
         if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
             return false;
         }
         return true;
     }

     @Override
     public String toString() {
         return "myentities.Message[ id=" + id + " ]";
     }

  }

This is the facade class, where I have put in the findConversation method: 这是Facade类,我在其中放置了findConversation方法:

 package service;

 import java.util.List;
 import javax.ejb.Stateless;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import myentities.Message;

  /**
    *
    * @author Arabic
    */
  @Stateless @Path("myentities.message")
  public class MessageFacadeREST extends AbstractFacade<Message {
     @PersistenceContext(unitName = "backendCTPU")
     private EntityManager em;

     public MessageFacadeREST() {
         super(Message.class);
     }

     @POST
     @Override
     @Consumes({"application/xml", "application/json"})
     public void create(Message entity) {
         super.create(entity);
     }

     @PUT
     @Override
     @Consumes({"application/xml", "application/json"})
     public void edit(Message entity) {
         super.edit(entity);
     }

     @DELETE
     @Path("{id}")
     public void remove(@PathParam("id") Integer id) {
         super.remove(super.find(id));
     }

     @GET
     @Path("{id}")
     @Produces({"application/xml", "application/json"})
     public Message find(@PathParam("id") Integer id) {
         return super.find(id);
     }

     @GET
     @Override
     @Produces({"application/xml", "application/json"})
     public List<Message findAll() {
         return super.findAll();
     }

     @GET
     @Path("{from}/{to}")
     @Produces({"application/xml", "application/json"})
     public List<Message findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
         return super.findRange(new int[]{from, to});
     }

     @GET
     @Path("count")
     @Produces("text/plain")
     public String countREST() {
         return String.valueOf(super.count());
     }

     @GET
     @Path("{Receiver}/{Sender}")
     @Produces({"application/xml", "application/json"})
     public Message findConversation(@PathParam("Receiver") String receiver,@PathParam("Sender") String sender ) {     
         //return new Message();
         return (Message) em.createNamedQuery("Message.findConversation").setParameter("Sender",sender).setParameter("Receiver", receiver);
     } 

     @Override
     protected EntityManager getEntityManager() {
         return em;
     }
  }

The path of findConversation isn't unique. findConversation的路径不是唯一的。

This is an overview over all services: 这是所有服务的概述:

  • base path: myentities.message/ 基本路径: myentities.message/
    • POST: void create(Message entity) 开机自检: void create(Message entity)
    • PUT: void edit(Message entity) PUT: void edit(Message entity)
    • GET: List<Message> findAll() GET: List<Message> findAll()
  • count: myentities.message/count 计数: myentities.message/count
    • GET: String countREST() GET: String countREST()
  • base path + id: myentities.message/{id} 基本路径+ ID: myentities.message/{id}
    • DELETE: void remove(@PathParam("id") Integer id) 删除: void remove(@PathParam("id") Integer id)
    • GET: Message find(@PathParam("id") Integer id) GET: Message find(@PathParam("id") Integer id)
  • base path + 2 parameters: myentities.message/{param1}/{param2} 基本路径+ 2个参数: myentities.message/{param1}/{param2}
    • GET: List<Message> findRange(@PathParam("from") Integer from, @PathParam("to")Integer to) GET: List<Message> findRange(@PathParam("from") Integer from, @PathParam("to")Integer to)
    • GET: Message findConversation(@PathParam("Receiver") String receiver,@PathParam("Sender") String sender ) GET: Message findConversation(@PathParam("Receiver") String receiver,@PathParam("Sender") String sender )

You can easily see, that findRange and findConversation use the same path and the same method. 您可以轻松地发现, findRangefindConversation使用相同的路径和相同的方法。

For REST services it's common to use an human readable format, although not required. 对于REST服务,通常使用人类可读的格式,尽管不是必需的。 For example you could use query parameters for the findRange and findConversation methods, that would even allow you to combine the search parameters: 例如,您可以对findRangefindConversation方法使用查询参数,甚至可以组合搜索参数:

.../myentities.message/?from=1000&to=2000&receiver=0815&sender=0911

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM