[英]Adding new methods to RESTful web service (error)
I have a MySQL database that has two tables content
and message
. 我有一个具有两个表
content
和message
的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: 这是所有服务的概述:
myentities.message/
myentities.message/
void create(Message entity)
void create(Message entity)
void edit(Message entity)
void edit(Message entity)
List<Message> findAll()
List<Message> findAll()
myentities.message/count
myentities.message/count
String countREST()
String countREST()
myentities.message/{id}
myentities.message/{id}
void remove(@PathParam("id") Integer id)
void remove(@PathParam("id") Integer id)
Message find(@PathParam("id") Integer id)
Message find(@PathParam("id") Integer id)
myentities.message/{param1}/{param2}
myentities.message/{param1}/{param2}
List<Message> findRange(@PathParam("from") Integer from, @PathParam("to")Integer to)
List<Message> findRange(@PathParam("from") Integer from, @PathParam("to")Integer to)
Message findConversation(@PathParam("Receiver") String receiver,@PathParam("Sender") String sender )
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. 您可以轻松地发现,
findRange
和findConversation
使用相同的路径和相同的方法。
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: 例如,您可以对
findRange
和findConversation
方法使用查询参数,甚至可以组合搜索参数:
.../myentities.message/?from=1000&to=2000&receiver=0815&sender=0911
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.