cxf开发Restful Web Services
一、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; } }
请求的结果如下: