springBoot + webservice

之前发布在CSDN 现转移到简书了
既然要做WebService,基本用途大家肯定都是知道的. 话不多说直接上代码:

准备工作:
创建springBoot项目webservice_server
创建springBoot项目webservice_client
分别添加CXF的依赖:

<!-- CXF webservice -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.1.11</version>
</dependency>
<!-- CXF webservice -->

一.定义要发布的接口和实现类
接口:

@WebService
public interface AppService {
    @WebMethod
    String getUserName(@WebParam(name = "id") String id) throws UnsupportedEncodingException;
    @WebMethod
    public User getUser(String id) throws UnsupportedEncodingException;
}

实现类:

//name暴露的服务名称, targetNamespace:命名空间,设置为接口的包名倒写(默认是本类包名倒写). endpointInterface接口地址
@WebService(name = "test" ,targetNamespace ="http://cxf.wolfcode.cn/" ,endpointInterface = "cn.wolfcode.cxf.AppService")
public class AppServiceImpl implements AppService {
    JSONResult jsonResult = JSONResult.getJsonResult();
    @Override
    public String getUserName(String id) throws UnsupportedEncodingException {
        System.out.println("==========================="+id);
        JSONResult result=  JSONResult.getJsonResult();
        result.setSuccess(true);
        result.setMessage("明哥");
        return result.toJsonObject();
    }
    @Override
    public User getUser(String id)throws UnsupportedEncodingException  {
        System.out.println("==========================="+id);
        return new User(1L,"明哥");
    }

}

二.发布服务

  1. 定义配置类
@Configuration
public class CxfConfig {
    //默认servlet路径/*,如果覆写则按照自己定义的来
    @Bean
    public ServletRegistrationBean dispatcherServlet() {
        return new ServletRegistrationBean(new CXFServlet(), "/services/*");
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    //把实现类交给spring管理
    @Bean
    public AppService appService() {
        return new AppServiceImpl();
    }

    //终端路径
    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(springBus(), appService());
        endpoint.getInInterceptors().add(new AuthInterceptor());//添加校验拦截器
        endpoint.publish("/user");
        return endpoint;
    }
}
  1. 发布服务
@SpringBootApplication
public class WebserviceApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebserviceApplication.class, args);
    }
}

因为我添加了用户名和密码校验所以在发布之前还需要定义自己校验用户名和密码的Interceptor

public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final String USERNAME="root";
    private static final String PASSWORD="admin";

    public AuthInterceptor() {
        //定义在哪个阶段进行拦截
        super(Phase.PRE_PROTOCOL);
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List<Header> headers = null;
        String username=null;
        String password=null;
        try {
           headers = soapMessage.getHeaders();
        } catch (Exception e) {
            logger.error("getSOAPHeader error: {}",e.getMessage(),e);
        }

        if (headers == null) {
            throw new Fault(new IllegalArgumentException("找不到Header,无法验证用户信息"));
        }
        //获取用户名,密码
        for (Header header : headers) {
            SoapHeader soapHeader = (SoapHeader) header;
            Element e = (Element) soapHeader.getObject();
            NodeList usernameNode = e.getElementsByTagName("username");
            NodeList pwdNode = e.getElementsByTagName("password");
             username=usernameNode.item(0).getTextContent();
             password=pwdNode.item(0).getTextContent();
            if( StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
                throw new Fault(new IllegalArgumentException("用户信息为空"));
            }
        }
        //校验用户名密码
        if(!(username.equals(USERNAME) && password.equals(PASSWORD))){
            SOAPException soapExc = new SOAPException("认证失败");
            logger.debug("用户认证信息错误");
            throw new Fault(soapExc);
        }

    }

}

现在可以发布服务了.....
发布完成后访问http://localhost:8888/services/user?wsdl
能够出现以下界面就是发布OK

20180227213241950.png


三.调用服务

 

  1. 新建调用端项目,添加依赖

  2. 因为示例演示了两种调用方式,其中一种需要用到接口,所以先把服务接口拷贝一份到调用端项目中(代码就是上面接口的代码)

  3. 因为服务端添加了用户名密码校验,所以调用的时候需要添加用户名密码信息, 所以需要使用下面的Interceptor完成添加用户名密码信息

/**
 * Created by sky on 2018/2/27.
 */
public class LoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    private String username="root";
    private String password="admin";
    public LoginInterceptor(String username, String password) {
        //设置在发送请求前阶段进行拦截
        super(Phase.PREPARE_SEND);
        this.username=username;
        this.password=password;
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List<Header> headers = soapMessage.getHeaders();
        Document doc = DOMUtils.createDocument();
        Element auth = doc.createElementNS("http://cxf.wolfcode.cn/","SecurityHeader");
        Element UserName = doc.createElement("username");
        Element UserPass = doc.createElement("password");

        UserName.setTextContent(username);
        UserPass.setTextContent(password);

        auth.appendChild(UserName);
        auth.appendChild(UserPass);

        headers.add(0, new Header(new QName("SecurityHeader"),auth));
    }
}
  1. 调用接口
/**
 * Created by sky on 2018/2/27.
 */
public class Cxfclient {
    //webservice接口地址
    private static String address = "http://localhost:8888/services/user?wsdl";

    //测试
    public static void main(String[] args) {
        test1();
        test2();
    }

    /**
     * 方式1:使用代理类工厂,需要拿到对方的接口
     */
    public static void test1() {
        try {
            // 代理工厂
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            // 设置代理地址
            jaxWsProxyFactoryBean.setAddress(address);
            //添加用户名密码拦截器
            jaxWsProxyFactoryBean.getOutInterceptors().add(new LoginInterceptor("root","admin"));;
            // 设置接口类型
            jaxWsProxyFactoryBean.setServiceClass(AppService.class);
            // 创建一个代理接口实现
            AppService cs = (AppService) jaxWsProxyFactoryBean.create();
            // 数据准备
            String LineId = "1";
            // 调用代理接口的方法调用并返回结果
            User result = (User)cs.getUser(LineId);
            System.out.println("==============返回结果:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 动态调用方式
     */
    public static void test2() {
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(address);
        // 需要密码的情况需要加上用户名和密码
         client.getOutInterceptors().add(new LoginInterceptor("root","admin"));
        Object[] objects = new Object[0];
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            System.out.println("======client"+client);
            objects = client.invoke("getUserName", "1");
            System.out.println("返回数据:" + objects[0]);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

嗯...总体上就是这么简单, 演示代码可以去这里下载:http://download.csdn.net/download/weixin_41138656/10262143



作者:touch_The_Sky
链接:https://www.jianshu.com/p/dd1bf8fa6904
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值