转自:https://www.cnblogs.com/zjm701/p/6845813.html原文更清晰

本文介绍使用CXF实现基于Rest方式的WebService(CXF的版本是3.0.0)

一. 前言

Java有三种WebService规范:Jax-WS,Jax-RS,Jaxm

1. Jax-WS(Java Api for XML-Based WebService):实现Soap协议(Simple Object Access Protocol)(用的也不多了)
2. Jax-RS(Java Api for Resource-Based WebService):实现Rest方式(Representational State Transfer)(推荐)
3. Jaxm支持文件传输,暴露更多底层细节(不推荐)

二. 引入依赖

<!-- Jax-RS前端控制模块,处理服务业务的请求 -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-frontend-jaxrs</artifactId>
  <version>3.0.0</version>
</dependency>

<!-- Jax-RS客户端,用到WebClient等客户端代码调用类时需引入 -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-rs-client</artifactId>
  <version>3.0.0</version>
</dependency>

<!-- Json格式自动转换Provider,Jackson好用一些 -->
<!-- 也可以引入CXF自带的cxf-rt-rs-extension-providers(以及它默认使用jettison)-->
<!-- 也可以不使用Provider,直接使用CXF默认的Response.ResponseBuilder生成Response并返回,格式需要自己转换,例如使用Gson -->
<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.4.1</version>
</dependency>

<!-- 数据传输模块(与Soap一样) -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-transports-http</artifactId>
  <version>3.0.0</version>
</dependency>

<!-- 引入内置的Jetty,如在Tomcat中发布服务可以不引入(与Soap一样)  -->
<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-transports-http-jetty</artifactId>
  <version>3.0.0</version>
</dependency>

三. 编写SEI(Service Endpoint Interface)

1. 接口

import javax.ws.rs.core.Response;

//Produces & Consumes既可以加在Class上,也可以加在Method上,Method上的优先
@Path("/hello")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public interface HelloWorld {

  //Response是CXF默认的返回对象,实际数据可以封装在里面,如果使用WebClient等客户端测试类时,推荐返回Response 
  @GET
  @Path(value = "/resp")
  public Response sayHelloResponse();

  @GET
  @Path(value = "/string/{name}")
  public Result sayHelloString(@PathParam("name") String name);

  //Result、User都是POJO,代码略,需要使用某种第三方*JsonProvider,这样普通对象和Json格式可以自动互相转换  
  @POST
  @Path(value = "/user")
  public Result sayHelloUser(User user);

}

2. 实现类

public class HelloWorldImpl implements HelloWorld {

  // 使用Response.ResponseBuilder生成Response,格式需要自己转换,例如使用Gson
  @Override
  public Response sayHelloResponse() {
    Response.ResponseBuilder rb = Response.status(Status.OK);
    return rb.entity("Hello").build();
  }

  @Override
  public Result sayHelloString(String name) {
    return new Result("Hello, (String) " + name);
  }

  @Override
  public Result sayHelloUser(User user) {
    return new Result(new User("Rest_" + user.getName()));
  }

}

四. 发布服务

1. 发布方式一:使用默认的Jetty时,使用CXF提供的JAXRSServerFactoryBean(与Soap类似)

// 1). 服务端工厂类
JAXRSServerFactoryBean server = new JAXRSServerFactoryBean();

// 2). 设置了二个属性
server.setAddress("http://localhost:8088/testcxf/cxf/rest");
server.setServiceBean(new HelloWorldImpl());

// 3). 添加 Provider,用于支持自动解析各种数据格式、如Json
List<Object> providerList = new ArrayList<Object>();
providerList.add(new JacksonJsonProvider());
server.setProviders(providerList);

// 添加输入&输出日志(可选)
server.getInInterceptors().add(new LoggingInInterceptor());
server.getOutInterceptors().add(new LoggingOutInterceptor());

// 4). 创建并发布服务,会发起一个http服务,默认使用Jetty
server.create();

(http://localhost:8088/testcxf/cxf/rest/hello/string/Jimmy)

2. 发布方式二:在Web应用中,使用CXFNonSpringServlet发布(实际是显式调用了发布方式一

a. 在web.xml中添加CXFNonSpringServlet的实现类(与Soap一样)

<servlet>
  <servlet-name>CXFNonSpring</servlet-name>
  <servlet-class>net.jmystudio.servlet.WebServiceNonSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>CXFNonSpring</servlet-name>
  <url-pattern>/cxfns/*</url-pattern>
</servlet-mapping>

b. 实现WebServiceNonSpringServlet类(与Soap类似)

import org.apache.cxf.transport.servlet.CXFNonSpringServlet;

public class WebServiceNonSpringServlet extends CXFNonSpringServlet {

  @Override
  protected void loadBus(ServletConfig servletConfig) {
    super.loadBus(servletConfig);

    //使用JAXRSServerFactoryBean,代码类似发布方式一,此处简略

    // 1). 服务端工厂类
    JAXRSServerFactoryBean server = new JAXRSServerFactoryBean();

    // 2). 设置了两个属性 
    ......

    // 3). 创建并发布服务
    server.create();
  }

}

(http://localhost:8090/testcxf/cxfns/rest/hello/string/Jimmy)(应用包名是testcxf)

3. 发布方式三:在Web应用中,整合Spring+CXFServlet发布(实际是隐式调用了发布方式一(最常用)

a. 需要引入Spring相关的Jar包(与Soap一样)

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.1.6.RELEASE</version>
</dependency>

b. 在web.xml中添加Spring配置和CXFServlet(与Soap一样)

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:spring*.xml</param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
  <servlet-name>CXF</servlet-name>
  <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>CXF</servlet-name>
  <url-pattern>/cxf/*</url-pattern>
</servlet-mapping>

c. 添加关于cxf的spring配置文件(例spring-cfx-rest.xml)(与Soap类似)

<!-- 初始化cxf servlet -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<!-- 日志拦截器bean -->
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>

<!-- 发布方式1:使用JAXRSServerFactoryBean-->
<jaxrs:server address="/rest">
  <jaxrs:serviceBeans>
    <ref bean="helloWorldService" />
  </jaxrs:serviceBeans>
  <!-- Provider -->
  <jaxrs:providers>
    <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
  </jaxrs:providers>
  <!-- 输入日志拦截器 -->
  <jaxrs:inInterceptors>
    <ref bean="loggingInInterceptor"/>
  </jaxrs:inInterceptors>
  <!-- 输出日志拦截器 -->
  <jaxrs:outInterceptors>
    <ref bean="loggingOutInterceptor" />
  </jaxrs:outInterceptors>
</jaxrs:server>

<bean id="helloWorldService" class="net.jmystudio.cxf.rest.HelloWorldImpl" />

(http://localhost:8090/testcxf/cxf/rest/hello/string/Jimmy) (应用包名是testcxf)

五. 调用方式

无论使用哪种发布方式,发布成功后,都可以在火狐RestCilent的调试插件里调试,均可看到该WebService的接口定义的返回内容

例如 http://localhost:8088/testcxf/cxf/rest/hello/string/Jimmy

代码调用主要有3种方式

1. 调用方式一:使用JAXRSClientFactory获得静态的代理Client显式依赖WebService接口,需要引入服务提供方提供的jar包)(JAX-RS 1.0,已过时,不推荐)(与Soap类似)

HelloWorld staticClient = JAXRSClientFactory.create("http://localhost:8088/testcxf/cxf/rest", HelloWorld.class);
Response resp1 = staticClient.sayHelloResponse();
System.out.println(resp1.getMetadata());
System.out.println(resp1.readEntity(String.class));

2. 调用方式二:使用ClientBuilder、WebTarget

WebTarget webTarget = ClientBuilder.newClient().target("http://localhost:8088/testcxf/cxf/rest").path("/hello/string").path("/Tony");
Response resp2 = webTarget.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).get();
System.out.println(resp2.getMetadata());
System.out.println(resp2.readEntity(String.class));

3. 调用方式三:使用WebClient(推荐)

WebClient webClient = WebClient.create("http://localhost:8088/testcxf/cxf/rest").path("/hello/string").path("/Kevin");
Response resp3 = webClient.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).get();
System.out.println(resp3.getMetadata());
System.out.println(resp3.readEntity(String.class));

4. 其它调用方式:使用HttpClient或HttpURLConnection等连接,与常规的URL获得数据的方式一致,详情略。

使用CXF实现基于Rest方式的WebService(转)的更多相关文章

  1. 使用CXF实现基于Rest方式的WebService

    本文介绍使用CXF实现基于Rest方式的WebService(CXF的版本是3.0.0) 一. 前言 Java有三种WebService规范:Jax-WS,Jax-RS,Jaxm 1. Jax-WS( ...

  2. 使用CXF实现基于Soap协议的WebService

    本文介绍使用CXF实现基于Soap协议的WebService(CXF的版本是3.0.0) 一. 前言 Java有三种WebService规范:Jax-WS,Jax-RS,Jaxm 1. Jax-WS( ...

  3. java实现REST方式的webService

    一. 简介 WebService有两种方式,一是SOAP方式,二是REST方式.SOAP是基于XML的交互,WSDL也是一个XML文档, 可以使用WSDL作为SOAP的描述文件:REST是基于HTTP ...

  4. 使用CXF与Spring集成实现RESTFul WebService

    以下引用与网络中!!!     一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...

  5. 浅析基于AXIS框架的WebService

    一.写在前面 之前做项目用到了基于Axis的WebService,为了更进一步的理解和记忆,在这里通过代码实践和源码分析来完整的做一遍Axis的WebService以及对应的客户端调用实践,并和其它的 ...

  6. FineReport中以jws方式调用WebService数据源方案

    在使用WebService作为项目的数据源时,希望报表中也是直接调用这个WebService数据源,而不是定义数据连接调用对应的数据库表,这样要怎么实现呢? 在程序中访问WebService应用服务, ...

  7. 使用ajax和urlconnection方式调用webservice服务

    <html> <head> <title>使用ajax方式调用webservice服务</title> <script> var xhr = ...

  8. 【ALB技术笔记】基于多线程方式的串行通信接口数据接收案例

    基于多线程方式的串行通信接口数据接收案例 广东职业技术技术学院  欧浩源 1.案例背景 在本博客的<[CC2530入门教程-06]CC2530的ADC工作原理与应用>中实现了电压数据采集的 ...

  9. FTP方式发布webservice

    以前我发布webservice的步骤是:在  C:\inetpub\wwwroot\路径下发布webservice,然后再在IIS中添加网站并制定路径,这样每次发布了webservice后,需要把发布 ...

随机推荐

  1. [5] 柱台(Cylinder)图形的生成算法

    顶点数据的生成 bool YfBuildCylinderVertices ( Yreal topRadius, Yreal bottomRadius, Yreal height, Yuint slic ...

  2. mini-parser

    https://leetcode.com/problems/mini-parser/ /** * // This is the interface that allows for creating n ...

  3. Informatica 常用组件Filter之一 概述

    转换类型:已连接.主动 过滤器转换允许您过滤映射中的行.通过过滤器转换从源转换传递所有的行,然后为转换输入过滤条件.所有过滤器转换中的端口均为输入/输出端口,只有符合条件的行才能通过过滤器转换. 在某 ...

  4. HDU2669 Romantic 扩展欧几里德 对我来说有陷阱

    这道题对我来说有陷阱虽说是赤果果的扩展欧几里德,看样子基本攻还是不够哈,基本功夫一定要好,准备每天上那种洗脑课时分  多看看数论书,弥补一下 自己 狗一样的基础, 这道题用到了一个性质: 对于不定整数 ...

  5. RequireJS 参考文章

    入门: http://www.cnblogs.com/snandy/archive/2012/05/22/2513652.html http://www.cnblogs.com/snandy/arch ...

  6. iOS开发-Xcode入门ObjC程序

    元旦三天假跟妹子冷战一天半,剩下的半天觉得无聊,可以写点东西,折腾了下xCode 6.1,虽然iPhone6比较丑,但是不影响IOS在高端机上面的地位,ObjC是扩充C的面向对象编程语言.主要使用于M ...

  7. Linked List Cycle leetcode java (链表检测环)

    题目: Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without usin ...

  8. .Net应用程序打包部署总结

    编译源代码并完成测试以后,开发过程其实并没有结束.在这个极端,需要把应用程序提供给用户.无论是ASP.NET应用程序,客户端应用程序还是 Compact Framework构建的应用程序,开发出来的软 ...

  9. IOS程式语法之block的使用掌握

    在现阶IOBlock 是iOS在4.0之后新增的程式语法,严格来说block的概念并不算是基础程式设计的范围,对初学者来说也不是很容易了解,但是在iOS SDK 4.0之后,block几乎出现在所有新 ...

  10. IOS把图片做成圆形效果

    利用CAShapeLayer能够制作出随意的几何图形,把它作为UIImageView的遮罩,达到把图片做成圆形效果. imgView = [[UIImageView alloc]initWithFra ...