需要用Java编写RESTful JSON服务

这是我的要求:

  1. 我在mysql中有一个简单的表(考虑任何带有几个字段的表)
  2. 我需要在Java中编写一个简单的RESTFUL JSON Web服务,在该表上执行CRUD操作。

我尝试在网上搜索一些全面的例子,但找不到任何。 有人可以帮忙吗?

Jersey是用于构建RESTful Web服务的JAX-RS实现。

从他们的教程开始。 这很简单。

http://jersey.java.net/nonav/documentation/latest/getting-started.html

编辑:此外,还有一本关于这个主题的伟大的O’Riley书(令人震惊,我知道); 使用JAX-RS的RESTful Java

我会看一下Spring提供的内容。 有RestTemplate和Spring MVC ,两者都应该可以帮到你。

另一个有用的东西是某种JSON-Mapping库。 我会推荐Jackson Object Mapper 。 看看他们的教程,了解它的工作原理。

这可能正是你正在寻找的: http : //restsql.org/doc/Overview.html

免责声明:我从未使用它 – 只记得最近在新闻帖中看到它。

我将概述我在博客中使用Java构建RESTful Web服务的基本部分,其中显示了使用以下方法连接到数据库和创建RESTful Web服务的步骤。

  • IDE:Jave EE Developers(Kepler)的Eclipse IDE,内置Maven
  • 数据库:MySQL(也使用MySQL Workbench)
  • 应用程序服务器:GlassFish 4.0
  • Java EE 7(JAX-RS,JPA,JAXB等)
  • 任何用于测试的REST客户端:(例如Postman)

以下描述假设您已经安装了上面列出的技术。 该服务用于存储具有字段id,itemName,itemDescription,itemPrice的项目的数据库表“item”。

持久层

  • 使用MySQL Workbench的“ 在连接服务器中创建新模式 ”图标创建MySQL数据库模式。 在此示例中,架构称为“smallbiz”。
  • 将Eclipse连接到MySQL
    • 下载MySQL JDBC驱动程序并保存在方便的位置。
    • 在Eclipse中,在“ 数据源资源管理器”选项卡中创建新的数据库连接 。 在此过程中,您将需要浏览到MySQL JDBC驱动程序。
  • 在GlassFish中创建MySQL JDBC连接池和资源(这是应用程序在服务器上部署后能够连接数据库所必需的)。
    • 将MySQL JDBC驱动程序复制到GlassFish中的ext目录,即$ glassfish_install_folder \ glassfish \ lib \ ext 。 然后重启GlassFish。
    • 使用浏览器登录GlassFish管理区域(默认情况下位于http://localhost:4848 )。
    • Resources> JDBC> Connection Pools下 ,创建一个新的连接池,其“资源类型”为java.sql.Driver。
    • 在“新建JDBC连接池(第1步,共2步)”屏幕上。
      • 输入“池名称”(例如SmallBizPool)。
      • 选择“资源类型”(java.sql.Driver)。
      • 选择“数据库驱动程序供应商”(MySQL)。
      • 接下来
    • 在“ 附加属性”中的以下屏幕的底部。
      • URL: jdbc:mysql:// localhost:3306 / smallbiz
      • user: yourUser(root in my setup-up)
      • 密码: yourPassword
      • 在以下屏幕上Ping以测试连接。
    • Resources> JDBC> JDBC Resources的连接池中创建JDBC资源
      • 输入’JNDI名称’(例如jdbc / SmallBiz)。 我们在persistence.xml文件中使用它,以便应用程序知道如何连接到数据库。
      • 从“池名称”下拉列表中选择先前创建的连接池。
    • 有关JDBC连接池和资源的更多信息
      • 这个答案有一些可能有帮助的屏幕截图。 请注意,它使用javax.sql.DataSource的“资源类型”
      • 在Glassfish中制作数据源
      • 围绕JDBC资源和JDBC连接池Glassfish的一些混淆
  • 将Eclipse连接到GlassFish。
    • 通过搜索“ 帮助”>“Eclipse Marketplace”将GlassFish工具添加到Eclipse。
    • 使用Servers选项卡创建新服务器,将GlassFish连接到Eclipse。
      • 在“ 定义新服务器”屏幕上选择“GlassFish 4.0”。
      • 确保选中’jdk7’并在New GlasssFish 4.0 Runtime屏幕中选择JDK
      • 在随后的屏幕上,确保选择了正确的域目录(默认为domain1,例如$ glassfish_install_folder \ glassfish \ domains \ domain1 ),然后输入GlassFish的管理员凭据。
      • 您现在可以在Eclipse中与GlassFish(启动,停止,重新启动,运行等)进行交互。
  • 在Eclipse中创建一个新的Maven项目并使用m2e(内置)添加依赖项:
    • EclipseLink(用于JPA)“org.eclipse.persistence eclipselink”

要映射到数据库,使用JPA实体。 JPA实体很简单,用JPA注释注释POJO(Plain Old Java Object)。 如果数据库已存在,Eclipse可以从数据库生成JPA实体。

  • 使用Eclipse中的SQL 剪贴簿使用以下SQL创建数据库表

     CREATE TABLE item ( id VARCHAR(36) NOT NULL, itemName TEXT NOT NULL, itemDescription TEXT, itemPrice DOUBLE, PRIMARY KEY (id) ) 
  • 通过右键单击在Eclipse中创建的包并从表中选择New> JPA Entities,从数据库表创建JPA实体

  • 使用JAXB注释注释JPA实体,以便能够将它与xml或json进行编组。

由于此示例使用UUID作为主键,因此还有一些注释(@UuidGenerator和@GeneratedValue)特定于EclipseLink来处理它们。 没有必要使用UUID作为主键,但我使用它的原因之一是我可以在客户端上创建一个带有UUID的模型,然后将新模型PUT到服务器(例如,在离线模式下,新的当单元信号返回时,本地创建和存储的模型将被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文件。

        jdbc/SmallBiz   
    • 有关更多信息,请参阅了解JPA中的Persistence.xml 。

RESTful服务层

  • 将Maven编译器设置为1.7
    • 右键单击pom.xml文件,然后选择Open With> Maven POM Editor 。 在结束标记之前添加以下内容。

xml片段

     maven-compiler-plugin 3.1  1.7 1.7     
  • 使用m2e添加依赖项:
    • Servlet 3.1(JAX-RS 2.0需要这个)“javax.servlet javax.servlet.api”
    • 泽西岛(适用于JAX-RS)“org.glassfish.jersey.core jersey-sever”
    • EJB(需要使用@Stateless注释)“javax.ejb javax.ejb.api”
  • 创建POJO(普通的旧Java对象)并使用JAX-RS注释对其进行注释以创建端点。
    • @Path(“/ your-app-api-uri”) :指示相对于服务器库uri的路径,资源位于
    • @Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) :生成的表示可以是json或xml。
    • @Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) :消耗的表示可以是json或xml
    • @Stateless :服务器不在交互之间存储状态(这是RESTful架构的原则之一)。
  • 注释映射到CRUD操作的方法
    • @POST :创建
    • @GET :阅读
    • @PUT :更新
    • @DELETE :删除

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 getItems(){ TypedQuery 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服务器。
  • 使用任何HTTP客户端(例如在chrome中工作的Postman)进行测试。

虽然该示例使用GlassFish,但任何符合Java EE 7的容器都可以使用。 如果你确实使用了不同的容器(假设你使用相同的EclipseLink for JPA和Jersey来实现JAX-RS),你将不得不:

  • 整理出如何从Eclipse连接它。
  • 将Jersey和EclipseLink的Maven依赖项从提供更改为编译(因为这些是GlassFish中的实现,在其他容器中可能不同)。

希望它有所帮助。