zoukankan      html  css  js  c++  java
  • CXF2.7整合spring发布webservice

    ---------==========--服务端发布webservice-=============--------

    1.需要的jar包:

    2.包结构

     

     3.代码

    1.实体类

    package cn.qlq.domain;
    
    public class User {
    
        private String username;
        private String password;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User [username=" + username + ", password=" + password + "]";
        }
    }

    2.dao代码:

    package cn.qlq.dao;
    
    import java.sql.SQLException;
    
    import cn.qlq.domain.User;
    
    public interface UserDao {
        /**
         * 保存用户
         * 
         * @param user
         * @return
         * @throws SQLException
         */
        public int saveUser(User user) throws SQLException;
    
        /**
         * 根据userId获取user
         * 
         * @param userId
         * @return
         */
        public User getUserById(int userId);
    }
    package cn.qlq.dao.impl;
    
    import java.sql.SQLException;
    
    import org.springframework.stereotype.Repository;
    
    import cn.qlq.dao.UserDao;
    import cn.qlq.domain.User;
    
    @Repository
    public class UserDaoImpl implements UserDao {
    
        public UserDaoImpl(){
            System.out.println("=====生成userDao=====");
        }
        
        @Override
        public int saveUser(User user) throws SQLException {
            System.out.println("保存用户");
            return 0;
        }
    
        @Override
        public User getUserById(int userId) {
            // 模拟从数据库取数据
            User u = new User();
            u.setUsername("qlq");
            u.setPassword("123456");
            return u;
        }
    
    }

    3.service代码:

    package cn.qlq.service;
    
    import java.sql.SQLException;
    
    import javax.jws.WebMethod;
    import javax.jws.WebService;
    
    import cn.qlq.domain.User;
    
    @WebService
    public interface UserService {
        /**
         * 保存用户
         * 
         * @param user
         * @return
         * @throws SQLException
         */
        public int saveUser(User user) throws SQLException;
    
        /**
         * 根据userId获取user
         * 
         * @param userId
         * @return
         */
        @WebMethod
        public User getUserById(int userId);
    }
    package cn.qlq.service.impl;
    
    import java.sql.SQLException;
    
    import javax.jws.WebService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.qlq.dao.UserDao;
    import cn.qlq.domain.User;
    import cn.qlq.service.UserService;
    
    @Service
    @WebService
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        @Override
        public int saveUser(User user) throws SQLException {
            System.out.println("----------------保存user----------");
            return 0;
        }
    
        @Override
        public User getUserById(int userId) {
            return userDao.getUserById(userId);
        }
    
    }

    4.配置文件

     application.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    
        <!-- 引cxf的一些核心配置 -->
        <import resource="classpath:META-INF/cxf/cxf.xml" />
        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
        <!-- 自动扫描dao和service包(自动注入) -->
        <context:component-scan base-package="cn.qlq" />
    
        <jaxws:endpoint id="userWS" implementor="cn.qlq.service.impl.UserServiceImpl"
            address="/userws">
        </jaxws:endpoint>
    
    </beans>

    经测试:上面的import不需要也是可以的。 (而且最好不写上面三个)

     web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="WebApp_ID" version="2.5">
        <display-name>CXFTest</display-name>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <servlet>
            <servlet-name>CXFServlet</servlet-name>
            <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>CXFServlet</servlet-name>
            <url-pattern>/WS/*</url-pattern>
        </servlet-mapping>
    </web-app>

    5.启动服务进行测试:

    查看有哪些发布的webservice:

    查看WSDL描述:

     

    6.第二种xml配置发布webservice的配置可以参考:https://www.cnblogs.com/qlqwjy/p/7576528.html

      这种方式配置可以查看日志,也就是传的参数与返回值(XML格式的数据)都可以在日志中查看:

    例如修改上面的application的配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://cxf.apache.org/jaxws http://cxf.apache.org/jaxws http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
        <!-- 自动扫描dao和service包(自动注入) -->
        <context:component-scan base-package="cn.qlq" />
    
        <!-- 配置cxf 地址: http://192.168.114.10:8080/CXF_Server/ws/employeeManager 
            组成 : http://192.168.114.10:8080 +CXF_Server( 项目名)+ws(过滤的路径)+/employeeManager(自定义部分) 
            服务类 : 服务的实现类: 拦截器 -->
        <jaxws:server address="/userws" serviceClass="cn.qlq.service.UserService">
            <jaxws:serviceBean>
                <ref bean="userServiceImpl" />
            </jaxws:serviceBean>
            <!-- 配置输入显示日志信息的拦截器 -->
            <jaxws:inInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
            </jaxws:inInterceptors>
            <jaxws:outInterceptors>
                <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
            </jaxws:outInterceptors>
        </jaxws:server>
    
    </beans>

    启动服务查看有哪些发布的服务:

    测试访问一个服务:

    import javax.xml.namespace.QName;
    
    import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
    
    public class TestWS {
    
        public static void main(String[] args) throws Exception {
    
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
    
            org.apache.cxf.endpoint.Client client = dcf.createClient("http://localhost/CXFTest/WS/userws?wsdl"); // url为调用webService的wsdl地址
    
            QName name = new QName("http://service.qlq.cn/", "getAllUsers");// namespace是命名空间,methodName是方法名
    
            Object[] objects;
            try {
                objects = client.invoke(name);// 第一个参数是上面的QName,第二个开始为参数,可变数组
                System.out.println(objects[0].toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }

    查看服务端日志(控制台):

    ----------------------------
    ID: 1
    Address: http://localhost/CXFTest/WS/userws?wsdl
    Http-Method: GET
    Content-Type: text/xml
    Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], content-type=[text/xml], host=[localhost], pragma=[no-cache], user-agent=[Apache CXF 2.7.4]}
    --------------------------------------
    九月 15, 2018 2:31:32 下午 org.apache.cxf.staxutils.StaxUtils createXMLInputFactory
    警告: Could not create a secure Stax XMLInputFactory.  Found class com.ctc.wstx.stax.WstxInputFactory.  Suggest Woodstox 4.2.0 or newer.
    九月 15, 2018 2:31:41 下午 org.apache.cxf.services.userService.UserServicePort.UserService
    信息: Inbound Message
    ----------------------------
    ID: 2
    Address: http://localhost/CXFTest/WS/userws
    Encoding: UTF-8
    Http-Method: POST
    Content-Type: text/xml; charset=UTF-8
    Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[162], content-type=[text/xml; charset=UTF-8], host=[localhost], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.4]}
    Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllUsers xmlns:ns2="http://service.qlq.cn/"/></soap:Body></soap:Envelope>
    --------------------------------------
    九月 15, 2018 2:31:42 下午 org.apache.cxf.services.userService.UserServicePort.UserService
    信息: Outbound Message
    ---------------------------
    ID: 2
    Encoding: UTF-8
    Content-Type: text/xml
    Headers: {}
    Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getAllUsersResponse xmlns:ns2="http://service.qlq.cn/"><allUsers><password>0</password><username>0</username></allUsers><allUsers><password>1</password><username>1</username></allUsers><allUsers><password>2</password><username>2</username></allUsers></ns2:getAllUsersResponse></soap:Body></soap:Envelope>
    --------------------------------------

    =========客户端使用webservice:============

      无论哪种方式调用都会调用到发布的webservice的实现类的代码(项目中的代码)。也就是必须依赖tomcat服务器启动才能访问webservice的实现代码,如果tomcat没启动将访问不到wsdl。并且会报访问不到wsdl与连接拒绝的错误。

      访问方式基本上有三种,生成本地代码、静态代理、动态代理。

    1.利用JDK自带的工具生成代码到本地的方式进行(不依赖于CXF框架)

    C:UsersliqiangDesktop>cd webservice
    
    
    C:UsersliqiangDesktopwebservice>wsimport http://localhost/CXFTest/WS/userws?wsdl
    parsing WSDL...
    
    
    
    Generating code...
    
    
    Compiling code...

    会将代码生成到本地,如下:

     打成jar包后使用:

    C:UsersliqiangDesktopwebservice>jar cvf wstest.jar ./
    已添加清单
    正在添加: cn/(输入 = 0) (输出 = 0)(存储了 0%)
    正在添加: cn/qlq/(输入 = 0) (输出 = 0)(存储了 0%)
    正在添加: cn/qlq/service/(输入 = 0) (输出 = 0)(存储了 0%)
    正在添加: cn/qlq/service/GetUserById.class(输入 = 605) (输出 = 376)(压缩了 37%)
    正在添加: cn/qlq/service/GetUserByIdResponse.class(输入 = 763) (输出 = 424)(压缩了 44%)
    正在添加: cn/qlq/service/impl/(输入 = 0) (输出 = 0)(存储了 0%)
    正在添加: cn/qlq/service/impl/SQLException.class(输入 = 788) (输出 = 422)(压缩了 46%)
    正在添加: cn/qlq/service/impl/UserService.class(输入 = 1050) (输出 = 507)(压缩了 51%)
    正在添加: cn/qlq/service/impl/UserServiceImplService.class(输入 = 2369) (输出 = 1050)(压缩了
    正在添加: cn/qlq/service/ObjectFactory.class(输入 = 3124) (输出 = 1009)(压缩了 67%)
    正在添加: cn/qlq/service/package-info.class(输入 = 242) (输出 = 195)(压缩了 19%)
    正在添加: cn/qlq/service/SaveUser.class(输入 = 656) (输出 = 384)(压缩了 41%)
    正在添加: cn/qlq/service/SaveUserResponse.class(输入 = 694) (输出 = 411)(压缩了 40%)
    正在添加: cn/qlq/service/SQLException.class(输入 = 1036) (输出 = 525)(压缩了 49%)
    正在添加: cn/qlq/service/User.class(输入 = 798) (输出 = 434)(压缩了 45%)

    导入eclipse中测试:

    测试代码:

    import cn.qlq.service.User;
    import cn.qlq.service.impl.UserService;
    import cn.qlq.service.impl.UserServiceImplService;
    
    public class TestWS {
    
        public static void main(String[] args) {
            UserServiceImplService us = new UserServiceImplService();
            UserService userService = us.getUserServiceImplPort();
            User user = userService.getUserById(0);
            System.out.println(user.getUsername()+"	"+user.getPassword());
        }
        
    }

    结果:

    qlq 123456

    2.第二种方式:静态代理:(依赖于CXF框架,而且需要将接口写在对应包下---与webservice保持一致)

    目录结构:

     jar包:

     测试类:

    import org.apache.cxf.interceptor.LoggingInInterceptor;
    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
    
    import cn.qlq.domain.User;
    import cn.qlq.service.UserService;
    
    public class TestWS {
    
        public static void main(String[] args) throws Exception {
            // 创建WebService客户端代理工厂
            JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
            // 判断是否抛出异常
            factory.getOutInterceptors().add(new LoggingInInterceptor());
            // 注册webservice接口
            factory.setServiceClass(UserService.class);
            // 配置webservice地址
            factory.setAddress("http://localhost/CXFTest/WS/userws?wsdl");
            // 获得接口对象
            UserService service = (UserService) factory.create();
            // 调用接口方法
            User user = service.getUserById(5);
            // 关闭接口连接
            System.out.println(user.getUsername() + "	" + user.getPassword());
        }
    
    }

    结果:

    qlq 123456

    3.动态调用:(推荐这种)

    import javax.xml.namespace.QName;
    
    import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
    
    public class TestWS {
    
        public static void main(String[] args) throws Exception {
    
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
    
            org.apache.cxf.endpoint.Client client = dcf.createClient("http://localhost/CXFTest/WS/userws?wsdl"); // url为调用webService的wsdl地址
    
            QName name = new QName("http://service.qlq.cn/", "getUserById");// namespace是命名空间,methodName是方法名
    
            int userId = 1;
    
            Object[] objects;
            try {
                objects = client.invoke(name, userId);// 第一个参数是上面的QName,第二个开始为参数,可变数组
                System.out.println(objects[0].toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    } 

     参数解释:

     注意:如果上面报错:

      org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name

    我们需要将targetNamespace和namespace保持一致,如下:

    我们需要将实现类和接口放在同一个包下,或者对服务端的接口实现类中的@WebService添加targetNamespace,其值为接口包名的倒置,例如上面我的配置为:(只用包名)

    package cn.qlq.service.impl;
    
    import java.sql.SQLException;
    
    import javax.jws.WebService;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.qlq.dao.UserDao;
    import cn.qlq.domain.User;
    import cn.qlq.service.UserService;
    
    @Service
    @WebService(targetNamespace = "http://service.qlq.cn")
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        @Override
        public int saveUser(User user) throws SQLException {
            System.out.println("----------------保存user----------");
            return 0;
        }
    
        @Override
        public User getUserById(int userId) {
            System.out.println("----------------获取user----------" + userId);
            return userDao.getUserById(userId);
        }
    
    }

    结果:

      至此webservice的发布与使用基本完成,明天还会在项目中实际发布webservice,以及测试webservice类改变运用上面三种方式访问webservice的结果。

    参考:http://cxf.apache.org/docs/index.html

  • 相关阅读:
    数据切分——Atlas介绍
    HDU 5015 233Matrix (构造矩阵)
    Wincc操作数据库SQLSERVER
    UIWebView 设置背景为透明
    29个你必须知道的Linux命令
    【读书笔记】iOS-UIWindow-WindowLevel
    linux下uart应用编程
    Java Web HelloWorld!
    手把手图文教你eclipse下如何配置tomcat
    Tomcat安装及配置教程
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/9644078.html
Copyright © 2011-2022 走看看