cxf - WebService的介绍和使用

WebService的介绍和使用

概念:Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。分为SOAP和restfull风格

XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。

Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。

UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。在用户能够调用Web服务之前,必须确定这个服务内包含哪些商务方法,找到被调用的接口定义,还要在服务端来编制软件,UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

调用原理

在这里插入图片描述

实现一个完整的Web服务包括以下步骤:

◆ Web服务提供者设计实现Web服务,并将调试正确后的Web服务通过Web服务中介者发布,并在UDDI注册中心注册; (发布)

◆ Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务; (发现)

◆ Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读;(发现)

◆ 利用从Web服务中介者返回的描述信息生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用;(绑定)

◆ Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。(绑定)

SOAT风格
Helloword

首先下载apache-cxf-3.3.1,里面有jar包

新建一个java web工程,将apache-cxf-3.3.1的lib包的jar拷贝到lib文件夹下

新建一个HelloWord.java的接口和实现它 的HelloWordImpl.java,在接口上注解@WebService

@WebService
public interface HelloWord {
     public String sayHello(String name);
}

public class HelloWordImpl implements HelloWord {
    @Override
    public String sayHello(String name) {
        return "name="+name+"------------age=21";
    }
}

新建一个MainService.java 来发布服务,运行服务,会发现它不会停止,一直在运行

public class MainService {
    public static void main(String[] args) {
        JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
        //发布的地址和服务名
        jaxWsServerFactoryBean.setAddress("http://192.168.43.53:8888/helloword");
        jaxWsServerFactoryBean.setServiceClass(HelloWordImpl.class);
        Server server = jaxWsServerFactoryBean.create();
        server.start();
        System.out.println("======开始服务--------->>>>>>>>");
    }
}

打开游览器输入:http://192.168.43.53:8888/helloword?wsdl可以看到如下,说明服务启动正确

新建一个Client,来调用服务,运行程序,输出

public class Client {
    public static void main(String[] args) {
        /*代理*/
        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
        /*地址*/
        jaxWsProxyFactoryBean.setAddress("http://192.168.43.53:8888/helloword");
        /*传入接口*/
        jaxWsProxyFactoryBean.setServiceClass(HelloWord.class);
        HelloWord helloword = (HelloWord) jaxWsProxyFactoryBean.create();
        String str = helloword.sayHello("chenlong");
        System.out.println(str);
    }
}

一个简单的HelloWord就写好了。这是我们自己手动写代码来调用的,如果不写代理类,怎么实现呢?借助JAX-WS工具。

首先到apache-cxf-3.3.1\bin这个目录下,打开cmd,输入wsdl2java <http://192.168.43.53:8888/helloword?wsdl 然后会发现,该目录下回生成一些代码,将这些类直接复制到项目的一个包中(或者达成jar包放在lib下也可以),新建client2.java

public class Client2 {
    public static void main(String[] args) {
        HelloWord helloWord  = new HelloWordImpl();
        String chen = helloWord.sayHello("chen");
        System.out.println(chen);
    }
}

直接这样就可以了。

Restful Web Services (JAX-RS)

•JAX-RS= Java API For Restful Web Services

• JAX-RS是JAVA EE6 引入的一个新规范。 是一个Java 编程语言的应用程序接口,支持按照表述性状态转移 (REST)架构风格创建Web服务。

• JAX-RS使用了Java标注来简化Web服务的客户端和服务端的开发和部署。

• 除了JAX-RS方式发布Restful风格的Webservice,SpringMVC也可以发布Restful风格的Webservice

JAX-RS提供了一些标注将一个资源类,一个POJO Java类,封装为Web资源。包括:

@Path,标注资源类或者方法的相对路径 @GET,@PUT,@POST,@DELETE,标注方法是HTTP请求的类型。

@Produces,标注返回的MIME媒体类型 @Consumes,标注可接受请求的MIME媒体类型

@PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam,分别标注方法的参数来自于HTTP请求的不同位置,例如:

@PathParam来自于URL的路径,@QueryParam来自于URL的查询参数,

@HeaderParam来自于HTTP请求的头信息,@CookieParam来自于HTTP请求的Cookie。

基于JAX-RS实现的框架有Jersey,RESTEasy等,这两个框架创建的应用可以很方便地部署到Servlet 容器中

简单实例:

创建一个web工程,添加jar包,要实现的服务是根据ID查用户,添加一个用户的功能

首先创建Customer.java

@XmlRootElement
public class Customer {
    @FormParam("id")
    private String id;
    @FormParam("name")
    private String name;
    @FormParam("age")
    private int age;
    public Customer() {}
    public Customer(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

@XmlRootElement,可以将customer转为xml

创建一个CustomerService 接口

@WebService
public interface CustomerService {
    Customer getCustomerById(String id);
    String addCustomer(Customer customer);
}

实现接口,一个get方法,一个post方法

@Path("/crm")
public class CustomerServiceImpl implements CustomerService {
    @Override
    @GET
    @Path("/customer/{id}")
    @Produces("application/json")//以什么样的方式返回数据xml,json标注返回的MIME媒体类型
    public Customer getCustomerById(@PathParam("id") String id) {
        if(id.equals("1")){
            return  new Customer("1","zhangsan",12);
        }
        if(id.equals("2")){
            return  new Customer("2","lisi",13);
        }
        return new Customer("3","chenlong",11);
    }
    @Override
    @POST
    @Path("/customer")
    @Consumes("application/x-www-form-urlencoded")
    public String addCustomer(@BeanParam Customer customer) {
        System.out.println(customer);
        return "success:"+customer.toString();
    }}

手动发布服务

public class Main {
    public static void main(String[] args) {
        JAXRSServerFactoryBean jaxrsServerFactoryBean = new JAXRSServerFactoryBean();
        //customer为自己写的服务名,客户端用这个地址加方法就可以用了
        jaxrsServerFactoryBean.setAddress("http://localhost:8888/customer");
        jaxrsServerFactoryBean.setResourceClasses(CustomerServiceImpl.class);
        jaxrsServerFactoryBean.create().start();
        System.out.println("开始服务------->>>>>>>");
    }
}

服务启动之后,在游览器输入:http://localhost:8888/customer/crm/customer/3,可以看到json数据

使用客户端调用,get调用

public class Client {
    public static void main(String[] args) throws IOException {
        //1. 创建 HttpClient 的实例
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();

        //2. 创建某种连接方法的实例
        HttpGet httpget = new HttpGet("http://localhost:8888/customer/crm/customer/3");

        //3. 调用第一步中创建好的实例的execute方法来执行第二步中创建好的链接类实例
        HttpResponse response = httpclient.execute(httpget);

        //4. 读response获取HttpEntity
        HttpEntity entity = response.getEntity();

        //5. 对得到后的内容进行处理
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            String result = EntityUtils.toString(entity, "UTF-8");
            System.out.println(result);
        } else {
            String result = EntityUtils.toString(entity, "UTF-8");
            System.err.println(result);
        }
        //6. 释放连接。无论执行方法是否成功,都必须释放连接
        EntityUtils.consume(entity);
        httpclient.close();
    }
}

使用客户端post请求

public class PostClient {
    public static void main(String[] args) throws Exception {
        /*创建HTTPclient的实例*/
        CloseableHttpClient closeableHttpClient = HttpClientBuilder.create().build();
        /*创建链接的方式*/
        HttpPost httpPost = new HttpPost("http://localhost:8888/customer/crm/customer");
        /*传递参数*/
        List<BasicNameValuePair> list= new ArrayList<>();
        list.add(new BasicNameValuePair("id","4"));
        list.add(new BasicNameValuePair("name","陈龙"));
        list.add(new BasicNameValuePair("age","18"));
        HttpEntity httpEntity = new UrlEncodedFormEntity(list,"utf-8");
        httpPost.setEntity(httpEntity);
        /*调用*/
        HttpResponse execute = closeableHttpClient.execute(httpPost);
        // 读response获取HttpEntity
        HttpEntity entity = execute.getEntity();
        if(execute.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
            String s = EntityUtils.toString(entity, "Utf-8");
            System.out.println(s);
        }else {
            String s = EntityUtils.toString(entity, "Utf-8");
            System.out.println(s);
        }
        //6. 释放连接。无论执行方法是否成功,都必须释放连接
        EntityUtils.consume(entity);
        closeableHttpClient.close();
    }
}

运行,可在

客户端控制台下输出:success:Customer{id=‘4’, name=‘陈龙’, age=18}

在服务器控制台输出:Customer{id=‘4’, name=‘陈龙’, age=18}

spring + cxf 的整合

工程的结构

在这里插入图片描述
创建一个web maven工程,在web.xml加入代码

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

  <!-- CXF的Servlet -->
  <servlet>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 本系统的WebService路径必须以/ws/开头 -->
  <servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <url-pattern>/ws/*</url-pattern>
  </servlet-mapping>

将上述的Customer,和CustomerService以及实现类加入工程,以及helloword的服务加进来,在resource目录下新建application.xml

<?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-4.1.xsd
		http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
		http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">

<jaxws:endpoint id="helloword" implementor="ws.HelloWordImpl" address="/helloword"></jaxws:endpoint>

    <jaxrs:server id="customer" address="/customerService">
        <jaxrs:serviceBeans>
            <bean id="customerService" class="clong.service.impl.CustomerServiceImpl"></bean>
        </jaxrs:serviceBeans>
    </jaxrs:server>
</beans>

启动Tomcat,在游览器访问http://localhost:8080/ws/,可以看到你发布的服务

在这里插入图片描述

这时候用代码调用只需要改:HttpGet httpget = new HttpGet(“http://localhost:8080/ws/customerService/crm/customer/3”);就可以了,我这里不知道为什么掉用这个方法,获取不到json,显示

No message body writer has been found for class clong.bean.Customer, ContentType: application/json

而将这个方法的 @Produces(“application/json”)改为 @Produces(“application/xml”),就可以显示xml数据,不知道哪里有问题,待完善

Post 请求一样的,将HttpPost httpPost = new HttpPost(“http://localhost:8080/ws/customerService/crm/customer”);修改就可以了。

大概的webservice就到这里了。以后有新需求,在添加!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值