使用Apache CXF开发RESTful服务

介绍

如您所知,有两种开发Web服务的方法

  1. 简单对象访问协议(SOAP)
  2. 代表性状态转移(REST)

在继续学习如何使用Apache CXF创建基于REST的Web服务之前,我们将了解什么是REST。 REST不是一项技术,当然也不是某种标准。 这只是一种架构风格,它限制了如何以某种方式编写Web服务。 这种样式是由某个Roy Fielding在2000年定义的(您猜对了,是的,他是HTTP的架构师之一)。REST体系结构的主要主角是资源 ,可以由统一资源标识符或URI 。 在任何给定时间点资源的状态由文件表示,称为资源的表示 。 客户端可以通过将表示形式与请求一起传送来更新资源状态。 现在,新的表示形式将与响应一起返回给客户端。 该表示形式包含资源接受的html,xml,JSON等格式的信息。 遵守REST体系结构规则的资源称为RESTfull资源,遵守此规则的Web服务称为RESTfull Web服务。

创建一个项目以包含您的Web服务

我通常使用maven Strut2入门原型在struts2 + spring中进行Web开发,以创建我的Web项目。 要在我的项目中使用CXF,我将以下依赖项添加到我的POM中

<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-frontend-jaxws</artifactId>
	<version>${cxf.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-transports-http</artifactId>
	<version>${cxf.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-transports-http-jetty</artifactId>
	<version>${cxf.version}</version>
</dependency>

非maven用户可以在以下链接中找到要添加的依赖项的详细信息: http : //cxf.apache.org/docs/using-cxf-with-maven.html 。 可以从此处直接下载CXF: http : //cxf.apache.org/download.html

如何创建CXF RESTfull Web服务?

假设您想使用CXF创建RESTfull Web服务来管理个人书架中的书。 您通常需要在书架上执行以下操作

  1. 新增书籍
  2. 更新书籍信息
  3. 从书架上删除一本书
  4. 拿书
  5. 获取图书清单
  6. 按作者姓名获取图书清单

需要执行以下步骤来创建这样的服务

  1. 创建BookVO,BookList(值对象)以在请求和响应中作为表示形式传递。
  2. 将对象与请求和响应绑定。
  3. 创建服务实现类以接受请求并生成响应。
  4. 使用CXF容器注册您的Web服务。
  5. 在Web容器中部署服务。
  6. 创建客户端以调用服务上的方法。

获取本教程的源代码

我已经在SVN中提交了本教程的源文件。

注意:这两个都是ItelliJ maven项目,因此您可以将它们直接导入到intelliJ IDE或手动将文件复制到其他IDE

创建BookVO(值对象)以在请求和响应中作为表示形式传递。

BookVO类
package com.aranin.weblog4j.vo;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable;

@XmlRootElement(name="Book")
public class BookVO implements Serializable{

private long bookId;
private String bookName;
private String author;

public long getBookId() {
return bookId;
}

public void setBookId(long bucketId) {
this.bookId = bookId;
}

public String getBookName() {
return bookName;
}

public void setBookName(String bookName) {
this.bookName = bookName;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}
}
图书清单类
package com.aranin.weblog4j.vo;

import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;

@XmlRootElement(name="BookList")
public class BookList {
private List<BookVO> bookList;

public List<BookVO> getBookList() {
if(bookList == null){
bookList = new ArrayList<BookVO>();
}
return bookList;
}

public void setBookList(List<BookVO> bookList) {
this.bookList = bookList;
}
}

将数据对象(即BookVO)与请求和响应绑定

要将BookVO与请求或响应绑定,需要将其序列化为XML或JSON流。 序列化需要使用数据绑定组件之一来完成。 CXF使用JAXB作为默认数据绑定组件。 JaXB使用@XmlRootElement批注将数据对象映射到xml。 您可以在上面的代码中看到XmlRootElement批注的使用。

创建服务实现类以接受请求并生成响应

让我们看看CXF RestFull Web服务的外观。 我们将创建一个BookService类,该类将对BookSelf执行添加,更新,删除和获取操作。

BookService类别
package com.aranin.weblog4j.services.rest;

import com.aranin.weblog4j.hashdb.HashDB;
import com.aranin.weblog4j.vo.BookVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 3/13/13
 * Time: 3:58 PM
 * To change this template use File | Settings | File Templates.
 */
public class BookService {

protected final Logger log = LoggerFactory.getLogger(BookService.class);

    @POST
    @Path("/getbook/{name}")
    @Produces({"application/xml","application/json"})
    @Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})
    public Response getBucket(@PathParam("name") String name) {
        log.debug("name : " + name);
        BookVO bookVO = null;
        try {
            bookVO = HashDB.getBook(URLDecoder.decode(name, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }

        if(bookVO == null){
            return Response.status(Response.Status.BAD_REQUEST).build();
        }else{
            return Response.ok(bookVO).build();
        }
    }

    @POST
    @Path("/addbook")
    @Produces({"application/xml","application/json"})
    @Consumes({"application/xml","application/json","application/x-www-form-urlencoded"})
    public Response addBook(@FormParam("name") String bookName,
                            @FormParam("author") String author) {
        log.debug("inside addBook");
        BookVO bookVO = new BookVO();
        bookVO.setBookName(bookName);
        bookVO.setAuthor(author);
        HashDB.insertBook(bookVO);
        if(HashDB.getBook(bookName) == null){
            return Response.status(Response.Status.BAD_REQUEST).build();
        }else{
            return Response.ok(bookVO).build();
        }

    }
}

您可以在BookService类的getBook和addBook中看到两个方法。 它们是获取和添加书籍的服务方法。 其余的更新删除等方法可以用相同的方式编写。 现在,让我们看看各种注释和方法调用的含义。

  • @POST –表示服务仅接收POST请求。
  • @Path –这是Web服务的路径。 因此,可以使用以下URL <base_url> / bookservice / getbook / {name}进行获取,使用<base_url> / bookservice / addbook进行添加来调用Web服务。
  • @Produces –指示生成的响应的MIME类型。 在我们的例子中,它既是application / xml也是application / json。
  • @Consumes –指示此服务可以使用的请求的MIME类型。

使用CXF容器注册您的Web服务。

CXF的一件很酷的事情是,它使用基于Spring的配置来注册其Web服务端点,因此让我们在WEB-INF中创建beans.xml并在web.xml中配置CXF。 首先,我们需要连接beans.xml以通过spring容器加载。

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/beans.xml,/WEB-INF/applicationContext.xml</param-value>
</context-param>

其次,将注册CXFServlet加载到web.xml中。

<servlet>
<servlet-name>CXFServlet</servlet-name>
<display-name>CXF Servlet</display-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

现在打开bean.xml并注册bookservice端点。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs"
	xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://cxf.apache.org/jaxrs

http://cxf.apache.org/schemas/jaxrs.xsd

http://cxf.apache.org/jaxws

http://cxf.apache.org/schemas/jaxws.xsd">

	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<jaxws:endpoint
	  id="bookShelfService"
	  implementor="com.aranin.weblog4j.services.BookShelfServiceImpl"
	  address="/bookshelfservice" />

    <bean id="bookserviceclass" class="com.aranin.weblog4j.services.rest.BookService"/>

    <jaxrs:server id="bookservice" address="/bookservice">
        <jaxrs:serviceBeans>
        <ref bean="bookserviceclass" />
        </jaxrs:serviceBeans>
    </jaxrs:server>

</beans>

现在您的Web服务已准备就绪。 构建您的Web应用程序并将其部署在任何servlet容器中。

为您的Web服务创建客户端

可以通过多种方式创建客户端,我已经使用apache Http Components编写了客户端。 这些库可以在http://hc.apache.org/httpclient-3.x/中找到。

Maven用户可以使用以下命令拉动Http组件jar

<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.1.3</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.1.3</version>
<scope>compile</scope>
</dependency>

现在调用Web服务,我创建了一个名为DemoRestClient的util类。

package com.aranin.weblog4j.client;

import com.aranin.weblog4j.vo.BookVO;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

import java.net.URLEncoder;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 3/13/13
 * Time: 4:15 PM
 * To change this template use File | Settings | File Templates.
 */
public class DemoRestClient {
    public static void main(String[] args){
        DemoRestClient restClient = new DemoRestClient();
        try {
            //restClient.addBook("Naked Sun", "Issac Asimov");
            restClient.getBook("Naked Sun");
        } catch (Exception e) {
            e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
        }

    }

    public BookVO getBook(String bookName) throws Exception {

        String output = null;
        try{
            String url = "http://localhost:8080/weblog4jdemo/bookservice/getbook/";

            url = url + URLEncoder.encode(bookName, "UTF-8");

            HttpClient client = new HttpClient();
            PostMethod mPost = new PostMethod(url);
            client.executeMethod( mPost );
            Header mtHeader = new Header();
            mtHeader.setName("content-type");
            mtHeader.setValue("application/x-www-form-urlencoded");
            mtHeader.setName("accept");
            mtHeader.setValue("application/xml");
            mPost.addRequestHeader(mtHeader);
            client.executeMethod(mPost);
            output = mPost.getResponseBodyAsString( );
            mPost.releaseConnection( );
            System.out.println("out : " + output);
        }catch(Exception e){
            throw new Exception("Exception in retriving group page info : " + e);
        }
        return null;
    }

    public void addBook(String bookName, String author) throws Exception {

        String output = null;
        try{
            String url = "http://localhost:8080/weblog4jdemo/bookservice/addbook";
            HttpClient client = new HttpClient();
            PostMethod mPost = new PostMethod(url);
            mPost.addParameter("name", "Naked Sun");
            mPost.addParameter("author", "Issac Asimov");
            Header mtHeader = new Header();
            mtHeader.setName("content-type");
            mtHeader.setValue("application/x-www-form-urlencoded");
            mtHeader.setName("accept");
            mtHeader.setValue("application/xml");
            //mtHeader.setValue("application/json");
            mPost.addRequestHeader(mtHeader);
            client.executeMethod(mPost);
            output = mPost.getResponseBodyAsString( );
            mPost.releaseConnection( );
            System.out.println("output : " + output);
        }catch(Exception e){
        throw new Exception("Exception in adding bucket : " + e);
        }

    }

}

运行此客户端以查看Web服务的输出。 现在,它将发送xmloutput,因为响应接受标头为“ application / xml”。 您可以将其更改为application / json以获得json输出。

多数民众赞成。 这是使用apache CXF开发RestFull Web服务的非常基本的介绍,还有很多要探索的内容。 愉快的探索,直到那再见。 如果您阅读了此文章,请留下一些评论,以使我不断受到启发。

参考: Weblog4j博客上的JCG合作伙伴 Niraj Singh 使用Apache CXF开发RESTful服务

翻译自: https://www.javacodegeeks.com/2013/07/developing-restful-services-using-apache-cxf.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值