需要用Java编写RESTful JSON服务

时间:2011-10-01 19:46:34

标签: java json rest

这是我的要求:

  1. 我在mysql中有一个简单的表(考虑任何带有几个字段的表)
  2. 我需要在Java中编写一个简单的RESTFUL JSON Web服务,在此表上执行CRUD操作。
  3. 我尝试在网上搜索一些全面的例子,但找不到任何。 有人可以帮忙吗?

4 个答案:

答案 0 :(得分:8)

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

从他们的教程开始。这很容易。

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

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

答案 1 :(得分:2)

我会看一下Spring提供的内容。有RestTemplateSpring MVC,两者都可以帮助你。

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

答案 2 :(得分:2)

我将概述我的博文Building a RESTful Web Service in Java的基本部分,其中显示了使用以下内容连接数据库和创建RESTful Web服务可以采取的步骤。

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

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

持久层

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

要映射到数据库,请使用JPA实体。 JPA实体是一个简单的POJO(普通旧Java对象),注释了JPA注释。如果数据库已经存在,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&gt;,从数据库表创建JPA实体。表中的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文件。

    <?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>
    

RESTful服务层

  • 将Maven编译器设置为1.7
    • 右键单击pom.xml文件,然后选择打开方式&gt; Maven POM编辑。在结束标记之前添加以下内容。

xml代码段

    <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>
  • 使用m2e添加依赖项:
    • Servlet 3.1(JAX-RS 2.0需要这个)&#34; javax.servlet javax.servlet.api&#34;
    • 泽西岛(适用于JAX-RS)&#34; org.glassfish.jersey.core jersey-sever&#34;
    • EJB(需要使用@Stateless注释)&#34; javax.ejb javax.ejb.api&#34;
  • 创建POJO(普通旧Java对象)并使用JAX-RS注释对其进行注释以创建端点。
    • @Path(&#34; / your-app-api-uri&#34;):表示资源所在的相对于服务器基础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<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。

    • 右键单击项目运行方式&gt;在服务器上运行
    • 选择已连接的GlassFish服务器。
  • 使用任何HTTP客户端(例如以chrome工作的Postman)进行测试。

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

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

希望它有用。

答案 3 :(得分:1)

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

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