WebService

Webservice 是一种传统的soa技术架构, 它不依赖于任何的编程语言,也不依赖于任何的技术平台, 可以直接基于http协议实现网络应用间的数据交互

Webservice 服务端是以接口远程接口为主的, 在java实现的webservice技术里面主要依靠的是CXF开发框架,而这个CXF框架可以直接将接口发布成webservice,同时还需要考虑到整个项目之中的安全性问题

[ws-common] 子模块中  定义接口

package com.ly.service;

import javax.jws.WebMethod;

import javax.jws.WebParam;

import javax.jws.WebService;

@WebService(name="MessageService",targetNamespace = "http://service.ly.com") //与包名相反

public interface IMessageService {

    @WebMethod    //进行webservice 方法标注

    public String echo(@WebParam String msg);

}

[ws-server] 中 定义接口的实现

package com.ly.service.impl;

import com.ly.service.IMessageService;

import org.springframework.stereotype.Service;

import javax.jws.WebService;

@WebService(serviceName = "MessageService",

            targetNamespace = "http://service.ly.com",   //接口命名空间

            endpointInterface = "com.ly.service.IMessageService")  //接口名称

@Service

public class MessageService implements IMessageService {

    @Override

    public String echo(String msg) {

        return "[Echo]"+msg;

    }

}

此时webservice 接口开发完成了, 但最终想要使用 还需要一些安全上的配置,

这个安全配置是基于拦截器完成的

[ws-server 中 ]

package com.ly.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.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

import org.springframework.stereotype.Component;

import org.w3c.dom.NodeList;

import javax.xml.soap.SOAPException;

import javax.xml.soap.SOAPHeader;

import javax.xml.soap.SOAPMessage;

import java.util.Locale;

@Component

public class WebServiceInterceptorLy extends AbstractPhaseInterceptor {

    private SAAJInInterceptor saaj = new SAAJInInterceptor();//创建拦截器

    private static final String USER_NAME="liu"; //用户名

    private static final String USER_PASS="ly.com";//密码

    public WebServiceInterceptorLy() {

        super(Phase.PRE_PROTOCOL);

        super.getAfter().add(SAAJInInterceptor.class.getName());//添加拦截

    }

    @Override

    public void handleMessage(SoapMessage soapMessage) throws Fault {

        SOAPMessage content = soapMessage.getContent(SOAPMessage.class);

        if(content ==null){ //没有消息内容

            this.saaj.handleMessage(soapMessage); // 直接走默认处理

            content = soapMessage.getContent(SOAPMessage.class);//尝试获取消息

        }

        SOAPHeader header = null; //soa 头信息

        try {

            header = content.getSOAPHeader(); //通过消息获取头

        } catch (SOAPException e) {

            e.printStackTrace();

        }

        if(header==null){  //没有头信息

          throw new Fault(new IllegalAccessException("找不到头信息,无法实现用户认证"));

        }

        //SOAP 是就xml文件结构进行传输的,所以如果要想获取认证信息必须进行相关的结构约定

        NodeList usernameList = header.getElementsByTagName("username");

        NodeList passwordList = header.getElementsByTagName("password");

        if (usernameList.getLength()<1 || passwordList.getLength()<1){

            throw new Fault(new IllegalAccessException("找不到头信息,无法实现用户认证"));

        }

        String username = usernameList.item(0).getTextContent().trim();

        String passsword = passwordList.item(0).getTextContent().trim();

        if(USER_NAME.equals(username) && USER_PASS.equals(passsword)){ //认证合法

            System.out.println("认证成功-------------");

        }else{

            SOAPException soapException = new SOAPException("用户认证失败");

            System.out.println("用户认证失败--------------------");

            throw new Fault(soapException);

        }

    }

}

[ws-server]

package com.ly.config;

import com.ly.interceptor.WebServiceInterceptorLy;

import com.ly.service.IMessageService;

import org.apache.cxf.Bus;

import org.apache.cxf.jaxws.EndpointImpl;

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

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.web.servlet.ServletRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

@Configuration

public class CXFConfig {

    @Autowired

    private Bus bus;  //注入bug接口实例

    @Autowired

    private IMessageService messageService;//注入业务实例

    @Autowired

    private WebServiceInterceptorLy interceptor;//认证拦截器

    @Bean

    public ServletRegistrationBean getRegistrationBean(){

        return new ServletRegistrationBean(new CXFServlet(),"/services/*");  //webservice 访问的父路径

    }

@Bean

    public Endpoint messagePoint(){

        EndpointImpl endpoint = new EndpointImpl(this.bus,this.messageService);

        endpoint.publish("/MessageService");

        endpoint.getInInterceptors().add(this.interceptor);

        return endpoint;

    }

}

[ws-server]  创键 启动类

package com.ly;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class WSServer {

    public static void main(String[] args) {

        SpringApplication.run(WSServer.class,args);

    }

}

启动 ,  地址栏输入 http://localhost:8080/services

WebService_第1张图片

Wsdl 描述文件

WebService_第2张图片

[ws-client] 创建一个拦截器 ,来实现认证数据的传递

WebService_第3张图片

WebService_第4张图片

package com.ly.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.message.Message;

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;

public class ClientInterceptor extends AbstractPhaseInterceptor {

    private String username;

    private String password;

    public ClientInterceptor(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 document = DOMUtils.createDocument();//创建文档

        Element auth = document.createElement("authority");//认证数据信息

        Element username = document.createElement("username");//认证数据信息

        Element password = document.createElement("password");//认证数据信息

        username.setTextContent(this.username);

        password.setTextContent(this.password);

        auth.appendChild(username);

        auth.appendChild(password);

        headers.add(0,new Header(new QName("authority"),auth));

    }

}

[ws-client]  基于代理的方式 实现WebService服务调用

package com.ly.client;

import com.ly.interceptor.ClientInterceptor;

import com.ly.service.IMessageService;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class CXFClientProxy {

    public static void main(String[] args) throws Exception{

        String address = "http://localhost:8080/services/MessageService?wsdl";

        JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();

        jaxWsProxyFactoryBean.setAddress(address);

        jaxWsProxyFactoryBean.setServiceClass(IMessageService.class);// 映射的接口

        jaxWsProxyFactoryBean.getOutInterceptors().add(new ClientInterceptor("liu","ly.com"));

        IMessageService service = (IMessageService) jaxWsProxyFactoryBean.create();//远程接口映射

        String message = "hello webservice";

        String result = service.echo(message);

        System.out.println("客户端输出----"+result);

    }

}

启动 ws-server , 启动成功后, 在ws-client中 运行CXFClientProxy的main

控制台 输出

[ws-client]  通过动态代理方式实现

package com.ly.client;

import com.ly.interceptor.ClientInterceptor;

import org.apache.cxf.endpoint.Client;

import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

public class CXFClientDyn {

    public static void main(String[] args) throws Exception{

        String address = "http://localhost:8080/services/MessageService?wsdl";

        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();

        Client client = dcf.createClient(address); //创建一个客户端类

        client.getOutInterceptors().add(new ClientInterceptor("liu","ly.com"));

        String message = "hello webservice";

        Object[] result = client.invoke("echo",message);

        System.out.println("客户端输出333333----"+result[0]);

    }

}

启动 server  运行 ,

WebService_第5张图片

你可能感兴趣的:(java,java)