使用JSON和Jersey的Java RESTful Web服務
使用Jersey建立一個RESTful Web服務來産生JSON響應。 RESTful Web服務可以配置為生成不同類型的響應,如XML,JSON,html,純文字和大多數MIME類型。 本篇文章完成設定mime類型以生成JSON響應。 如果你剛剛開始使用RESTful Web服務,可以先了解下Jersey的RESTful Web服務的基本資訊。
@Produces Annotation
我們可以使用@Produces注釋為資源指定MIME類型表示。 例如,我們可以将mime類型指定為text / html作為@Produces(“text / html”)。 此@Produces注釋可以在類級别和方法級别指定。 方法預設為類級别注釋,方法級别注釋覆寫類級别注釋的值。
當資源能夠産生多個MIME類型時,則基于請求的Accept頭選擇類型。 accept頭可以是以下格式的,例如,
Accept: application/json
接受标頭可以指定多個MIME類型,在這種情況下,會考慮由接受标頭指定的首選項。 如果首選項相等,則選擇@Produces注釋中的第一個出現MIME類型作為響應。
Web服務中的JSON響應
要更改已寫入以提供XML響應或建立新響應的Web服務,我們隻需要添加兩件事。
使用@Produces注釋并添加MIME類型應用程式/ json。
添加相關JAR檔案以生成JSON響應。
SEVERE: MessageBodyWriter not found for media type={application/json, q=1000}, type=class java.util.ArrayList, genericType=java.util.List<com.javapapers.webservices.rest.jersey.Animal>
.
如果您沒有添加依賴的Jar檔案以生成JSON響應,您将收到上述錯誤。 應該添加以下Maven依賴項來生成JSON
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.17</version>
</dependency>
帶有JSON示例的RESTful Web服務
在前面的教程中,我們看到了使用Jersey建立一個CRUD RESTful Web服務。 我們将根據該Web服務教程中提供的示例建立一個示例Web服務。 有多個依賴jar需要運作這個例子,它更好地使用MAVEN來管理JAR依賴。 通過我的Maven 10分鐘教程,如果你是新的。
- pom.xml和Maven依賴
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>JSONRESTfulServices</groupId>
<artifactId>JSONRESTfulServices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.17</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.17</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
-
Java RESTful Web服務與JSON示例源代碼
ProductsResource.java
此RESTful服務資源使用@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON}),并且我們已經通過Maven添加了相關的JAR檔案以生成JSON響應。 現在,如果這個Web服務接收到一個帶有請求頭Accept:application / json的請求,它将發出一個JSON響應。
package com.javapapers.webservices.rest.jersey;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
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.Request;
import javax.ws.rs.core.UriInfo;
@Path("/products")
public class ProductsResource {
@Context
UriInfo uriInfo;
@Context
Request request;
ProductService productService;
public ProductsResource() {
productService = new ProductService();
}
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public List<Product> getProducts() {
return productService.getProductAsList();
}
@GET
@Produces(MediaType.TEXT_XML)
public List<Product> getProductsAsHtml() {
return productService.getProductAsList();
}
// URI: /rest/products/count
@GET
@Path("count")
@Produces(MediaType.TEXT_PLAIN)
public String getCount() {
return String.valueOf(productService.getProductsCount());
}
@POST
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void createProduct(@FormParam("id") String id,
@FormParam("productname") String name,
@FormParam("productcategory") String category,
@Context HttpServletResponse servletResponse) throws IOException {
Product product = new Product(id, name, category);
productService.createProduct(product);
servletResponse.sendRedirect("./products/");
}
@Path("{product}")
public ProductResource getProduct(@PathParam("product") String id) {
return new ProductResource(uriInfo, request, id);
}
}
ProductService.java
package com.javapapers.webservices.rest.jersey;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.JAXBElement;
public class ProductResource {
@Context
UriInfo uriInfo;
@Context
Request request;
String id;
ProductService productService;
public ProductResource(UriInfo uriInfo, Request request, String id) {
this.uriInfo = uriInfo;
this.request = request;
this.id = id;
productService = new ProductService();
}
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Product getProduct() {
Product product = productService.getProduct(id);
return product;
}
@GET
@Produces(MediaType.TEXT_XML)
public Product getProductAsHtml() {
Product product = productService.getProduct(id);
return product;
}
@PUT
@Consumes(MediaType.APPLICATION_XML)
public Response putProduct(JAXBElement<Product> productElement) {
Product product = productElement.getValue();
Response response;
if (productService.getProducts().containsKey(product.getId())) {
response = Response.noContent().build();
} else {
response = Response.created(uriInfo.getAbsolutePath()).build();
}
productService.createProduct(product);
return response;
}
@DELETE
public void deleteProduct() {
productService.deleteProduct(id);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>JSON RESTful Services</display-name>
<servlet>
<servlet-name>JSON RESTful Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.javapapers.webservices.rest.jersey</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JSON RESTful Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
其他檔案
package com.javapapers.webservices.rest.jersey;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Product {
private String id;
private String name;
private String category;
public Product() {
}
public Product(String id, String name, String category) {
super();
this.id = id;
this.name = name;
this.category = category;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
}
package com.javapapers.webservices.rest.jersey;
import java.util.HashMap;
import java.util.Map;
public enum ProductDao {
instance;
private Map<String, Product> products = new HashMap<String, Product>();
private ProductDao() {
// pumping-in some default data
Product product = new Product("1001", "iPhone 5S", "Mobile");
products.put("1", product);
product = new Product("1002", "Sony MDR-XD200", "Headphone");
products.put("2", product);
product = new Product("1003", "Bose Wave II", "Home Audio");
products.put("3", product);
}
public Map<String, Product> getProducts() {
return products;
}
}
package com.javapapers.webservices.rest.jersey;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ProductService {
ProductDao productDao;
public ProductService() {
productDao = ProductDao.instance;
}
public void createProduct(Product product) {
productDao.getProducts().put(product.getId(), product);
}
public Product getProduct(String id) {
return productDao.getProducts().get(id);
}
public Map<String, Product> getProducts() {
return productDao.getProducts();
}
public List<Product> getProductAsList() {
List<Product> productList = new ArrayList<Product>();
productList.addAll(productDao.getProducts().values());
return productList;
}
public int getProductsCount() {
return productDao.getProducts().size();
}
public void deleteProduct(String id) {
productDao.getProducts().remove(id);
}
}
-
RESTful Web服務用戶端
我們需要向Web服務添加一個“Header”請求。
JSON響應:
XML響應: