cxf开发Restful Web Services

简介: 一、restful web services   rest全称是Representation State Transfer(表述性状态转移)。它是一种软件架构风格,只是提供了一组设计原则和约束条件。在restful web services的设计原则中,所有的事物都应该拥有唯一的URI,通过对URI的请求访问,完成相应的操作。

一、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;
    }
}

   请求的结果如下:

目录
相关文章
|
10月前
|
XML JSON API
Understanding RESTful API and Web Services: Key Differences and Use Cases
在现代软件开发中,RESTful API和Web服务均用于实现系统间通信,但各有特点。RESTful API遵循REST原则,主要使用HTTP/HTTPS协议,数据格式多为JSON或XML,适用于无状态通信;而Web服务包括SOAP和REST,常用于基于网络的API,采用标准化方法如WSDL或OpenAPI。理解两者区别有助于选择适合应用需求的解决方案,构建高效、可扩展的应用程序。
|
缓存 前端开发 API
深入浅出:后端开发中的RESTful API设计原则
【10月更文挑战第43天】在数字化浪潮中,后端开发如同搭建梦想的脚手架,而RESTful API则是连接梦想与现实的桥梁。本文将带你领略API设计的哲学之美,探索如何通过简洁明了的设计,提升开发效率与用户体验。从资源定位到接口约束,从状态转换到性能优化,我们将一步步构建高效、易用、可维护的后端服务。无论你是初涉后端的新手,还是寻求进阶的开发者,这篇文章都将为你的开发之路提供指引。让我们一起走进RESTful API的世界,解锁后端开发的新篇章。
|
JSON API 数据格式
探索后端开发:从零构建简易RESTful API
在数字时代的浪潮中,后端开发如同搭建一座桥梁,连接着用户界面与数据世界。本文将引导读者步入后端开发的殿堂,通过构建一个简易的RESTful API,揭示其背后的逻辑与魅力。我们将从基础概念出发,逐步深入到实际操作,不仅分享代码示例,更探讨如何思考和解决问题,让每一位读者都能在后端开发的道路上迈出坚实的一步。
|
JSON API 开发者
构建高效API:后端开发中的RESTful最佳实践####
在数字化时代,API作为不同系统间通信的桥梁,其重要性日益凸显。本文将深入探讨RESTful API的设计原则与最佳实践,通过实际案例分析,揭示如何构建高效、可维护且易于使用的API接口,助力后端开发者提升项目质量与用户体验。 ####
|
JSON 缓存 API
探索后端开发中的RESTful API设计原则
【10月更文挑战第41天】在后端开发的广阔天地中,API的设计如同绘制一幅精细的地图,指引着数据的流向和前端的交互。本文将带你走进RESTful API的世界,一起探索如何用简洁高效的设计原则来构建一个清晰、可维护且易于理解的API结构。我们将从RESTful API的基础概念出发,通过实际案例分析,揭示如何在实践中应用这些设计原则,并讨论如何在复杂的业务逻辑中保持API的简洁性和一致性。
|
XML JSON API
【PHP开发专栏】PHP RESTful API设计与开发
随着互联网技术的发展,前后端分离成为Web开发的主流模式。本文介绍RESTful API的基本概念、设计原则及在PHP中的实现方法。RESTful API是一种轻量级、无状态的接口设计风格,通过HTTP方法(GET、POST、PUT、DELETE)操作资源,使用JSON或XML格式传输数据。在PHP中,通过定义路由、创建控制器、处理HTTP请求和响应等步骤实现RESTful API,并强调了安全性的重要性。
275 2
|
安全 测试技术 API
构建高效RESTful API:后端开发的艺术与实践####
在现代软件开发的浩瀚星空中,RESTful API如同一座桥梁,连接着前端世界的绚丽多彩与后端逻辑的深邃复杂。本文旨在探讨如何精心打造一款既高效又易于维护的RESTful API,通过深入浅出的方式,剖析其设计原则、实现技巧及最佳实践,为后端开发者提供一份实用的指南。我们不深入晦涩的理论,只聚焦于那些能够即刻提升API品质与开发效率的关键点,让你的API在众多服务中脱颖而出。 ####
152 0
|
3月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
323 4
|
7月前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
7月前
|
JavaScript 前端开发 API
鸿蒙5开发宝藏案例分享---Web加载时延优化解析
本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。