Eclipse和Tomcat的RESTEasy教程

时间:2020-02-23 14:35:33  来源:igfitidea点击:

欢迎使用RESTEasy教程。
RESTEasy是JBoss项目提供的JAX-RS实现。
我们可以使用RESTEasy创建宁静的Web服务。
RESTEasy提供了与JBoss Application Server的更紧密的集成,但是我们可以将其部署在任何servlet容器上。
因此,今天我们将学习如何使用RestEasy框架创建Restful Web服务并部署在Tomcat Servlet容器中进行测试。

RESTEasy教程

RESTEasy框架的一些功能包括:

  • 兼容JAX-RS API-因此大多数情况下,您需要将其插入JAX-RS API编码以创建其余的Web服务。

  • 在几乎所有支持Java 6或者更高版本的servlet容器上运行

  • 提供对使用JAX-RS 2.0客户端API编写客户端程序的支持。
    我们也会研究测试程序。

  • 丰富的提供程序集-XML,JSON,YAML,Multipart,XOP,Atom等

  • OAuth2和带有JBoss AS7的分布式SSO

  • EJB,Seam,Guice,Spring和Spring MVC集成

RESTEasy示例

以下是我们将在RestEasy Web服务实现中公开的URI。

URIHTTP MethodDescription
/employee/addPOSTAdd an employee
/employee/getDummyGETreturns a dummy employee object
/employee/{id}/getGETGet the employee with 'id' in the URI
/employee/getAllGETGet all employees
/employee/{id}/deleteDELETEDelete employee with 'id' in the URI

RESTEasy示例Eclipse项目

下图显示了我们的最终项目结构。
首先,在Eclipse中创建"动态Web应用程序",然后将其转换为Maven项目以获取Web项目框架。

让我们研究一下RestEasy网络服务项目的不同组成部分。

RESTEasy示例模型类

我们有两个模型类-" Employee"(雇员)对象和" GenericResponse"(发送状态,消息和错误代码的客户端响应对象)。

package com.theitroad.jaxrs.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "employee")
public class Employee {
	private String name;
	private double salary;
	private int id;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return id + "::" + name + "::" + salary;
	}

}
package com.theitroad.jaxrs.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "response")
public class GenericResponse {

	private boolean status;
	private String message;
	private String errorCode;

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public String getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(String errorCode) {
		this.errorCode = errorCode;
	}

	@Override
	public String toString() {
		return status + "|" + message + "|" + errorCode;
	}
}

请注意,两个Java Bean均带有@ XmlRootElement注释。
JAXB API要求将对象转换为xml,反之亦然。

RESTEasy示例服务类

首先,我们为尝试在静态网络服务中公开的所有操作创建一个界面。

package com.theitroad.jaxrs.service;

import javax.ws.rs.core.Response;

import com.theitroad.jaxrs.model.Employee;

public interface EmployeeService {

	public Response addEmployee(Employee e);
	
	public Response deleteEmployee(int id);
	
	public Employee getEmployee(int id);
	
	public Employee[] getAllEmployees();

}

以下是上述员工服务接口的实现类。

package com.theitroad.jaxrs.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
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.MediaType;
import javax.ws.rs.core.Response;

import com.theitroad.jaxrs.model.Employee;
import com.theitroad.jaxrs.model.GenericResponse;

@Path("/employee")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class EmployeeServiceImpl implements EmployeeService {

	private static Map<Integer,Employee> emps = new HashMap<Integer,Employee>();
	
	@Override
	@POST
  @Path("/add")
	public Response addEmployee(Employee e) {
		GenericResponse response = new GenericResponse();
		if(emps.get(e.getId()) != null){
			response.setStatus(false);
			response.setMessage("Employee Already Exists");
			response.setErrorCode("EC-01");
			return Response.status(422).entity(response).build();
		}
		emps.put(e.getId(), e);
		response.setStatus(true);
		response.setMessage("Employee created successfully");
		return Response.ok(response).build();
	}

	@Override
	@DELETE
  @Path("/{id}/delete")
	public Response deleteEmployee(@PathParam("id") int id) {
		GenericResponse response = new GenericResponse();
		if(emps.get(id) == null){
			response.setStatus(false);
			response.setMessage("Employee Doesn't Exists");
			response.setErrorCode("EC-02");
			return Response.status(404).entity(response).build();
		}
		emps.remove(id);
		response.setStatus(true);
		response.setMessage("Employee deleted successfully");
		return Response.ok(response).build();
	}

	@Override
	@GET
	@Path("/{id}/get")
	public Employee getEmployee(@PathParam("id") int id) {
		return emps.get(id);
	}
	
	@GET
	@Path("/{id}/getDummy")
	public Employee getDummyEmployee(@PathParam("id") int id) {
		Employee e = new Employee();
		e.setSalary(8976.55);
		e.setName("Dummy");
		e.setId(id);
		return e;
	}

	@Override
	@GET
	@Path("/getAll")
	public Employee[] getAllEmployees() {
		Set<Integer> ids = emps.keySet();
		Employee[] e = new Employee[ids.size()];
		int i=0;
		for(Integer id : ids){
			e[i] = emps.get(id);
			i++;
		}
		return e;
	}

}

我们仅使用诸如@ Path,@ PathParam,Response等的JAX-RS API批注。
请注意,在某些方法中,我将javax.ws.rs.core.Response作为响应对象。
我想发送200以外的HTTP状态代码的地方。

RESTEasy配置

到目前为止,我们还没有做过与RestEasy相关的任何事情,现在是时候将RestEasy配置为我们的宁静Web服务的JAX-RS API实现。

第一步是扩展javax.ws.rs.core.Application类,并覆盖一些注入服务类实现的方法。

package com.theitroad.jaxrs.resteasy.app;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

import com.theitroad.jaxrs.service.EmployeeServiceImpl;

public class EmployeeApplication extends Application {
	
	private Set<Object> singletons = new HashSet<Object>();

	public EmployeeApplication() {
		singletons.add(new EmployeeServiceImpl());
	}

	@Override
	public Set<Object> getSingletons() {
		return singletons;
	}

}

下一步是在我们的pom.xml文件中添加RESTEasy Maven依赖项,如下所示。

<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-jaxrs</artifactId>
	<version>3.0.13.Final</version>
</dependency>
<!-- Below dependency is for JAXB integration -->
<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-jaxb-provider</artifactId>
	<version>3.0.13.Final</version>
</dependency>

最后一步是将部署描述符中的RESTEasy Servlet类配置为前端控制器。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>RestEasy-Example</display-name>
<listener>
  <listener-class>
       org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    </listener-class>
</listener>
<servlet>
  <servlet-name>resteasy-servlet</servlet-name>
  <servlet-class>
          org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
      </servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.theitroad.jaxrs.resteasy.app.EmployeeApplication</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>resteasy-servlet</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

我们的网络服务已准备就绪。
您可以看到,将RestEasy插入为我们的JAX-RS实现以实现静态Web服务是多么容易。

RESTEasy Restful Web服务测试

我正在使用Chrome Postman扩展程序对我们的Web服务进行测试。
以下是一些具有响应的测试案例。
如下图所示,所有请求中的标头都是一个共同的部分。

  • getDummy
  • add
  • get
  • getAll
  • delete
  • 添加错误– HTTP响应422
  • 删除错误-HTTP响应404

如您所见,所有测试都通过了测试,我们的其余Web服务运行正常。

RestEasy Client – ResteasyClient示例

如前所述,RestEasy还提供用于通过Java程序测试其余Web服务的API。
为此,我们需要在pom.xml文件中添加另一个依赖项。

<dependency>
	<groupId>org.jboss.resteasy</groupId>
	<artifactId>resteasy-client</artifactId>
	<version>3.0.13.Final</version>
</dependency>

下面是简单的测试程序,其中我正在以编程方式测试我们的Web服务。
我提供了用于测试GET,POST和DELETE HTTP方法的示例。

package com.theitroad.jaxrs.resteasy.client;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;

import com.theitroad.jaxrs.model.Employee;
import com.theitroad.jaxrs.model.GenericResponse;

public class RestEasyTestClient {

	public static void main(String[] args) {

		ResteasyClient client = new ResteasyClientBuilder().build();
		
		//GET example
		ResteasyWebTarget getDummy = client.target("https://localhost:8080/RestEasy-Example/employee/99/getDummy");
		
		Response getDummyResponse = getDummy.request().get();
		
		String value = getDummyResponse.readEntity(String.class);
      System.out.println(value);
      getDummyResponse.close();  
      
      //POST example
		ResteasyWebTarget add = client.target("https://localhost:8080/RestEasy-Example/employee/add");
		Employee emp = new Employee();
		emp.setId(50);emp.setName("Rick");emp.setSalary(1000);
		Response addResponse = add.request().post(Entity.entity(emp, MediaType.APPLICATION_XML));
		System.out.println(addResponse.readEntity(GenericResponse.class));
		System.out.println("HTTP Response Code:"+addResponse.getStatus());
		addResponse.close();
		
		addResponse = add.request().post(Entity.entity(emp, MediaType.APPLICATION_XML));
		System.out.println(addResponse.readEntity(GenericResponse.class));
		System.out.println("HTTP Response Code:"+addResponse.getStatus());
		addResponse.close();
		
		//DELETE example
		ResteasyWebTarget delete = client.target("https://localhost:8080/RestEasy-Example/employee/50/delete");
		Response deleteResponse = delete.request().delete();
		System.out.println(deleteResponse.readEntity(GenericResponse.class));
		System.out.println("HTTP Response Code:"+deleteResponse.getStatus());
		deleteResponse.close();
		
		deleteResponse = delete.request().delete();
		System.out.println(deleteResponse.readEntity(GenericResponse.class));
		System.out.println("HTTP Response Code:"+deleteResponse.getStatus());
		deleteResponse.close();
	}

}

以下是上述RESTEasy客户程序产生的输出。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee><id>99</id><name>Dummy</name><salary>8976.55</salary></employee>
true|Employee created successfully|null
HTTP Response Code:200
false|Employee Already Exists|EC-01
HTTP Response Code:422
true|Employee deleted successfully|null
HTTP Response Code:200
false|Employee Doesn't Exists|EC-02
HTTP Response Code:404