CXF2.7整合spring發布webservice
阿新 • • 發佈:2018-09-14
localhost 掃描 接口 eclips mpls welcom 而且 icc 框架
---------==========--服務端發布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 voidsetUsername(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:============
無論哪種方式調用都會調用到發布的webservice的實現類的代碼(項目中的代碼)。也就是必須依賴tomcat服務器啟動才能訪問webservice的實現代碼,如果tomcat沒啟動將訪問不到wsdl。並且會報訪問不到wsdl與連接拒絕的錯誤。
訪問方式基本上有三種,生成本地代碼、靜態代理、動態代理。
1.利用JDK自帶的工具生成代碼到本地的方式進行(不依賴於CXF框架)
C:\Users\liqiang\Desktop>cd webservice C:\Users\liqiang\Desktop\webservice>wsimport http://localhost/CXFTest/WS/userws? parsing WSDL... Generating code... Compiling code...
會將代碼生成到本地,如下:
打成jar包後使用:
C:\Users\liqiang\Desktop\webservice>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()+"\t"+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() + "\t" + 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的結果。
CXF2.7整合spring發布webservice