我有一个MySQL数据库,有两个表content
和message
。我试图使用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;
}
}
答案 0 :(得分:0)
findConversation
的路径不是唯一的。
这是对所有服务的概述:
myentities.message/
void create(Message entity)
void edit(Message entity)
List<Message> findAll()
myentities.message/count
String countREST()
myentities.message/{id}
void remove(@PathParam("id") Integer id)
Message find(@PathParam("id") Integer id)
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 )
您可以很容易地看到,findRange
和findConversation
使用相同的路径和相同的方法。
对于REST服务,尽管不是必需的,但通常使用人类可读的格式。例如,您可以使用findRange
和findConversation
方法的查询参数,甚至可以合并搜索参数:
.../myentities.message/?from=1000&to=2000&receiver=0815&sender=0911