【发布时间】:2011-10-01 19:46:33
【问题描述】:
这是我的要求:
- 我在 mysql 中有一个简单的表(考虑任何有几个字段的表)
- 我需要用 Java 编写一个简单的 RESTFUL JSON Web 服务,用于对这个表执行 CRUD 操作。
我尝试在网上搜索一些全面的示例,但找不到。 有人可以帮忙吗?
【问题讨论】:
-
您是否考虑过结合使用 Spring Web Services 和 Hibernate 进行 CRUD 操作?
这是我的要求:
我尝试在网上搜索一些全面的示例,但找不到。 有人可以帮忙吗?
【问题讨论】:
Jersey 是一个用于构建 RESTful Web 服务的 JAX-RS 实现。
从他们的教程开始。这很容易。
http://jersey.java.net/nonav/documentation/latest/getting-started.html
编辑:另外,关于这个主题,O'Riley 有一本很棒的书(我知道,令人震惊); RESTful Java with JAX-RS
【讨论】:
我会看看 Spring 提供了什么。有RestTemplate和Spring MVC,应该都能帮到你。
另一件有用的事情是某种 JSON 映射库。我会推荐Jackson Object Mapper。查看他们的教程,了解其工作原理。
【讨论】:
我将概述我的博客文章 Building a RESTful Web Service in Java 的基本部分,其中显示了您可以采取的步骤来连接到数据库并使用以下内容创建 RESTful Web 服务。
以下描述假定您已经安装了上面列出的技术。该服务适用于数据库表“item”,该表存储具有id、itemName、itemDescription、itemPrice字段的项目。
http://localhost:4848)。为了映射到数据库,使用了 JPA 实体。 JPA 实体是一个简单的 POJO(普通旧 Java 对象),使用 JPA 注释进行注释。如果数据库已经存在,Eclipse 可以从数据库中生成 JPA Entity。
在 Eclipse 中使用 SQLscrapbook 使用以下 SQL 创建数据库表
CREATE TABLE item (
id VARCHAR(36) NOT NULL,
itemName TEXT NOT NULL,
itemDescription TEXT,
itemPrice DOUBLE,
PRIMARY KEY (id)
)
通过右键单击在 Eclipse 中创建的包并选择 New > JPA Entities from Table,从数据库表中创建 JPA 实体。
由于此示例使用 UUID 作为主键,因此还有特定于 EclipseLink 的注释(@UuidGenerator 和 @GeneratedValue)来负责创建它们。没有必要使用 UUID 作为主键,但我使用它的原因之一是我可以在客户端上创建一个带有 UUID 的模型,然后将该新模型放入服务器(例如,在离线模式下,新当单元信号返回时,本地创建和存储的模型将被 PUT 到服务器)。如果服务器创建了 UUID,则使用 POST 将新模型发送到没有 id 的服务器。
package com.zangolie.smallbiz.entities;
import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.annotations.UuidGenerator;
/**
* The persistent class for the item database table.
*
*/
@UuidGenerator(name="UUID")
@XmlRootElement
@Entity
@NamedQuery(name="Item.findAll", query="SELECT i FROM Item i")
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator="UUID")
@Column(length=36)
private String id;
private String itemDescription;
@Lob
private String itemName;
private double itemPrice;
public Item() {
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getItemDescription() {
return this.itemDescription;
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDescription;
}
public String getItemName() {
return this.itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public double getItemPrice() {
return this.itemPrice;
}
public void setItemPrice(double itemPrice) {
this.itemPrice = itemPrice;
}
}
创建文件夹 src\main\webapp\WEB-INF\classes\META-INF 并创建一个 persistence.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="testPU" transaction-type="JTA">
<jta-data-source>jdbc/SmallBiz</jta-data-source>
</persistence-unit>
</persistence>
xml sn-p
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
JAX-RS 服务
package com.zangolie.smallbiz.services.rest;
import java.net.URI;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
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 javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import com.zangolie.smallbiz.entities.Item;
@Path("/item")
@Produces ({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Consumes ({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@Stateless
public class ItemRestService {
//the PersistenceContext annotation is a shortcut that hides the fact
//that, an entity manager is always obtained from an EntityManagerFactory.
//The peristitence.xml file defines persistence units which is supplied by name
//to the EntityManagerFactory, thus dictating settings and classes used by the
//entity manager
@PersistenceContext(unitName = "testPU")
private EntityManager em;
//Inject UriInfo to build the uri used in the POST response
@Context
private UriInfo uriInfo;
@POST
public Response createItem(Item item){
if(item == null){
throw new BadRequestException();
}
em.persist(item);
//Build a uri with the Item id appended to the absolute path
//This is so the client gets the Item id and also has the path to the resource created
URI itemUri = uriInfo.getAbsolutePathBuilder().path(item.getId()).build();
//The created response will not have a body. The itemUri will be in the Header
return Response.created(itemUri).build();
}
@GET
@Path("{id}")
public Response getItem(@PathParam("id") String id){
Item item = em.find(Item.class, id);
if(item == null){
throw new NotFoundException();
}
return Response.ok(item).build();
}
//Response.ok() does not accept collections
//But we return a collection and JAX-RS will generate header 200 OK and
//will handle converting the collection to xml or json as the body
@GET
public Collection<Item> getItems(){
TypedQuery<Item> query = em.createNamedQuery("Item.findAll", Item.class);
return query.getResultList();
}
@PUT
@Path("{id}")
public Response updateItem(Item item, @PathParam("id") String id){
if(id == null){
throw new BadRequestException();
}
//Ideally we should check the id is a valid UUID. Not implementing for now
item.setId(id);
em.merge(item);
return Response.ok().build();
}
@DELETE
@Path("{id}")
public Response deleteItem(@PathParam("id") String id){
Item item = em.find(Item.class, id);
if(item == null){
throw new NotFoundException();
}
em.remove(item);
return Response.noContent().build();
}
}
创建一个定义基本 uri 的应用程序类。例如http://localhost:8080/smallbiz/rest
package com.zangolie.smallbiz.services.rest;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("rest")
public class ApplicationConfig extends Application {
}
从 Eclipse 中部署到 GlassFish。
虽然该示例使用 GlassFish,但任何符合 Java EE 7 的容器都可以使用。如果您确实使用了不同的容器(并假设您对 JPA 使用相同的 EclipseLink,而对 JAX-RS 实现使用 JerseyLink),您将必须:
希望对你有帮助。
【讨论】:
这可能正是您正在寻找的: http://restsql.org/doc/Overview.html
免责声明: 我从未使用过它——只是记得最近在一篇新闻文章中看到过它。
【讨论】: