CXF客戶端動態呼叫
阿新 • • 發佈:2019-02-14
問題一:
使用CXF實現WebService,並在客戶端實現動態呼叫編寫伺服器注意事項
注意 :不要指定
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
因為cxf 不支援:rpc、encoded,在動態客戶呼叫過程。
問題二:
Caused by: javax.xml.bind.UnmarshalException
這種xml格式化標籤的異常, 因此傳遞帶有html標籤的html格式資料的時候, 可能會遇到這種問題, ,將html標籤格式的資料轉換成字串, 然後傳遞給webservice, 然後在webservice端再進行解碼。
BASE64Encoder encoder = new BASE64Encoder();
String content = encoder.encode(str.getBytes("UTF-8"));
BASE64Decoder decoder = new BASE64Decoder();
new String(decoder.decodeBuffer(content), "UTF-8")
這樣就解決了webservice接收 html標籤格式資料的問題.
問題三:動態呼叫響應緩慢,CXF傳送、接收訊息超時設定
java中設定
//設定超時單位為毫秒 預設是30000毫秒,即30秒。
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(3000); //連線超時 預設是60000毫秒,即60秒.
httpClientPolicy.setAllowChunking(false); //取消塊編碼
httpClientPolicy.setReceiveTimeout(3000 ); //響應超時
http.setClient(httpClientPolicy);
spring 中配置設定
spring+cxf配置方式:
Xml程式碼 收藏程式碼
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd ">
<http-conf:conduit name="{WSDL Namespace}portName.http-conduit">
<http-conf:client ConnectionTimeout="10000" ReceiveTimeout="20000"/>
</http-conf:conduit>
</beans>
問題四:傳遞基本屬性
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://127.0.0.1:9000/hello?wsdl");
Object[] objects=client.invoke("sayHello", "張三");
Object[] objects1=client.invoke("sayHello2", "李四");
System.out.println(objects[0].toString()+" "+objects1[0].toString());
問題五:傳遞物件
方法一:已知實體類所在的包及類名及各個屬性
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8080/OrderProcess?wsdl");
//已知service類所在的包server.Order 建立實體類
Object order = Thread.currentThread().getContextClassLoader().loadClass("server.Order").newInstance();
Method m1 = order.getClass().getMethod("setCustomerID", String.class);
Method m2 = order.getClass().getMethod("setItemID", String.class);
Method m3 = order.getClass().getMethod("setQty", Integer.class);
Method m4 = order.getClass().getMethod("setPrice", Double.class);
m1.invoke(order, "C001");
m2.invoke(order, "I001");
m3.invoke(order, 100);
m4.invoke(order, 200.00);
Object[] response = client.invoke("processOrder", order);
System.out.println("Response is " + response[0]);
方法二:已知service實現類所在的包以及物件屬性
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8080/OrderProcess?wsdl");
Endpoint endpoint = client.getEndpoint();
// Make use of CXF service model to introspect the existing WSDL
ServiceInfo serviceInfo = endpoint.getService().getServiceInfos().get(0);
QName bindingName = new QName("http://server/", "OrderProcessServiceSoapBinding");
BindingInfo binding = serviceInfo.getBinding(bindingName);
//繫結方法
QName methodName = new QName("http://server/", "processOrder");
BindingOperationInfo boi = binding.getOperation(methodName); // Operation name is processOrder
BindingMessageInfo inputMessageInfo = null;
if (!boi.isUnwrapped()) {
//OrderProcess uses document literal wrapped style.
inputMessageInfo = boi.getWrappedOperation().getInput();
} else {
inputMessageInfo = boi.getUnwrappedOperation().getInput();
}
List<MessagePartInfo> parts = inputMessageInfo.getMessageParts();
//得到第一個引數,以下是對第一個引數的操作。此處只有一個引數
MessagePartInfo partInfo = parts.get(0); // Input class is Order
// Get the input class Order
Class<?> orderClass = partInfo.getTypeClass();
Object orderObject = orderClass.newInstance();
// Populate the Order bean
// Set customer ID, item ID, price and quantity
PropertyDescriptor custProperty = new PropertyDescriptor("customerID", orderClass);
custProperty.getWriteMethod().invoke(orderObject, "C001");
PropertyDescriptor itemProperty = new PropertyDescriptor("itemID", orderClass);
itemProperty.getWriteMethod().invoke(orderObject, "I001");
PropertyDescriptor priceProperty = new PropertyDescriptor("price", orderClass);
priceProperty.getWriteMethod().invoke(orderObject, Double.valueOf(100.00));
PropertyDescriptor qtyProperty = new PropertyDescriptor("qty", orderClass);
qtyProperty.getWriteMethod().invoke(orderObject, Integer.valueOf(20));
// Invoke the processOrder() method and print the result
// The response class is String
Object[] result = client.invoke(methodName, orderObject);
System.out.println("The order ID is " + result[0]);