1. 程式人生 > >Java 調用PHP的Web Service(三)

Java 調用PHP的Web Service(三)

ron eight pad rgs asc ali auto mat 請求

usoap是PHP環境中的開源soap工具,算是用得比較多的一個工具了。

在utf-8環境中,nusoap可以工作得很好。但是當用於中文環境中時,nusoap經常會出現一些讓人不得其解的問題。

最近一個項目中,服務端是用nusoap實現的,支持UTF-8和GBK兩種字符集。

當客戶端用GBK來調用服務時,出現錯誤:Charset from HTTP Content-Type US-ASCII does not match encoding from XML declaration GBK,意思是說,客戶端的請求中,HTTP Content-Type的字符集是US-ASCII,而soap請求的XML聲明裏,字符集是GBK,兩者不匹配。檢查soap client的request變量,HTTP Content-Type的值也是GBK,怎麽會變成了US-ASCII呢?有點莫名其妙了。於是只好跟蹤nusoap的源碼,發現nusoap在處理HTTP Content-Type時把US-ASCII,ISO-8859-1,UTF-8以外的字符集都默認為US-ASCII。最終發現其原因是因為nusoap使用了xml parser,而xml parser只支持這幾種字符集。所以客戶端在調用時,當采用GBK編時,調用的HTTP Content-Type 和 soap request的字符集都應該換成ISO-8859-1。

稍後在封裝客戶端時,也遇到一個類似的問題。客戶端字符集聲明為GBK,服務端在返回SOAP調用結果時 HTTP Content-Type和soap request都聲明字符集為GBK,客戶端沒有獲取任何值。查看soap client的response對象,發現服務端返回正確。為解決這個問題,只好修改服務端,把HTTP Content-Type和soap response的字符集都聲明為ISO-8859-1。

所以在使用nusoap時,當遇到GBK或GB2312字符集時,可以使用ISO-8859-1代替。

=============================================================================================

PHP Web Service Server端:

  1. <?php
  2. //header("Content-Type:text/html;charset=UTF-8");
  3. // Pull in the NuSOAP code
  4. require_once(‘./lib/nusoap.php‘);
  5. // Define the method as a PHP function
  6. function hello($name) {
  7. return ‘你好! ‘ . $name;
  8. }
  9. // Create the server instance
  10. $server = new soap_server;
  11. $server->configureWSDL(‘hellowsdl‘, ‘urn:hellowsdl‘);
  12. $server->wsdl->schemaTargetNamespace = ‘urn:hellowsdl‘;
  13. // Register the method to expose
  14. $server->register(‘hello‘,
  15. array(‘name‘=>‘xsd:string‘),
  16. array(‘return‘=>‘xsd:string‘),
  17. ‘urn:hellowsdl‘,
  18. ‘urn:hellowsdl#hello‘,
  19. ‘rpc‘,
  20. ‘encoded‘,
  21. ‘Say hello to somebody‘
  22. );
  23. // Use the request to (try to) invoke the service
  24. $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ‘‘;
  25. $server->service($HTTP_RAW_POST_DATA);
  26. ?>

Client 端:

  1. <?php
  2. //header("Content-Type:text/html;charset=GB2312");
  3. // Pull in the NuSOAP code
  4. require_once(‘./lib/nusoap.php‘);
  5. // Create the client instance
  6. $client = new soapclient(‘http://localhost/soapTest/helloService.php?wsdl‘,true);
  7. // Call the SOAP method
  8. $param = array("name"=>"安迪");
  9. $result = $client->call(‘hello‘, $param);
  10. // Display the result
  11. //print_r($result);
  12. if(!$err=$client->getError()){
  13. print_r($result );
  14. print(‘</br>‘);
  15. echo "程序返回: ", htmlentities($result,ENT_QUOTES,GB2312);
  16. }
  17. else{
  18. echo "錯誤: ", htmlentities($result,ENT_QUOTES,GB2312);
  19. }
  20. echo ‘ <h2> Request </h2> <pre> ‘ . htmlspecialchars($client-> request, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
  21. echo ‘ <h2> Response </h2> <pre> ‘ . htmlspecialchars($client-> response, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
  22. echo ‘ <h2> Debug </h2> <pre> ‘ . htmlspecialchars($client-> debug_str, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
  23. ?>

Java代碼:

註意: 要使用Axis1.x, 去官網不要下載了Axis2。好像Axis1.x 和 Axis2還是差別很大的,而且目前Axis1.x的文檔比較全點。這些是網上搜到的說法。

如果需要使用中文參數調用Web Service,必須使用ISO-8859-1編碼參數,返回的Response再解碼。不要使用別的編碼,會出錯!

java代碼

...

java代碼

  1. import org.apache.axis.client.Service;
  2. <span style="color: #464646; font-family: simsun; line-height: 21px; text-align: left; white-space: normal; background-color: #ffffff;">import org.apache.axis.client.Call;</span>
  3. public class WebServiceTest {
  4. public static void main(String[] args) {
  5. String endpoint = "http://localhost/soapTest/helloService.php";
  6. //String endpoint = "http://testweb.dev.php/testWebService/testWebService.php";//該段就是上面剛將的地址
  7. Service service = new Service();
  8. Call call;
  9. try {
  10. call = (Call) service.createCall();
  11. call.setTargetEndpointAddress(new java.net.URL(endpoint));
  12. call.setOperationName("hello");
  13. String param = new String("安迪".getBytes(),"ISO-8859-1");//如果沒有加這段,中文參數將會亂碼
  14. //String param = new String("中文");
  15. String s = (String) call.invoke(new Object[] {param});
  16. s = new String(s.getBytes("ISO-8859-1"));//如果沒有轉換編碼,中文也會亂碼
  17. System.out.println(s);
  18. } catch (Exception e) {
  19. // TODO Auto-generated catch block
  20. e.printStackTrace();
  21. }
  22. }
  23. }

Java 調用PHP的Web Service(三)