博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot | CXF发布WebService服务和客户端调用WebService服务
阅读量:4181 次
发布时间:2019-05-26

本文共 9294 字,大约阅读时间需要 30 分钟。

一、引入maven依赖

org.apache.cxf
cxf-spring-boot-starter-jaxws
3.2.7

二、服务端

2.1、service接口类

package com.example.server;import com.example.entity.Book;import javax.jws.WebService;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2018/11/23 9:01 * @description V1.0  如要指定服务名称则接口和实现类的须一致@WebService(name="demo") */@WebServicepublic interface DemoService {    Book getBookById(int id);    String insert();}

2.2、实现类

package com.example.server;import com.example.entity.Book;import com.example.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import javax.jws.WebService;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2018/11/23 9:03 * @description V1.0  命名空间 默认为接口类所在包的逆序 * 如要指定服务名称则接口和实现类的须一致@WebService(name="demo") @WebService(endpointInterface = "com.example.server.DemoService",serviceName = "demo") */@WebService(endpointInterface = "com.example.server.DemoService")@Componentpublic class DemoServiceImpl implements DemoService {    @Autowired    BookService bookService;    @Override    public Book getBookById(int id) {        Book book = new Book();        book.setName("webservice测试");        book.setId(123);        book.setAuthor("小布");        return book;    }    @Override    public String insert() {        Book book = new Book();        book.setAuthor("小布");        book.setName("CXF webservice调用");        bookService.save(book);        return "插入成功";    }}

2.3、定义拦截器验证用户名和密码

package com.example.server.interceptor;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.w3c.dom.NodeList;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPHeader;import javax.xml.soap.SOAPMessage;/** * @author xiaobu * @date 2018/11/23 13:57 * @descprition   CXF定义拦截器用于用户验证 * @version 1.0 */public class AuthInterceptor extends AbstractPhaseInterceptor
{ private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class); private SAAJInInterceptor saa = new SAAJInInterceptor(); private static final String USER_NAME = "admin"; private static final String USER_PASSWORD = "1"; public AuthInterceptor() { super(Phase.PRE_PROTOCOL); getAfter().add(SAAJInInterceptor.class.getName()); } @Override public void handleMessage(SoapMessage message) throws Fault { SOAPMessage mess = message.getContent(SOAPMessage.class); if (mess == null) { saa.handleMessage(message); mess = message.getContent(SOAPMessage.class); } SOAPHeader head = null; try { head = mess.getSOAPHeader(); } catch (Exception e) { logger.error("getSOAPHeader error: {}",e.getMessage(),e); } if (head == null) { throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息")); } NodeList users = head.getElementsByTagName("username"); NodeList passwords = head.getElementsByTagName("password"); if (users.getLength() < 1) { throw new Fault(new IllegalArgumentException("找不到用户信息")); } if (passwords.getLength() < 1) { throw new Fault(new IllegalArgumentException("找不到密码信息")); } String userName = users.item(0).getTextContent().trim(); String password = passwords.item(0).getTextContent().trim(); if(USER_NAME.equals(userName) && USER_PASSWORD.equals(password)){ logger.debug("admin auth success"); } else { SOAPException soapExc = new SOAPException("认证错误"); logger.debug("admin auth failed"); throw new Fault(soapExc); } }}

2.4、CXF服务端配置

package com.example.server.interceptor;import com.example.server.DemoService;import org.apache.cxf.Bus;import org.apache.cxf.jaxws.EndpointImpl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.xml.ws.Endpoint;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2018/11/23 9:16 * @description V1.0 CXF配置 */@Configurationpublic class CxfConfig {    @Autowired    private Bus bus;    @Autowired    DemoService demoService;    /**     * @author xiaobu     * @date 2018/11/23 14:38     * @return javax.xml.ws.Endpoint     * @descprition  EndpointImpl 引入的包为  org.apache.cxf.jaxws.EndpointImpl;      * @version 1.0     */    @Bean    public Endpoint endpoint() {        EndpointImpl endpoint = new EndpointImpl(bus, demoService);        endpoint.publish("/demoService");        endpoint.getInInterceptors().add(new AuthInterceptor());        return endpoint;    }}

2.5、访问效果如下(默认的路径 http://主机地址:端口/services):

三、客户端配置

3.1、在头部设置账户、密码

package com.example.server.interceptor;import org.apache.cxf.binding.soap.SoapMessage;import org.apache.cxf.headers.Header;import org.apache.cxf.helpers.DOMUtils;import org.apache.cxf.interceptor.Fault;import org.apache.cxf.phase.AbstractPhaseInterceptor;import org.apache.cxf.phase.Phase;import org.w3c.dom.Document;import org.w3c.dom.Element;import javax.xml.namespace.QName;import java.util.List;/** * @author xiaobu * @date 2018/11/23 14:11 * @return * @descprition  客户端在头部设置账户、密码 * @version 1.0 */public class ClientLoginInterceptor  extends AbstractPhaseInterceptor
{ private String username; private String password; public ClientLoginInterceptor(String username, String password) { super(Phase.PREPARE_SEND); this.username = username; this.password = password; } @Override public void handleMessage(SoapMessage soap) throws Fault { List
headers = soap.getHeaders(); Document doc = DOMUtils.createDocument(); Element auth = doc.createElement("authority"); Element username = doc.createElement("username"); Element password = doc.createElement("password"); username.setTextContent(this.username); password.setTextContent(this.password); auth.appendChild(username); auth.appendChild(password); headers.add(0, new Header(new QName("tiamaes"),auth)); }}

3.2、动态调用

package com.example.cxfClient;import com.example.entity.Book;import com.example.server.interceptor.ClientLoginInterceptor;import com.example.util.EntityUtils;import org.apache.cxf.endpoint.Client;import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;import java.util.Arrays;import java.util.List;import java.util.Map;/** * @author xiaobu * @version JDK1.8.0_171 * @date on  2018/11/23 10:45 * @description V1.0 webservice客户端调用 */public class TestDemo {    private static final String WSDL_URL = "http://localhost:8080/services/demoService?wsdl";    private static final String USER_NAME = "admin";    private static final String PASS_WORD = "1";    private static JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();    private static Client client = dcf.createClient(WSDL_URL);    public static void main(String[] args) {        method1();    }    /**     * @author xiaobu     * @date 2018/11/23 14:29     * @param     * @return void     * @descprition  //动态调用     * @version 1.0     */    @SuppressWarnings("all")    private static void method1() {        // 需要密码的情况需要加上用户名和密码         client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,PASS_WORD));        Object[] objects = new Object[0];        try {            // invoke("方法名",参数1,参数2,参数3....);            objects = client.invoke("getBookById", 1);            List list = Arrays.asList(objects);            //这里的Book对象            List
books = EntityUtils.copyList(list,Book.class,new String[]{}); System.out.println("books=======>>"+books); Book book = EntityUtils.convertBean(objects[0], Book.class); System.out.println("book======>>"+book); Book book2 = EntityUtils.copy(objects[0], Book.class, new String[]{}); System.out.println("book2======>>"+book2); Map map = EntityUtils.objectToMap(book); System.out.println("Map:" + map); Book book1 = EntityUtils.mapToObject(map,Book.class); System.out.println("book1======>>"+book1); } catch (java.lang.Exception e) { e.printStackTrace(); } }}

客户端生成代理调用的省略。。。。

 


项目用到shiro的话,需要设置匿名可以访问

 

//设置webservice访问无需登录  否则会出现Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog        filterChainDefinitionMap.put("/services/**", "anon");

 

转载地址:http://cygai.baihongyu.com/

你可能感兴趣的文章
《Android系统学习》第十一章:Android应用程序Activity组件分析
查看>>
Android4.2 Input子系统
查看>>
《C++面向对象》结构体继承
查看>>
《tiny6410裸机程序》第二章:LED跑马灯RVDS精简main.c说明
查看>>
指向指针的指针
查看>>
《tiny6410裸机程序》第三章:基础汇编test1
查看>>
《tiny6410裸机程序》第四章:汇编与C混合编程
查看>>
《tiny6410裸机程序》第五章:汇编与C混合编程-LED跑马灯最终说明、myled再次精简
查看>>
《tiny6410裸机程序》第六章:myled通过usb下载至nandflash不能运行
查看>>
《tiny6410裸机程序》第七章:S3C6410外部中断简介
查看>>
《tiny6410裸机程序》第八章:S3C6410外部中断控制寄存器
查看>>
《tiny6410裸机程序》第八章:S3C6410总中断控制寄存器
查看>>
《tiny6410裸机程序》第九章:tiny6410按键控制蜂鸣器程序
查看>>
有关free()函数的一个问题
查看>>
《Android系统学习》之bug定位
查看>>
《Linux内核编程》第七章:USB CORE与USB键鼠驱动
查看>>
《Android系统学习》之JAVA与C混合编程——JNI
查看>>
《C预处理》之#ifndef
查看>>
Android边录边播应用
查看>>
《Linux内核编程》第十三章:Linux对进程内存的二级页式管理
查看>>