从SOAP迁移到REST
本文关键字:REST 迁移 SOAP | 更新日期: 2023-09-27 17:58:18
我有一个与C#Web服务通信的Android项目。通信通过HTTPPost(SOAP方式)进行。我将xml形式的请求发送到服务器,并以xml形式获得响应。我使用以下方法进行通信:
public static BasicHttpResponse getResponse(String uri,
String SOAPRequestXML) throws ClientProtocolException, Exception {
HttpPost httppost = new HttpPost(uri);
StringEntity se = null;
try {
se = new StringEntity(SOAPRequestXML, HTTP.UTF_8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
se.setContentType("Text/Xml");
httppost.setHeader("Content-Type", "Text/Xml");
httppost.setEntity(se);
HttpClient httpclient = new DefaultHttpClient();
BasicHttpResponse httpResponse = null;
httpResponse = (BasicHttpResponse) httpclient.execute(httppost);
return httpResponse;
}
现在我想把这个soap代码移到REST。为此,我需要修改什么?我需要更改我的c#webservice项目吗?请解释如何迁移到RestFul服务。
首先,请阅读什么是REST以及RESTful的含义:RESTful编程究竟是什么
总之,这在很大程度上意味着URL将发生变化。使用XML或JSON并不重要,因为应该可以快速切换。
另一件事是,在我看来,不应该对字符串对象进行操作,而应该对可序列化对象进行操作
Class ContainerWithData implements Serializable {
private Integer a;
private Integer b;
private String c;
// Remember that it can be null values up here
// Getters and setters below
}
为了避免手动创建代码,您可以签出http://projects.spring.io/spring-android/或Android HTTP客户端以及Gson或其他库一些演示(用于检查代码)可以在https://bitbucket.org/bartosz_bednarek/easy-android-and-java-http-client-for-soap-and-restful-api/wiki/Home.对于XML或JSON,Spring库中有支持,或者您可以找到其他库。
如果您希望手动创建HTTP客户端代码,有很多可能性;例如:
也许这样的界面会对你有所帮助:
interface SimpleHttpClient {
<T> T get(String url, Class<T> classe) throws IOException;
<T> T post(String url, Class<T> classe, Serializable contentOrJson) throws IOException;
<T> T put(String url, Class<T> classe, Serializable contentOrJson) throws IOException;
void delete(String url, Serializable contentOrJson) throws IOException;
}
在这种情况下,可能会有,例如:
public abstract class EasyHttpClient implements SimpleHttpClient {
private EasyHttpClientRequest request = new EasyHttpClientRequest();
private EasyHttpClientGetRequest requestToGet = new EasyHttpClientGetRequest();
protected synchronized String get(String url) throws IOException {
return requestToGet.getRequest(url);
}
protected synchronized String post(String url, String contentOrJson)
throws IOException {
return request.doReguest(url, contentOrJson, "POST", getMimeType());
}
protected synchronized String put(String url, String contentOrJson)
throws IOException {
return request.doReguest(url, contentOrJson, "PUT", getMimeType());
}
protected synchronized void deleteRequest(String url, String contentOrJson) throws IOException {
request.doReguest(url, contentOrJson, "DELETE", getMimeType());
}
}
获取:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
public class EasyHttpClientGetRequest {
public String getRequest(String url) throws MalformedURLException, IOException{
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is,
Charset.forName("UTF-8")));
String jsonText = readAll(rd);
return jsonText;
} finally {
is.close();
}
}
/**
* Will get {@link String} from {@link Reader} assuming that {@link Byte} in
* {@link Reader} are char representation.
*/
private synchronized String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
}
其他如POST/PUT/DELETE:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
public final class EasyHttpClientRequest {
/**
* Will perform HTTP request to server based on the parameters that has been
* declared.
*
* @param url
* - URL for connect to.
* @param contentOrJson
* - content in String or JSON format
* @param method
* - "DELETE" / "POST" / "PUT" for sending data.
* @param mime
* - mime type in format of Content-Type.
* @return content of the request as String or null if no content.
* @throws IOException
* if there will be error during communication.
*/
public synchronized String doReguest(String url, String contentOrJson, String method, String mime)
throws IOException {
URL url1;
HttpURLConnection connection = null;
try {
// Create connection
url1 = new URL(url);
connection = (HttpURLConnection) url1.openConnection();
connection.setRequestMethod(method);
connection.setRequestProperty("Content-Type", mime);
connection.setRequestProperty("Content-Length",
"" + Integer.toString(contentOrJson.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(contentOrJson);
wr.flush();
wr.close();
// Get Response
InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append(''r');
}
rd.close();
return response.toString();
} catch (ProtocolException e) {
return checkProtocolOrReturn(method);
} catch (Exception e) {
throw new IOException("Invalid!");
} finally {
tryToCloseConnection(connection);
}
}
/**
* Checks if method is "DELETE" or returns null. It is done bcs DELETE has
* no content. Invoked after {@link ProtocolException}
*
* @param method
* representation ex. "DELETE"
* @return null if not Delete.
* @throws IOException
*/
private String checkProtocolOrReturn(String method) throws IOException {
if (!method.equals("DELETE")) {
throw new IOException("Invalid!");
} else {
return null;
}
}
/**
* Will try to close connection if it is not closed already.
*
*/
private void tryToCloseConnection(HttpURLConnection connection) {
if (connection != null) {
connection.disconnect();
}
}
}
本例中的URL上限可能不是最好的解决方案,因为您必须自己关心授权并记住超时,但这是一个建议。