一.WebService概述
1.1WebService簡介
Web Service(WEB服務)可以快捷和方便地綜合結合各類系統、商務和任何應用平臺。利用最新的Web Service 標準可以使任何軟件系統和系統之間的應用互通互聯,方便,並且更加廉價。 html
1.2WebService的應用場景
-
跨越防火牆通訊java
-
集成應用程序web
-
複用軟件spring
1.3其餘遠程應用調用解決方案
-
使用Socket遠程通訊shell
-
使用Apache的HttpClientapache
-
RMI(Remote Method Invoke)編程
1.4WebService的三個規範
-
JAXM&SAAJ(廢棄)json
-
JAX-WS :採用標準SOAP(Simple Object Access Protocol) 協議傳輸,soap協議傳輸是xml數據。api
-
JAX-RS:Java針對REST(Representation State Transfer)風格制定的一套Web服務規範。瀏覽器
二.Apache的CXF
Apache CXF是一個開源的Web Service 框架,CXF 幫助咱們構建和開發 Web Service,它支持多種協議,如:SOAP, XML/HTTP、RESTful或者CORBA。
下載地址:http://cxf.apache.org/download.html
三.基於JAX-WS規範的入門
3.1JAX-WS的三要素
-
SOAP:基於HTTP協議,採用XML格式,用來傳遞信息的格式。
-
WSDL:用來描述如何訪問具體的服務
-
UDDI:用戶可按UDDI標準搭建UDDI服務器,用來管理分發,查詢WebService。其餘用戶能夠本身註冊發佈WebService調用。
3.2入門案例
咱們在使用WebService時,更多的時候充當的是調用者。由於服務端別人已經寫好了。
3.2.1編寫服務端
第一步:建立Maven工程導入CXF座標
<!-- 導入cxf相關座標 --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-features-logging</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.3.0</version> </dependency>
第二步:編寫服務接口和實現類
/** * 提供實時公交的服務接口 * @author Mr.song * @date 2019/05/20 9:55 */ @WebService //代表當前接口是一個WebService服務 public interface BusService { /** * 根據公交線路查詢公交實時站點 * @param line 公交線路 * @return */ String getBusByLine(String line); } //========================================== /**提供實時公交的服務實現類 * @author Mr.song * @date 2019/05/20 9:57 */ public class BusServiceImpl implements BusService { public String getBusByLine(String line) { if ("916".equals(line)){ return "距您還有3站"; } return "未知"; } }
Tips:注意加入@WebService註解
第三步:編寫測試類(main方法啓動)
/** * @author Mr.song * @date 2019/05/20 10:17 */ public class WebBusServiceTest { public static void main(String[] args) { //1.建立發佈服務的對象 JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); //2.設置服務地址 factoryBean.setAddress("http://localhost:8847/bus"); //3.設置服務的對象 factoryBean.setServiceBean(new BusServiceImpl()); //4.發佈服務 factoryBean.create(); } }
第四步:瀏覽器訪問測試
地址爲:http://localhost:8847/bus/?wsdl
若控制檯無錯誤,則代表服務端編寫正確。
3.2.2編寫客戶端
第一步:建立Maven工程導入CXF座標(同上)
第二步:使用jdk提供的命令生成本地代碼
使用的是jdk bin目錄下的wsimport.exe工具
進入到客戶端工程java目錄下,按住shift右擊,在此處打開shell窗口輸入命令:wsimport -s . http://localhost:8847/bus/?wsdl 便可完成解析,並生成代碼。(此處的連接是服務端瀏覽器測試時訪問的)| -s 指定生成文件目錄 . 指當前文件夾下
第三步:編寫測試類
/** * @author Mr.song * @date 2019/05/20 16:32 */ public class BusTest { @Test public void testBus(){ //1.建立客戶端的代理工廠bean JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean(); //2.設置說明書的地址 proxy.setAddress("http://localhost:8847/bus?wsdl"); //3.設置客戶端須要使用的服務接口類字節碼 proxy.setServiceClass(BusService.class); //4.使用proxy建立服務接口的代理對象 Object obj = proxy.create(); //5.若是obj是service接口的代理實現類,強轉成service接口 BusService busService = (BusService) obj; //6.執行service中的方法 String rtValue = busService.getBusByLine("916"); System.out.println(rtValue); } }
Tips: 運行測試端代碼時,保證服務端不要關閉
3.3Spring整合CXF
3.3.1編寫服務端
第一步:建立Maven的Web工程並導入CXF座標(同上)
第二步:編寫服務接口和實現類(同上)
第三步:配置 Spring 的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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/schemas/jaxws.xsd"> <!-- 配置服務端的服務 --> <!-- 主機和端口用tomcat的,http協議 --> <jaxws:server address="/bus"> <!-- 配置具體服務實現類 --> <jaxws:serviceBean> <bean class="cn.dintalk.service.BusServiceImpl"/> </jaxws:serviceBean> </jaxws:server> </beans>
第四步:在 web.xml 中配置Spring容器在應用加載時建立
<?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" version="2.5"> <!-- 配置應用加載監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-cxf-server.xml</param-value> </context-param> <!-- CXF框架的核心控制器:CXFServlet --> <servlet> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <!-- 配置處理請求url中含有/ws/*的請求 --> <url-pattern>/ws/*</url-pattern> </servlet-mapping> </web-app>
第五步:瀏覽器訪問測試
地址:http://localhost:8080/ws/bus?wsdl
若控制檯無錯誤,則代表服務端編寫正確。
3.3.2編寫客戶端
第一步:建立Maven的Web工程並導入CXF座標(同上)
第二步:使用 jdk 提供的命令生成客戶端代碼(同上)
第三步:編寫 Spring 配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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/schemas/jaxws.xsd"> <!-- 配置服務端訪問地址和應用接口 --> <jaxws:client id="client" address="http://localhost:8080/ws/bus?wsdl" serviceClass="cn.dintalk.service.BusService"></jaxws:client> </beans>
第四步:編寫測試類
/** * @author Mr.song * @date 2019/05/20 17:29 */ public class BusTest { @Test public void testBus(){ //1.讀取配置文件,建立容器 ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext-cxf-client.xml"); //2.根據bean的id獲取對象 BusService busService = (BusService) ac.getBean("client"); //3.執行方法 String rtValue = busService.getBusByLine("916"); System.out.println(rtValue); } }
Tips: 運行測試類測試時,主要不要關閉服務端。
四.基於JAX-RS規範的入門
4.1JAX-RS和Restful
JAX-RS 是一個 Java 編程語言接口,被設計用來簡化使用 REST 架構的應用程序的開發。JAX-RS API 使用 Java 編程語言的註解來簡化 RESTful web service 的開發。開發人員使用 JAX-RS 的註解修飾Java編程語言的類文件來定義資源和可以應用在資源上的行爲。JAX-RS的註解是運行時的註解,所以運行時的映射會爲資源生成輔助類和其餘的輔助文件。包含 JAX-RS 資源類的 Java EE 應用程序中資源是被配置好的,輔助類和輔助文件是生成的,資源經過被髮布到 Java EE 服務器上來公開給客戶端。
RESTful web service 是建立來能在 web 更好的運行的 web service。REST 是一種架構類型,指定了如統一的接口等應用於 web service 的約束。REST 提供瞭如性能、可擴展性和可變性等特性,使得 service 可以更好的在web上工做。在 REST 框架中,數據和功能被認爲是資源,是經過 URI來訪問的,一般是 web連接。資源是經過使用一組簡單的、定義良好的操做來生效。REST 的架構方式限定了客戶/服務器架構,是設計來使用無狀態的通訊協議的,一般是 HTTP。在 REST 框架類型中,客戶端和服務器使用標準的接口和協議交換資源的representation。
4.2入門案例
4.2.1編寫服務端
第一步:建立Maven工程並導入座標
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-client</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-rs-extension-providers</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.7</version> </dependency>
第二步:編寫實體類(業務實體)
@XmlRootElement(name = "User") public class User { private Integer id; private String username; private String city; private List<Car> cars = new ArrayList<Car>(); public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public List<Car> getCars() { return cars; } public void setCars(List<Car> cars) { this.cars = cars; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", city=" + city + ", cars=" + cars + "]"; }
@XmlRootElement(name = "Car") public class Car { private Integer id; private String carName; private Double price; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCarName() { return carName; } public void setCarName(String carName) { this.carName = carName; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Car [id=" + id + ", carName=" + carName + ", price=" + price + "]"; } }
第三步:編寫業務接口和實現類
@Path("/userService") @Produces("*/*") public interface UserService { @POST @Path("/user") @Consumes({ "application/xml", "application/json" }) public void saveUser(User user); @PUT @Path("/user") @Consumes({ "application/xml", "application/json" }) public void updateUser(User user); @GET @Path("/user") @Produces({ "application/xml", "application/json" }) public List<User> findAllUsers(); @GET @Path("/user/{id}") @Consumes("application/xml") @Produces({ "application/xml", "application/json" }) public User finUserById(@PathParam("id") Integer id); @DELETE @Path("/user/{id}") @Consumes({"application/xml", "application/json"}) public void deleteUser(@PathParam("id") Integer id); }
/** * @author Mr.song * @date 2019/05/20 19:39 */ public class UserServiceImpl implements UserService { public void saveUser(User user) { System.out.println("save user:" + user); } public void updateUser(User user) { System.out.println("update user:" + user); } public List<User> findAllUsers() { List<User> users = new ArrayList<User>(); User user1 = new User(); user1.setId(1); user1.setUsername("小明"); user1.setCity("北京"); List<Car> carList1 = new ArrayList<Car>(); Car car1 = new Car(); car1.setId(101); car1.setCarName("保時捷"); car1.setPrice(1000000d); carList1.add(car1); Car car2 = new Car(); car2.setId(102); car2.setCarName("寶馬"); car2.setPrice(400000d); carList1.add(car2); user1.setCars(carList1); users.add(user1); User user2 = new User(); user2.setId(2); user2.setUsername("小麗"); user2.setCity("上海"); users.add(user2); return users; } public User finUserById(Integer id) { if (id == 1) { User user1 = new User(); user1.setId(1); user1.setUsername("小明"); user1.setCity("北京"); return user1; } return null; } public void deleteUser(Integer id) { System.out.println("delete user id :" + id); } }
第四步:編寫服務發佈類
/** * jaxrs服務的發佈 * @author Mr.song * @date 2019/05/20 19:45 */ public class UserTest { public static void main(String[] args) { //1.建立jaxrs服務工廠bean對象 JAXRSServerFactoryBean factoryBean = new JAXRSServerFactoryBean(); //2.設置服務地址 factoryBean.setAddress("http://localhost:8848"); //3.設置提供服務的類 factoryBean.setServiceBean(new UserServiceImpl()); //4.設置日誌輸入和輸出的兩個攔截器 factoryBean.getInInterceptors().add(new LoggingInInterceptor()); factoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); //5.發佈服務 factoryBean.create(); } }
4.2.2編寫客戶端
第一步:建立Maven工程並導入座標(同時)
第二步:編寫業務實體類(同上)
第三步:編寫測試類
/** * @author Mr.song * @date 2019/05/20 19:55 */ public class UserClientTest { /** * 注意:它和jaxws規範的區別是,它使用的是restful的url */ @Test public void test(){ User user = new User(); user.setId(1); user.setUsername("test"); //1.使用WebClient建立訪問地址 : 在服務端接口中有/userService /user的路徑規則 Object rtValue = WebClient.create("http://localhost:8848/userService/user") .type(MediaType.APPLICATION_XML).post(user); System.out.println(rtValue); } @Test public void test2(){ //1.使用WebClient建立訪問地址 Object rtValue = WebClient.create("http://localhost:8848/userService/user/123") .type(MediaType.APPLICATION_JSON).delete(); System.out.println(rtValue); } }
Tips: 測試時保證服務端開啓。
4.3Spring整合CXF
4.3.1編寫服務端
第一步:建立Maven的Web工程並導入座標(同上)
第二步:編寫業務代碼(實體類和服務接口及實現類)同上
第三步:編寫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" version="2.5"> <!-- 配置應用加載監聽器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-cxf-rs.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- CXF的核心控制器 --> <servlet> <servlet-name>cxfServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>cxfServlet</servlet-name> <!-- 配置攔截的路徑 --> <url-pattern>/rs/*</url-pattern> </servlet-mapping> </web-app>
第四步:編寫Spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <!-- 配置服務:ip、端口用tomcat的 --> <!-- 這裏配置了address,接口類就不要配置註解了(@Path("/userService")) --> <jaxrs:server id="userService" address="/userService"> <jaxrs:serviceBeans> <bean class="cn.dintalk.service.UserServiceImpl"/> </jaxrs:serviceBeans> <!-- 配置攔截器 --> <jaxrs:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/> </jaxrs:inInterceptors> <jaxrs:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> </jaxrs:outInterceptors> </jaxrs:server> </beans>
4.3.2編寫客戶端
第一步:建立Maven工程並導入座標(同上)
第二步:建立業務實體類(同上)
第三步:編寫測試類
@Test public void test04(){ User user = WebClient.create("http://localhost:8080/rs/userService/user/1") .type(MediaType.APPLICATION_XML).get(User.class); System.out.println(user); } //輸出以下: //User [id=1, username=小明, city=北京, cars=[]]
Tips: 測試時要保證服務端開啓。