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

时间:2013-05-01 21:43:30

标签: java rest glassfish restful-url

我有一个MySQL数据库,有两个表contentmessage。我试图使用netbeans将这两个表公开为Restful Web服务。我按照本教程。 https://netbeans.org/kb/docs/websvc/rest.html

应用程序适用于生成的方法和类,但我想添加一个额外的方法来通过另外两个参数“发送者”和“接收者”获取消息列表。当我添加它时,我在Glassfish中收到以下错误,服务器无法启动。

我添加的方法名为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) |#]

这是消息类(我手动添加了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 + " ]";
     }

  }

这是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;
     }
  }

1 个答案:

答案 0 :(得分:0)

findConversation的路径不是唯一的。

这是对所有服务的概述:

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

您可以很容易地看到,findRangefindConversation使用相同的路径和相同的方法。

对于REST服务,尽管不是必需的,但通常使用人类可读的格式。例如,您可以使用findRangefindConversation方法的查询参数,甚至可以合并搜索参数:

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