用Java实现RESTful Web Services框架的简要步骤

Posted Maozi_Lao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用Java实现RESTful Web Services框架的简要步骤相关的知识,希望对你有一定的参考价值。


1、         REST和RESTful Web Services的简要说明

REST(RepresentationalState Transfer),中文称为表述性状态转移,是一种针对于网络应用开发的软件架构风格,是满足一定的架构约束条件的。REST包括的准则主要有:1)网络上所有事物都抽象成资源;2)每个资源对应唯一的URI;3)通过通用接口对资源操作;5)操作都是无状态的;

RESTfulWeb Services,这是基于REST和HTTP实现的Web服务,在其实现的时候定义了URI,对资源的操作,以及支持的MIME类型等。

2、         JAX-RS和Jersey的简要说明:

JAX-RS,或称JSR311,是帮助实现RESTful WebServices的一组API,而Jersey则是其参考实现。

3、         开发环境配置:

Eclipse: 需要能进行Web Service开发的版本,例如《Eclipse IDE forJava EE Developers》,官网的下载地址附在博客末尾;

Tomcat:Tomcat是作为Web应用程序的服务器而使用的,为了在本次开发中能正确开发并调试程序,需要在Eclipse上预先配置Tomcat,具体步骤给出了相关链接,不在博文内直接表述。Tomcat的下载版本也至于文末;

4、         Jersey开发包下载以及其它包下载:


为了开发RESTful Web服务,需要下载对应的Jersey库文件,同时在本程序中,由于需要采用JSON样式,需要额外下载部分jar包;所有需要的jar包的截图如下:

其中,Jersey相关库文件可从其官网下载,链接文末给出;其余jar包也一起打包置于lib.rar中。

5、         具体步骤:

步骤一:新建Eclipse工程:“File->New->Other->DynamicWeb Project”,此处将工程命名为Jersey,之后的配置大约如下,具体需要注意Target runtime需要指定为对应的Tomcat版本,例如此处是7.0;


步骤二:将刚才下载的全部jar包复制到工程目录下,WEB-INF文件夹下的lib中,如图所示;


步骤三:新建包用于存放所有资源,此处命名为sample.hello.resources,并新建类HelloResource(此资源仅用于测试,之后可以删除),代码如下:

package sample.hello.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource 
	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayHello() 
		return "Hello Jersey";
	

其中,@Path即定义了资源的URI,@Get即HTTP的Get方法,@Produces声明了相应内容的MIME类型;

步骤四:修改WEB-INF下的web.xml文件,内容改为:


   

   
  
    
     Jersey
    
  
    
    
     
      index.html
     
    
     
      index.htm
     
    
     
      index.jsp
     
    
     
      default.html
     
    
     
      default.htm
     
    
     
      default.jsp
     
  
    
  
    
  
     
      Jersey REST Service
     

     
      
  com.sun.jersey.spi.container.servlet.ServletContainer

     
  
     
    
      
       com.sun.jersey.config.property.packages
      
    
      
       sample.hello.resources
      
  
     
  
     
      1
     

    

    
  
     
      Jersey REST Service
     
  
     
      /rest/*
     

       
  

   

 

之后就可以尝试启动Tomcat,并在浏览器中输入:http://your_domain:port/display-name/url-pattern/path_from_rest_class以访问资源了,例到目前为止,要访问HelloResource则需要进入http://localhost:8080/Jersey/rest/hello.成功的话,则浏览器返回‘Hello Jersey’.

 

步骤五:接下来,以所谓联系人(Contacts)为样例程序进行开发,主要的资源包括了ContactResource和ContactsResource两种,后者是前者的资源集合;资源定义分别如下:

public class ContactResource 
	@Context
	UriInfo uriInfo;
	@Context
	Request request;
	String contact;
	
	public ContactResource(UriInfo uriInfo, Request request, 
			String contact) 
		this.uriInfo = uriInfo;
		this.request = request;
		this.contact = contact;
	
	
	@GET
	@Produces(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON)
	public Contact getContact() 
		Contact cont = ContactStore.getStore().get(contact);
		if(cont==null)
			throw new NotFoundException("No such Contact.");
		return cont;
	
    

ContactsResource:

@Path("/contacts")
public class ContactsResource 
	@Context
	UriInfo uriInfo;
	@Context
	Request request;

	@GET
	@Produces(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON)
	public List
   
     getContacts() 
		List
    
      contacts = >new ArrayList
     
      ();
		contacts.addAll( ContactStore.getStore().values() );
		return contacts;
	

@Path("contact")
	public ContactResource getContact(
			@PathParam("contact") String contact) 
		return new ContactResource(uriInfo, request, contact);
	
           

     
    
   

这样就定义完样例程序的资源了。在具体实现程序时应该根据需要定义资源的属性和方法;

步骤六:上述仅仅实现了对资源的Get操作,即“检索某一资源的表现形式”或“列出资源集合中的所有成员”,要实现POST(创建资源或子资源),PUT(更新资源),DELETE(删除资源)操作,则需要在资源定义中声明额外的方法。例如:

POST操作(创建一个Contact):

@POST
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newContact(
		@FormParam("id") String id,
		@FormParam("name") String name,
		@Context HttpServletResponse servletResponse
) throws IOException 
	Contact c = new Contact(id,name,new ArrayList
()); ContactStore.getStore().put(id, c); URI uri = uriInfo.getAbsolutePathBuilder().path(id).build(); Response.created(uri).build(); servletResponse.sendRedirect("../pages/new_contact.html");

PUT操作(更新一个Contact):

@PUT
@Consumes(MediaType.APPLICATION_XML)
public Response putContact(JAXBElement
   
     jaxbContact) 
	Contact c = jaxbContact.getValue();
	return putAndGetResponse(c);


private Response putAndGetResponse(Contact c) 
	Response res;
	if(ContactStore.getStore().containsKey(c.getId())) 
		res = Response.noContent().build();
	 else 
		res = Response.created(uriInfo.getAbsolutePath()).build();
	
	ContactStore.getStore().put(c.getId(), c);
	return res;
   

   

DELETE(删除一个Contact):

                                    

@DELETE
public void deleteContact() 
	Contact c = ContactStore.getStore().remove(contact);
	if(c==null)
		throw new NotFoundException("No such Contact.");
  

步骤七(只针对样例程序):这一步骤是为了实现资源的定义而附加的操作,与具体的Web服务有关。就样例程序而言,这一步是必须的,但是对于其它程序则不是。在定义完成资源之后需要额外增加四个类的定义:位于sample.hello.bean下的Address类的定义和Contact类的定义,位于sample.hello.storage下的ContactStore,以及位于sample.hello.util下的ParamUtil类的定义。代码分别如下:

Address.java:

package sample.hello.bean;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Address 
	private String city;
	private String street;
	
	public Address() 
	
	public Address(String city, String street) 
		this.city = city;
		this.street = street;
	

	public String getCity() 
		return city;
	

	public void setCity(String city) 
		this.city = city;
	

	public String getStreet() 
		return street;
	

	public void setStreet(String street) 
		this.street = street;
	
	

Contact.java:

 

package sample.hello.bean;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Contact 
	private String id;
	private String name;
	private List
addresses; public Contact() public Contact(String id, String name, List
addresses) this.id = id; this.name = name; this.addresses = addresses; 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; @XmlElement(name="address") public List
getAddresses() return addresses; public void setAddresses(List
addresses) this.addresses = addresses;

ContactStore.java:

package sample.hello.storage;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import sample.hello.bean.Address;
import sample.hello.bean.Contact;

public class ContactStore 
	private static Map
   
     store;
	private static ContactStore instance = null;
	
	private ContactStore() 
		store = new HashMap
    
     ();
		initOneContact();
	
	
	public static Map
     
       getStore() 
		if(instance==null) 
			instance = new ContactStore();
		
		return store;
	
	
	private static void initOneContact() 
		Address[] addrs = 
			new Address("Shanghai", "Long Hua Street"),
			new Address("Shanghai", "Dong Quan Street")
		;
		Contact cHuang = new Contact("huangyim", "Huang Yi Ming", Arrays.asList(addrs));
		store.put(cHuang.getId(), cHuang);
	


     
    
   

ParamUtil.java:

package sample.hello.util;

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

public class ParamUtil 
	public static Map
   
     parse(String paramString) 
		Map
    
      params = new HashMap
     
      ();
		String[] paramPairs = paramString.split("&");
		for(String param : paramPairs) 
			String[] key_value = param.split("=");
			params.put(key_value[0], key_value[1]);
		
		return params;
	


     
    
   

到此为止,样例程序的资源定义就完成了。

步骤八(只针对样例程序):此时启动Tomcat并访问ContactsResource资源,则可以看到一个Contact的JSON的样式表现如下:

"contact":"address":["city":"Shanghai","street":"LongHua Street","city":"Shanghai","street":"DongQuanStreet"],"id":"huangyim","name":"HuangYi Ming"

 

步骤九(选做):通过Jersey Client可以与RESTful Web 服务通讯,这可以用于对服务进行单元测试(基于不同操作)。所需要完成的内容大概如下:

package sample.hello.client;

import java.util.Arrays;
import java.util.List;

import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXBElement;

import sample.hello.bean.Address;
import sample.hello.bean.Contact;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.representation.Form;

public class ContactClient 
	public static void main(String[] args) 
		Client c = Client.create();
		WebResource r = c.resource("http://localhost:8080/Jersey/rest/contacts");
		
		System.out.println("===== Get huangyim =====");
		getOneContact(r, "huangyim");
		
		System.out.println("===== Create foo =====");
		postForm(r, "foo", "bar");
		
		Address[] addrs = 
			new Address("Shanghai", "Ke Yuan Street")
		;
		Contact cnt = new Contact("guoqing", "Guo Qing", Arrays.asList(addrs));
		
		System.out.println("===== Create guoqing =====");
		putOneContact(r, cnt);
		
		System.out.println("===== All Contacts =====");
		getContacts(r);
		
		System.out.println("===== Delete foo =====");
		deleteOneContact(r, "foo");
		
		System.out.println("===== All Contacts =====");
		getContacts(r);
	
	
	public static void getContacts(WebResource r) 
		
		// 1, get response as plain text
		String jsonRes = r.accept(MediaType.APPLICATION_JSON).get(String.class);
		System.out.println(jsonRes);
		
		String xmlRes = r.accept(MediaType.APPLICATION_XML).get(String.class);
		System.out.println(xmlRes);
		
		// 2, get response and headers etc, wrapped in ClientResponse
		ClientResponse response = r.get(ClientResponse.class);
		System.out.println( response.getStatus() );
		System.out.println( response.getHeaders().get("Content-Type") );
		String entity = response.getEntity(String.class);
		System.out.println(entity);
		
		// 3, get JAXB response
		GenericType
   
    
     > genericType = new GenericType
     
      
       >() ;
		List
       
         contacts = r.accept(MediaType.APPLICATION_JSON).get(genericType); System.out.println("No. of Contacts: " + contacts.size()); Contact contact = contacts.get(0); System.out.println(contact.getId() + ": " + contact.getName());  public static void getOneContact(WebResource r, String id)  GenericType
        
         
          > generic = new GenericType
          
           
            >() ; JAXBElement
            
              jaxbContact = r.path(id).accept(MediaType.APPLICATION_JSON).get(generic); Contact contact = jaxbContact.getValue(); System.out.println(contact.getId() + ": " + contact.getName());  public static void postForm(WebResource r, String id, String name)  Form form = new Form(); form.add("id", id); form.add("name", name); ClientResponse response = r.type(MediaType.APPLICATION_FORM_URLENCODED) .post(ClientResponse.class, form); System.out.println(response.getEntity(String.class));  public static void putOneContact(WebResource r, Contact c)  ClientResponse response = r.path(c.getId()).accept(MediaType.APPLICATION_JSON) .put(ClientResponse.class, c); System.out.println(response.getStatus());  public static void deleteOneContact(WebResource r, String id)  ClientResponse response = r.path(id).delete(ClientResponse.class); System.out.println(response.getStatus());   
            
           
          
         
        
       
      
     
    
   

 

以上便是用Java进行RESTful WebServices开发的全部内容。主要的工作在于对URI的定义和相关操作方法的定义。


附加链接:

1、 Eclipse 官网下载:http://www.eclipse.org/downloads/

2、 Tomcat官网下载:http://tomcat.apache.org/download-70.cgi

3、 在Eclipse上配置Tomcat: http://jingyan.baidu.com/article/ca2d939dd90183eb6d31ce79.html

4、  Jersey官网下载:https://jersey.java.net/download.html

5、 参考链接1:http://only81.iteye.com/blog/1689537

6、 参考链接2:http://hbluojiahui.blog.163.com/blog/static/310647672009823101440937/

7、 参考链接3:http://blog.csdn.net/zztfj/article/details/7608991


以上是关于用Java实现RESTful Web Services框架的简要步骤的主要内容,如果未能解决你的问题,请参考以下文章

用 Java 技术创建 RESTful Web 服务/@Path@Produces@PathParam

Restful

SSM+RESTful+ajax——开发Java Web

使用RESTful风格开发Java Web

用spring boot快速创建 Restful Web Service

Java Web学习总结(43)—— Restful API 版本控制