springboot整合webservice使用簡(jiǎn)單案例總結(jié)
因?yàn)樽龅捻?xiàng)目中用到了webservice,所以在此總結(jié)一下。
一、webservice簡(jiǎn)介
Web Service也叫XML Web Service, WebService是一種可以接收從Internet或者Intranet上的其它系統(tǒng)中傳遞過(guò)來(lái)的請(qǐng)求,輕量級(jí)的獨(dú)立的通訊技術(shù)。是通過(guò)SOAP在Web上提供的軟件服務(wù),使用WSDL文件進(jìn)行說(shuō)明,并通過(guò)UDDI進(jìn)行注冊(cè)。WebService是一種跨編程語(yǔ)言和跨操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù)。
還可以從多個(gè)角度來(lái)理解WebService,從表面看,WebService就是一個(gè)應(yīng)用程序向外界暴露出一個(gè)能通過(guò)Web進(jìn)行調(diào)用的API,也就是說(shuō)能用編程的方法通過(guò)Web來(lái)調(diào)用這個(gè)應(yīng)用程序。我們把調(diào)用這個(gè)WebService的應(yīng)用程序叫做客戶(hù)端,而把提供這個(gè)WebService的應(yīng)用程序叫做服務(wù)端。從深層次看,WebService是建立可互操作的分布式應(yīng)用程序的新平臺(tái),是一個(gè)平臺(tái),是一套標(biāo)準(zhǔn)。它定義了應(yīng)用程序如何在Web上實(shí)現(xiàn)互操作性,你可以用任何你喜歡的語(yǔ)言,在任何你喜歡的平臺(tái)上寫(xiě)Web service ,只要我們可以通過(guò)Web service標(biāo)準(zhǔn)對(duì)這些服務(wù)進(jìn)行查詢(xún)和訪(fǎng)問(wèn)。
二、webservice三要素:
SOAP、WSDL、UDDI(UniversalDescriptionDiscovery andIntegration)三者構(gòu)成了WebService的三要素。下面詳細(xì)闡述這三大技術(shù):
SOAP:
WebService通過(guò)HTTP協(xié)議發(fā)送請(qǐng)求和接收結(jié)果時(shí),發(fā)送的請(qǐng)求內(nèi)容和結(jié)果內(nèi)容都采用XML格式封裝,并增加了一些特定的HTTP消息頭,以說(shuō)明HTTP消息的內(nèi)容格式,這些特定的HTTP消息頭和XML內(nèi)容格式就是SOAP協(xié)議。SOAP提供了標(biāo)準(zhǔn)的RPC(遠(yuǎn)程調(diào)用技術(shù))方法來(lái)調(diào)用Web Service。
SOAP協(xié)議組成:
SOAP協(xié)議 = HTTP協(xié)議 + XML數(shù)據(jù)格式
SOAP協(xié)議定義了SOAP消息的格式,SOAP協(xié)議是基于HTTP協(xié)議的,SOAP也是基于XML的,XML是SOAP的數(shù)據(jù)編碼方式。
WSDL
好比我們?nèi)ド痰曩I(mǎi)東西,首先要知道商店里有什么東西可買(mǎi),然后再來(lái)購(gòu)買(mǎi),商家的做法就是張貼廣告海報(bào)。 WebService也一樣,WebService客戶(hù)端要調(diào)用一個(gè)WebService服務(wù),首先要有知道這個(gè)服務(wù)的地址在哪,以及這個(gè)服務(wù)里有什么方法可以調(diào)用,所以,WebService務(wù)器端首先要通過(guò)一個(gè)WSDL文件來(lái)說(shuō)明自己家里有啥服務(wù)可以對(duì)外調(diào)用,服務(wù)是什么(服務(wù)中有哪些方法,方法接受的參數(shù)是什么,返回值是什么),服務(wù)的網(wǎng)絡(luò)地址用哪個(gè)url地址表示,服務(wù)通過(guò)什么方式來(lái)調(diào)用。
WSDL(Web Services Description Language)就是這樣一個(gè)基于XML的語(yǔ)言,用于描述Web Service及其函數(shù)、參數(shù)和返回值。它是WebService客戶(hù)端和服務(wù)器端都能理解的標(biāo)準(zhǔn)格式。因?yàn)槭腔赬ML的,所以WSDL既是機(jī)器可閱讀的,又是人可閱讀的,這將是一個(gè)很大的好處。一些最新的開(kāi)發(fā)工具既能根據(jù)你的Web service生成WSDL文檔,又能導(dǎo)入WSDL文檔,生成調(diào)用相應(yīng)WebService的代理類(lèi)代碼。
UDDI
uddi是一個(gè)跨產(chǎn)業(yè),跨平臺(tái)的開(kāi)放性架構(gòu),可以幫助 Web 服務(wù)提供商在互聯(lián)網(wǎng)上發(fā)布 Web 服務(wù)的信息。UDDI 是一種目錄服務(wù),企業(yè)可以通過(guò) UDDI 來(lái)注冊(cè)和搜索 Web 服務(wù)。簡(jiǎn)單來(lái)說(shuō),UDDI 就是一個(gè)目錄,只不過(guò)在這個(gè)目錄中存放的是一些關(guān)于 Web 服務(wù)的信息而已。
也就是說(shuō):
- soap:就是在與webservice通信時(shí)規(guī)定好的協(xié)議
- wsdl:就是webservice中的食譜,你可以找到webservice中有哪些材料(方法),怎去做這道菜(入?yún)?、方法、返回值)?/li>
- uddi:wsdl是食譜的話(huà),uddi就是菜單,可以用來(lái)注冊(cè)和搜索web服務(wù)。
三、為什么要使用WebService
- 跨平臺(tái)調(diào)用
- 跨語(yǔ)言調(diào)用
- 遠(yuǎn)程調(diào)用
四、springboot簡(jiǎn)單調(diào)用案例
1、引入依賴(lài):
<!-- CXF webservice --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.4.5</version> </dependency>
2、創(chuàng)建實(shí)體類(lèi):
@Data @Builder public class UserDto { private Long id; private String name; private Integer age; private String address; }
3、創(chuàng)建WebService接口
public interface IUserServer { UserDto getUser(Long str); }
4、創(chuàng)建WebService接口的實(shí)現(xiàn)類(lèi)
@Service @WebService public class UserServerImpl implements IUserServer { @Override public UserDto getUser(Long id) { return UserDto.builder() .id(id) .address("上海市浦東新區(qū)") .age(25) .name("laJi").build(); } }
這里用到了注解@WebService,我這就只在實(shí)現(xiàn)類(lèi)上使用了。這里介紹一下,先來(lái)看下它的定義:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface WebService { String name() default ""; String targetNamespace() default ""; String serviceName() default ""; String portName() default ""; String wsdlLocation() default ""; String endpointInterface() default ""; }
name: 對(duì)應(yīng)wsdl:portType標(biāo)簽,默認(rèn)值為Java類(lèi)或接口的名稱(chēng);
targetNamespace: 命名空間,一般寫(xiě)為接口的包名倒序,默認(rèn)值也是接口的包名倒序。對(duì)應(yīng)wsd:definitions:targetNamespace 標(biāo)簽;
serviceName: WebService的服務(wù)名稱(chēng),對(duì)應(yīng)wsdl:service,默認(rèn)值為WebService接口實(shí)現(xiàn)類(lèi)的名稱(chēng)+“Service”,示例:UserServiceImplServicce
portName: 對(duì)應(yīng)wsdl:port標(biāo)簽,默認(rèn)值為:WebService接口實(shí)現(xiàn)類(lèi)的名稱(chēng)+“Port”,示例:UserServiceImplPort
wsdlLocation: 指定用于定義WebService的WSDL文檔的地址
endpoointInterfacce: WebService接口全路徑
5、創(chuàng)建WebService配置類(lèi)
@Configuration @RequiredArgsConstructor public class CxfConfig { private final IUserServer userServer; /** * 注入Servlet,注意beanName不能為dispatcherServlet * @author Fang Ruichuan * @date 2022/11/14 19:16 */ @Bean public ServletRegistrationBean cxfServlet() { return new ServletRegistrationBean(new CXFServlet(), "/webservice/*"); } @Bean(name = Bus.DEFAULT_BUS_ID) public SpringBus springBus() { return new SpringBus(); } @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), userServer); endpoint.publish("/api"); return endpoint; } }
進(jìn)行訪(fǎng)問(wèn):http://localhost:8080/webservice
然后點(diǎn)擊url
客戶(hù)端:
public class WebserviceClient { public static void main(String[] args) { JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient("http://localhost:8080/webservice/api?wsdl"); final ObjectMapper mapper = new ObjectMapper(); try { Object[] objects = client.invoke("getUser", 99L); System.out.println(mapper.writeValueAsString(objects[0])); } catch (Exception e) { e.printStackTrace();; } } }
顯示:
{"address":"上海市浦東新區(qū)","age":25,"id":99,"name":"laJi"}
五、進(jìn)階使用:
webservice的服務(wù)端是以遠(yuǎn)程接口為主的,在java實(shí)現(xiàn)的webService主要是依靠的是CXF開(kāi)發(fā)框架,而這個(gè)CXF框架可以直接將接口發(fā)布成webservice,同時(shí)還要考慮到整個(gè)項(xiàng)目之中的安全性問(wèn)題。
相關(guān)注解:
1)@WebService
1、serviceName: 對(duì)外發(fā)布的服務(wù)名,指定 Web Service 的服務(wù)名稱(chēng):wsdl:service。缺省值為 Java 類(lèi)的簡(jiǎn)單名稱(chēng) + Service。(字符串)
2、endpointInterface: 服務(wù)接口全路徑, 指定做SEI(Service EndPoint Interface)服務(wù)端點(diǎn)接口,包名+實(shí)現(xiàn)類(lèi)的接口的完整路徑
3、name:此屬性的值包含XML Web Service的名稱(chēng)。在默認(rèn)情況下,該值是實(shí)現(xiàn)XML Web Service的類(lèi)的名稱(chēng),wsdl:portType 的名稱(chēng)。缺省值為 Java 類(lèi)的簡(jiǎn)單名稱(chēng) + Service。(字符串)
4、portName: wsdl:portName。缺省值為 WebService.name+Port。
5、targetNamespace:指定你想要的名稱(chēng)空間,默認(rèn)是使用接口實(shí)現(xiàn)類(lèi)的包名的反綴
6、wsdlLocation:指定用于定義 Web Service 的 WSDL 文檔的 Web 地址。Web 地址可以是相對(duì)路徑或絕對(duì)路徑。(字符串)
注意:實(shí)現(xiàn)類(lèi)上可以不添加Webservice注解
2)@WebMethod
注釋表示作為一項(xiàng) Web Service 操作的方法,將此注釋?xiě)?yīng)用于客戶(hù)機(jī)或服務(wù)器服務(wù)端點(diǎn)接口(SEI)上的方法,或者應(yīng)用于 JavaBeans 端點(diǎn)的服務(wù)器端點(diǎn)實(shí)現(xiàn)類(lèi)。
要點(diǎn): 僅支持在使用 @WebService 注釋來(lái)注釋的類(lèi)上使用 @WebMethod 注釋
1、operationName:指定與此方法相匹配的wsdl:operation 的名稱(chēng)。缺省值為 Java 方法的名稱(chēng)。(字符串)
2、action:定義此操作的行為。對(duì)于 SOAP 綁定,此值將確定 SOAPAction 頭的值。缺省值為 Java 方法的名稱(chēng)。(字符串)
3、exclude:指定是否從 Web Service 中排除某一方法。缺省值為 false。(布爾值)
3)@Oneway
注釋將一個(gè)方法表示為只有輸入消息而沒(méi)有輸出消息的 Web Service 單向操作。
將此注釋?xiě)?yīng)用于客戶(hù)機(jī)或服務(wù)器服務(wù)端點(diǎn)接口(SEI)上的方法,或者應(yīng)用于 JavaBeans 端點(diǎn)的服務(wù)器端點(diǎn)實(shí)現(xiàn)類(lèi)
4)@WebParam
注釋用于定制從單個(gè)參數(shù)至 Web Service 消息部件和 XML 元素的映射。
將此注釋?xiě)?yīng)用于客戶(hù)機(jī)或服務(wù)器服務(wù)端點(diǎn)接口(SEI)上的方法,或者應(yīng)用于 JavaBeans 端點(diǎn)的服務(wù)器端點(diǎn)實(shí)現(xiàn)類(lèi)。
1、name :參數(shù)的名稱(chēng)。如果操作是遠(yuǎn)程過(guò)程調(diào)用(RPC)類(lèi)型并且未指定partName 屬性,那么這是用于表示參數(shù)的 wsdl:part 屬性的名稱(chēng)。如果操作是文檔類(lèi)型或者參數(shù)映射至某個(gè)頭,那么 -name 是用于表示該參數(shù)的 XML 元素的局部名稱(chēng)。如果操作是文檔類(lèi)型、參數(shù)類(lèi)型為 BARE 并且方式為 OUT 或 INOUT,那么必須指定此屬性。(字符串)
2、partName:定義用于表示此參數(shù)的 wsdl:part屬性的名稱(chēng)。僅當(dāng)操作類(lèi)型為 RPC 或者操作是文檔類(lèi)型并且參數(shù)類(lèi)型為BARE 時(shí)才使用此參數(shù)。(字符串)
3、targetNamespace:指定參數(shù)的 XML 元素的 XML 名稱(chēng)空間。當(dāng)屬性映射至 XML 元素時(shí),僅應(yīng)用于文檔綁定。缺省值為 Web Service 的targetNamespace。(字符串)
4、mode:此值表示此方法的參數(shù)流的方向。有效值為 IN、INOUT 和 OUT。(字符串)
5、header:指定參數(shù)是在消息頭還是消息體中。缺省值為 false。(布爾值)
5)@WebResult
注釋用于定制從返回值至 WSDL 部件或 XML 元素的映射。將此注釋?xiě)?yīng)用于客戶(hù)機(jī)或服務(wù)器服務(wù)端點(diǎn)接口(SEI)上的方法,或者應(yīng)用于 JavaBeans 端點(diǎn)的服務(wù)器端點(diǎn)實(shí)現(xiàn)類(lèi)。
1、name:當(dāng)返回值列示在 WSDL 文件中并且在連接上的消息中找到該返回值時(shí),指定該返回值的名稱(chēng)。對(duì)于 RPC 綁定,這是用于表示返回值的 wsdl:part屬性的名稱(chēng)。對(duì)于文檔綁定,-name參數(shù)是用于表示返回值的 XML 元素的局部名。對(duì)于 RPC 和 DOCUMENT/WRAPPED 綁定,缺省值為 return。對(duì)于 DOCUMENT/BARE 綁定,缺省值為方法名 + Response。(字符串)
2、targetNamespace:指定返回值的 XML 名稱(chēng)空間。僅當(dāng)操作類(lèi)型為 RPC 或者操作是文檔類(lèi)型并且參數(shù)類(lèi)型為 BARE 時(shí)才使用此參數(shù)。(字符串)
3、header:指定頭中是否附帶結(jié)果。缺省值為false。(布爾值)
4、partName:指定 RPC 或 DOCUMENT/BARE 操作的結(jié)果的部件名稱(chēng)。缺省值為@WebResult.name。(字符串)
6)@HandlerChain
注釋用于使 Web Service 與外部定義的處理程序鏈相關(guān)聯(lián)。只能通過(guò)對(duì) SEI 或?qū)崿F(xiàn)類(lèi)使用 @HandlerChain 注釋來(lái)配置服務(wù)器端的處理程序。
但是可以使用多種方法來(lái)配置客戶(hù)端的處理程序??梢酝ㄟ^(guò)對(duì)生成的服務(wù)類(lèi)或者 SEI 使用 @HandlerChain 注釋來(lái)配置客戶(hù)端的處理程序。此外,可以按程序在服務(wù)上注冊(cè)您自己的 HandlerResolver 接口實(shí)現(xiàn),或者按程序在綁定對(duì)象上設(shè)置處理程序鏈。
1、file:指定處理程序鏈文件所在的位置。文件位置可以是采用外部格式的絕對(duì) java.net.URL,也可以是類(lèi)文件中的相對(duì)路徑。(字符串)
2、name:指定配置文件中處理程序鏈的名稱(chēng)。
/** * WebService涉及到的有這些 "四解三類(lèi) ", 即四個(gè)注解,三個(gè)類(lèi) * @WebMethod * @WebService * @WebResult * @WebParam * SpringBus * Endpoint * EndpointImpl * * 一般我們都會(huì)寫(xiě)一個(gè)接口,然后再寫(xiě)一個(gè)實(shí)現(xiàn)接口的實(shí)現(xiàn)類(lèi),但是這不是強(qiáng)制性的 * @WebService 注解表明是一個(gè)webservice服務(wù)。 * name:對(duì)外發(fā)布的服務(wù)名, 對(duì)應(yīng)于<wsdl:portType name="ServerServiceDemo"></wsdl:portType> * targetNamespace:命名空間,一般是接口的包名倒序, 實(shí)現(xiàn)類(lèi)與接口類(lèi)的這個(gè)配置一定要一致這種錯(cuò)誤 * Exception in thread "main" org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name xxxx * 對(duì)應(yīng)于targetNamespace="http://server.webservice.example.com" * endpointInterface:服務(wù)接口全路徑(如果是沒(méi)有接口,直接寫(xiě)實(shí)現(xiàn)類(lèi)的,該屬性不用配置), 指定做SEI(Service EndPoint Interface)服務(wù)端點(diǎn)接口 * serviceName:對(duì)應(yīng)于<wsdl:service name="ServerServiceDemoImplService"></wsdl:service> * portName:對(duì)應(yīng)于<wsdl:port binding="tns:ServerServiceDemoImplServiceSoapBinding" name="ServerServiceDemoPort"></wsdl:port> * * @WebMethod 表示暴露的服務(wù)方法, 這里有接口ServerServiceDemo存在,在接口方法已加上@WebMethod, 所以在實(shí)現(xiàn)類(lèi)中不用再加上,否則就要加上 * operationName: 接口的方法名 * action: 沒(méi)發(fā)現(xiàn)又什么用處 * exclude: 默認(rèn)是false, 用于阻止將某一繼承方法公開(kāi)為web服務(wù) * * @WebResult 表示方法的返回值 * name:返回值的名稱(chēng) * partName: * targetNamespace: * header: 默認(rèn)是false, 是否將參數(shù)放到頭信息中,用于保護(hù)參數(shù),默認(rèn)在body中 * * @WebParam * name:接口的參數(shù) * partName: * targetNamespace: * header: 默認(rèn)是false, 是否將參數(shù)放到頭信息中,用于保護(hù)參數(shù),默認(rèn)在body中 * model:WebParam.Mode.IN/OUT/INOUT */
使用步驟:
1)創(chuàng)建接口:
@WebService(name = "UserSSSS" ,targetNamespace ="http://data.fucker.mother.com") public interface UserService { User getUser(String userName); }
2)創(chuàng)建實(shí)現(xiàn)類(lèi):
@Service @WebService(name = "UserSSSS" , targetNamespace ="http://data.fucker.mother.com", endpointInterface = "com.mother.fucker.data.service.UserService") public class UserServerImpl implements UserService { @Override @WebMethod(operationName = "getUser") @WebResult(name = "User") public User getUser(@WebParam(name = "userName") String userName) { return new User("姓名","年齡","性別","工作"); } }
3)創(chuàng)建身份認(rèn)證攔截器:(不需要可以不創(chuàng)建)
import lombok.extern.slf4j.Slf4j; 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.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; @Component @Slf4j public class WebServiceAuthInterceptor extends AbstractPhaseInterceptor<SoapMessage> { /** * 用戶(hù)名 */ private static final String USER_NAME = "wangdi"; /** * 密碼 */ private static final String USER_PASSWORD = "wangdi.com"; private static final String NAME_SPACE_URI = "http://data.fucker.mother.com"; /** * 創(chuàng)建攔截器 */ private SAAJInInterceptor interceptor = new SAAJInInterceptor(); public WebServiceAuthInterceptor() { super(Phase.PRE_PROTOCOL); //添加攔截 super.getAfter().add(SAAJInInterceptor.class.getName()); } @Override public void handleMessage(SoapMessage message) throws Fault { //獲取指定消息 SOAPMessage soapMessage = message.getContent(SOAPMessage.class); if (null == soapMessage) { this.interceptor.handleMessage(message); soapMessage = message.getContent(SOAPMessage.class); } //SOAP頭信息 SOAPHeader header = null; try { header = soapMessage.getSOAPHeader(); } catch (SOAPException e) { e.printStackTrace(); } if (null == header) { throw new Fault(new IllegalAccessException("沒(méi)有Header信息,無(wú)法實(shí)現(xiàn)用戶(hù)認(rèn)證處理!")); } //SOAP是基于XML文件結(jié)構(gòu)進(jìn)行傳輸?shù)?,所以如果要想獲取認(rèn)證信息就必須進(jìn)行相關(guān)的結(jié)構(gòu)約定 NodeList usernameNodeList = header.getElementsByTagNameNS(NAME_SPACE_URI, "username"); NodeList passwordNodeList = header.getElementsByTagNameNS(NAME_SPACE_URI, "password"); if (usernameNodeList.getLength() < 1) { throw new Fault(new IllegalAccessException("沒(méi)有用戶(hù)信息,無(wú)法實(shí)現(xiàn)用戶(hù)認(rèn)證處理!")); } if (passwordNodeList.getLength() < 1) { throw new Fault(new IllegalAccessException("沒(méi)有密碼信息,無(wú)法實(shí)現(xiàn)用戶(hù)認(rèn)證處理!")); } String username = usernameNodeList.item(0).getTextContent().trim(); String password = passwordNodeList.item(0).getTextContent().trim(); if (USER_NAME.equals(username) && USER_PASSWORD.equals(password)) { log.info("用戶(hù)訪(fǎng)問(wèn)認(rèn)證成功!"); } else { SOAPException soapException = new SOAPException("用戶(hù)認(rèn)證失敗!"); log.info("用戶(hù)認(rèn)證失敗!"); throw new Fault(soapException); } } }
4)創(chuàng)建配置類(lèi):
import com.mother.fucker.data.AuthInterceptor.WebServiceAuthInterceptor; import com.mother.fucker.data.service.UserService; import lombok.RequiredArgsConstructor; import org.apache.cxf.Bus; import org.apache.cxf.bus.spring.SpringBus; 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 @RequiredArgsConstructor public class CxfConfig { private final UserService userServer; @Autowired private WebServiceAuthInterceptor interceptor; /** * 注入Servlet,注意beanName不能為dispatcherServlet * @author Fang Ruichuan * @date 2022/11/14 19:16 */ @Bean public ServletRegistrationBean cxfServlet() { return new ServletRegistrationBean(new CXFServlet(), "/webservice/*"); } @Bean(name = Bus.DEFAULT_BUS_ID) public SpringBus springBus() { return new SpringBus(); } @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus(), userServer); endpoint.publish("/api"); endpoint.getInInterceptors().add(this.interceptor); return endpoint; } /*用于發(fā)布多個(gè)WebService*/ // @Bean // public Endpoint messageEndPoint2() { // EndpointImpl endpoint = new EndpointImpl(springBus(), this.ageInfoService); // endpoint.publish("/userInfoService"); endpoint.getInInterceptors().add(this.interceptor); // return endpoint; // } }
5)創(chuàng)建客戶(hù)端攔截器:(如有需要)
import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; import org.apache.cxf.headers.Header; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.namespace.QName; import java.util.List; public class ClientLoginInterceptor extends AbstractPhaseInterceptor<SoapMessage> { private String username; private String password; private static final String NAME_SPACE_URI = "http://data.fucker.mother.com"; public ClientLoginInterceptor(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 document = DOMUtils.createDocument(); Element authority = document.createElementNS(NAME_SPACE_URI, "authority"); Element username = document.createElementNS(NAME_SPACE_URI, "username"); Element password = document.createElementNS(NAME_SPACE_URI, "password"); username.setTextContent(this.username); password.setTextContent(this.password); authority.appendChild(username); authority.appendChild(password); headers.add(0, new Header(new QName("authority"), authority)); } }
6) 新建客戶(hù)端調(diào)用接口(使用動(dòng)態(tài)代理)
/** * 用戶(hù)名 */ private static final String USER_NAME = "wangdi"; /** * 密碼 */ private static final String USER_PASSWORD = "wangdi.com"; private static final String NAME_SPACE_URI = "http://server.webservice.gtp.sinotrans.com"; public static void main(String[] args) { //打印日志 LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); List<Logger> loggerList = loggerContext.getLoggerList(); loggerList.forEach(logger -> {logger.setLevel(Level.INFO); }); JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient("http://localhost:8001/webservice/api?wsdl"); try { client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, USER_PASSWORD)); Object[] objects = client.invoke("getUser","aaa"); System.out.println(JSON.toJSONString(objects[0])); } catch (Exception e) { e.printStackTrace();; } }
7)當(dāng)webservcie中參數(shù)是復(fù)雜類(lèi)型的是:
@Override @WebMethod(operationName = "getUser") public User getUser(@WebParam(name = "userName") User userName) { return new User("姓名","年齡","性別","工作"); }
需要這樣調(diào)用:
//打印日志 // LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); // List<Logger> loggerList = loggerContext.getLoggerList(); // loggerList.forEach(logger -> {logger.setLevel(Level.INFO); }); JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client = dcf.createClient("http://localhost:1001/webservice/api?wsdl"); try { //通過(guò)反射,創(chuàng)建OrderInfo對(duì)象,com.limp.service.OrderInfo 這個(gè)包名稱(chēng)必須和webservice的中的order路徑一致 Object user = Thread.currentThread().getContextClassLoader(). loadClass("com.mother.fucker.data.User").newInstance(); //初始化實(shí)體對(duì)象 Method m = user.getClass().getMethod("setName", String.class); m.invoke(user, "uuid213-281heq-2131"); Object[] objects = client.invoke("getUser",user); System.out.println(JSON.toJSONString(objects[0])); } catch (Exception e) { e.printStackTrace();; }
總結(jié)
到此這篇關(guān)于springboot整合webservice使用的文章就介紹到這了,更多相關(guān)springboot整合webservice內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring boot webService使用方法解析
- SpringBoot調(diào)用第三方WebService接口的操作技巧(.wsdl與.asmx類(lèi)型)
- SpringBoot整合WebService的實(shí)現(xiàn)示例
- SpringBoot創(chuàng)建WebService方法詳解
- SpringBoot調(diào)用第三方WebService接口的兩種方法
- SpringBoot調(diào)用對(duì)方webService接口的幾種方法示例
- SpringBoot整合WebService的實(shí)戰(zhàn)案例
- Java(Springboot)項(xiàng)目調(diào)用第三方WebService接口實(shí)現(xiàn)代碼
相關(guān)文章
一篇文章了解Jackson注解@JsonFormat及失效解決辦法
這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章了解Jackson注解@JsonFormat及失效解決辦法的相關(guān)資料,@JsonFormat注解是一個(gè)時(shí)間格式化注解,用于格式化時(shí)間,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-11-11徹底解決Spring mvc中時(shí)間的轉(zhuǎn)換和序列化等問(wèn)題
這篇文章主要介紹了徹底解決Spring mvc中時(shí)間的轉(zhuǎn)換和序列化等問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09Java中LinkedHashSet的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Java中LinkedHasSet的實(shí)現(xiàn)原理詳解,LinkedHashSet?是具有可預(yù)知迭代順序的?Set?接口的哈希表和鏈接列表實(shí)現(xiàn),此實(shí)現(xiàn)與HashSet?的不同之處在于,后者維護(hù)著一個(gè)運(yùn)行于所有條目的雙重鏈接列表,需要的朋友可以參考下2023-09-09Spring Boot整合JPA使用多個(gè)數(shù)據(jù)源的方法步驟
這篇文章主要給大家介紹了關(guān)于Spring Boot整合JPA使用多個(gè)數(shù)據(jù)源的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08SpringSecurity多認(rèn)證器配置多模式登錄自定義認(rèn)證器方式
這篇文章主要介紹了SpringSecurity多認(rèn)證器配置多模式登錄自定義認(rèn)證器方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-0423種設(shè)計(jì)模式(19)java責(zé)任鏈模式
這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java責(zé)任鏈模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01短網(wǎng)址的原理與生成方法(Java實(shí)現(xiàn))
這篇文章主要給大家介紹了關(guān)于短網(wǎng)址的原理與生成方法,利用的是Java實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10