標籤:error php font generate pos 注意 wsdl 而且 return
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端:
- <?php
- //header("Content-Type:text/html;charset=UTF-8");
-
- // Pull in the NuSOAP code
- require_once(‘./lib/nusoap.php‘);
-
- // Define the method as a PHP function
- function hello($name) {
- return ‘你好! ‘ . $name;
- }
-
- // Create the server instance
- $server = new soap_server;
-
- $server->configureWSDL(‘hellowsdl‘, ‘urn:hellowsdl‘);
- $server->wsdl->schemaTargetNamespace = ‘urn:hellowsdl‘;
-
- // Register the method to expose
- $server->register(‘hello‘,
- array(‘name‘=>‘xsd:string‘),
- array(‘return‘=>‘xsd:string‘),
- ‘urn:hellowsdl‘,
- ‘urn:hellowsdl#hello‘,
- ‘rpc‘,
- ‘encoded‘,
- ‘Say hello to somebody‘
- );
-
- // Use the request to (try to) invoke the service
- $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ‘‘;
- $server->service($HTTP_RAW_POST_DATA);
- ?>
Client 端:
- <?php
- //header("Content-Type:text/html;charset=GB2312");
- // Pull in the NuSOAP code
- require_once(‘./lib/nusoap.php‘);
- // Create the client instance
- $client = new soapclient(‘http://localhost/soapTest/helloService.php?wsdl‘,true);
- // Call the SOAP method
- $param = array("name"=>"安迪");
- $result = $client->call(‘hello‘, $param);
- // Display the result
- //print_r($result);
-
- if(!$err=$client->getError()){
- print_r($result );
- print(‘</br>‘);
- echo "程式返回: ", htmlentities($result,ENT_QUOTES,GB2312);
- }
- else{
- echo "錯誤: ", htmlentities($result,ENT_QUOTES,GB2312);
- }
-
- echo ‘ <h2> Request </h2> <pre> ‘ . htmlspecialchars($client-> request, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
- echo ‘ <h2> Response </h2> <pre> ‘ . htmlspecialchars($client-> response, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
- echo ‘ <h2> Debug </h2> <pre> ‘ . htmlspecialchars($client-> debug_str, ENT_QUOTES,GB2312) . ‘ </pre> ‘;
-
- ?>
Java代碼:
注意: 要使用Axis1.x, 去官網不要下載了Axis2。好像Axis1.x 和 Axis2還是差別很大的,而且目前Axis1.x的文檔比較全點。這些是網上搜到的說法。
如果需要使用中文參數調用Web Service,必須使用ISO-8859-1編碼參數,返回的Response再解碼。不要使用別的編碼,會出錯!
java代碼
...
java代碼
- import org.apache.axis.client.Service;
-
- <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>
-
- public class WebServiceTest {
- public static void main(String[] args) {
- String endpoint = "http://localhost/soapTest/helloService.php";
- //String endpoint = "http://testweb.dev.php/testWebService/testWebService.php";//該段就是上面剛將的地址
- Service service = new Service();
- Call call;
- try {
- call = (Call) service.createCall();
- call.setTargetEndpointAddress(new java.net.URL(endpoint));
- call.setOperationName("hello");
-
-
- String param = new String("安迪".getBytes(),"ISO-8859-1");//如果沒有加這段,中文參數將會亂碼
- //String param = new String("中文");
- String s = (String) call.invoke(new Object[] {param});
- s = new String(s.getBytes("ISO-8859-1"));//如果沒有轉換編碼,中文也會亂碼
- System.out.println(s);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
Java 調用PHP的Web Service(三)