一、restful web services
rest全称是Representation State Transfer(表述性状态转移)。它是一种软件架构风格,只是提供了一组设计原则和约束条件。在restful web services的设计原则中,所有的事物都应该拥有唯一的URI,通过对URI的请求访问,完成相应的操作。访问的方法与http协议中的若干方法相对应。如下:
- 创建资源,使用 POST 方法。
- 获取某个资源,使用 GET 方法。
- 对资源进行更新,使用 PUT 方法。
- 删除某个资源,使用 DELETE 方法。
二、使用cxf进行构建
1、服务器端
新建工程,添加cxf的依赖jar包。添加netty-all依赖,这里使用到的是netty-all-4.0.25.Final,下载地址为:http://netty.io/downloads.html 。
实体类Address:
package com.cxf.jaxrs; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "address")
public class Address { private int id;
private String city;
private String street; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} 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;
} }
实体类Person:
package com.cxf.jaxrs; import java.util.Date; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "person")
public class Person { private int id;
private String name;
private Date date; private Address address; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Date getDate() {
return date;
} public void setDate(Date date) {
this.date = date;
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} }
服务接口MyService:
package com.cxf.jaxrs; import java.util.Date;
import java.util.List; import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
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; @Path("/person/")
// @Produces("text/xml") //只返回xml类型
// @Produces("application/json") //只返回json类型
@Produces("*/*") //表示可返回所有类型
public class MyService { @GET //get方法请求
@Path("/{id}/") //路径
public Person getById(@PathParam("id") int id) {
Person person = new Person();
person.setId(id);
person.setName("zhangsan");
person.setDate(new Date()); Address add = new Address();
add.setId(22);
add.setCity("shanghai");
add.setStreet("pudong");
person.setAddress(add); return person;
} @GET //get方法请求
@Path("/") //路径
public List<Person> getAll() {
List<Person> persons = new java.util.ArrayList<Person>();
Person person = new Person();
person.setId(111);
person.setName("zhangsan");
person.setDate(new Date()); Person person2 = new Person();
person2.setId(222);
person2.setName("lisi");
person2.setDate(new Date());
persons.add(person);
persons.add(person2);
return persons;
} @DELETE //delete方法请求
@Path("/{id}") //路径
public Person removeById(@PathParam("id") int id) {
Person person = new Person();
person.setId(111);
person.setName("zhangsan");
person.setDate(new Date());
return person;
} @POST //post方法请求
@Path("/") //路径
public Person add(Person person) {
System.out.println(person.getDate());
return person;
} @PUT //put方法请求
@Path("/{id}/") //路径
public Person update(@PathParam("id") int id, Person person) {
System.out.println("put id : " + id);
System.out.println(person.getDate());
return person;
}
}
对于服务类,我们也可定义一个接口,在接口里面写annotation,再定义一个实现类,实现类之完成具体业务逻辑。这样也是可以的。
服务器启动类Server:
package com.cxf.jaxrs; import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; public class Server {
public static void main(String[] args) { JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean();
factoryBean.setAddress("http://localhost:9000/myservice"); factoryBean.setResourceClasses(MyService.class);
factoryBean.setResourceProvider(MyService.class,
new SingletonResourceProvider(new MyService()));
factoryBean.getInInterceptors().add(new LoggingInInterceptor());
factoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
factoryBean.create();
}
}
2、客户端
对于客户端访问,使用apache的httpclient进行请求。cxf的lib目录总已经有httpclient jar包,这里可以直接使用。
访问代码如下:
package com.cxf.jaxrs; import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element; public class Client { public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); public static void main(String[] args) throws Exception { System.out.println("===========================get by url =================================");
String getResult = get("http://localhost:9000/myservice/person/1");
System.out.println(getResult); System.out.println("===========================get===================================");
String getsResult = get("http://localhost:9000/myservice/person");
System.out.println(getsResult); System.out.println("===========================delete===================================");
String deleteResult = delete("http://localhost:9000/myservice/person/1");
System.out.println(deleteResult); System.out.println("===========================post=================================");
Person person = new Person();
person.setId(3435);
person.setName("lisi");
person.setDate(new Date()); Document document = coverPersonToDocument(person); String data = coverDocumentToString(document); System.out.println("request data: ");
System.out.println(data); String postResult = post("http://localhost:9000/myservice/person", data);
System.out.println("response data: ");
System.out.println(postResult); System.out.println("===========================put===================================");
Person person2 = new Person();
person2.setId(3435);
person2.setName("lisi");
person2.setDate(new Date()); document = coverPersonToDocument(person); data = coverDocumentToString(document); System.out.println("request data: "); String putResult = put("http://localhost:9000/myservice/person/1", data);
System.out.println("response data: ");
System.out.println(putResult); } /**
* 发送get 方法请求,并返回结果
* @param url
* @return
* @throws IOException
* @throws ParserConfigurationException
*/
private static String get(String url) throws IOException,
ParserConfigurationException {
HttpGet get = new HttpGet(url);
get.setHeader("Accept", "application/json");//接受json数据返回类型
CloseableHttpClient client = HttpClients.createDefault();
String responseContent = null;
CloseableHttpResponse response = null;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();//响应体
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//响应状态码
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} return responseContent;
} /**
* 发送delete 方法请求,并返回结果
* @param url
* @return
* @throws IOException
* @throws ParserConfigurationException
*/
private static String delete(String url) throws IOException,
ParserConfigurationException {
HttpDelete delete = new HttpDelete(url);
CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse response = null;
String responseContent = null;
try {
response = client.execute(delete);
HttpEntity entity = response.getEntity();//响应体
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//响应状态码
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
}
return responseContent;
} /**
* 发送post 方法请求,并返回结果
* @param url
* @param data
* @return
* @throws IOException
* @throws ParserConfigurationException
*/
private static String post(String url, String data) throws IOException,
ParserConfigurationException {
HttpPost post = new HttpPost(url); StringEntity myEntity = new StringEntity(data,
ContentType.APPLICATION_XML);//请求体数据,xml类型
post.setEntity(myEntity); CloseableHttpClient client = HttpClients.createDefault();
String responseContent = null;
CloseableHttpResponse response = null;
try {
response = client.execute(post);
HttpEntity entity = response.getEntity();//响应体
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//响应状态码
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
}
return responseContent;
} /**
* 发送put 方法请求,并返回结果
* @param url
* @param data
* @return
* @throws ParserConfigurationException
* @throws IOException
*/
private static String put(String url, String data)
throws ParserConfigurationException, IOException {
HttpPut put = new HttpPut(url);
StringEntity myEntity = new StringEntity(data,
ContentType.APPLICATION_XML);
put.setEntity(myEntity);
put.setHeader("Accept", "application/json");//接受json数据返回类型
CloseableHttpClient client = HttpClients.createDefault();
String responseContent = null;
CloseableHttpResponse response = null;
try {
response = client.execute(put);
HttpEntity entity = response.getEntity();//响应体
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {//响应状态码
responseContent = EntityUtils.toString(entity, "UTF-8");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
}
return responseContent;
} /**
* 使用对象构造xml文档对象,并返回
* @param person
* @return
* @throws ParserConfigurationException
*/
private static Document coverPersonToDocument(Person person)
throws ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element root = document.createElement("person");
Element node = document.createElement("id");
node.setTextContent(String.valueOf(person.getId())); Element node2 = document.createElement("name");
node2.setTextContent(person.getName()); Element node3 = document.createElement("date");
node3.setTextContent(format.format(person.getDate())); root.appendChild(node);
root.appendChild(node2);
root.appendChild(node3); document.appendChild(root);
return document;
} /**
* 将xml文档对象转换成String,并返回
* @param document
* @return
* @throws TransformerFactoryConfigurationError
*/
private static String coverDocumentToString(Document document)
throws TransformerFactoryConfigurationError {
StreamResult strResult = new StreamResult(new StringWriter());
TransformerFactory tfac = TransformerFactory.newInstance();
try {
javax.xml.transform.Transformer t = tfac.newTransformer();
t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty(OutputKeys.METHOD, "xml"); // xml, html,
t.transform(new DOMSource(document.getDocumentElement()), strResult);
} catch (Exception e) {
System.err.println("XML.toString(Document): " + e);
}
String data = strResult.getWriter().toString();
return data;
}
}
请求的结果如下: