WebService

发布时间:2024年01月14日

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<SoapMessage> {

??? 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

Wsdl 描述文件

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

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<SoapMessage> {

??? 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<Header> 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? 运行 ,

文章来源:https://blog.csdn.net/ly121862/article/details/135553345
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。