Sha*_*aul 5 java android httpurlconnection android-asynctask
我有多个活动的每一个来自不同的URL和不同的HTTP方法,如获得不同的数据POST,GET,PUT,DELETE,等一些要求有标题的数据,而一些有身体,有些人可能兼得.我正在使用AsyncTask具有多个构造函数的单个类来传递活动中的数据,以便我可以将它们添加到HttpUrlConnection实例中.
我尝试了这个教程:http://cyriltata.blogspot.in/2013/10/android-re-using-asynctask-class-across.html.
但上面的教程使用HttpClient和NameValuePair.我替换NameValuePair了Pair.但我发现很难实现相同的逻辑,HttpUrlConnection因为我需要POST在我的请求中添加多个数据和标题.
但返回的String是空的.如何正确实施此方案?
完整代码:
public class APIAccessTask extends AsyncTask<String,Void,String> {
URL requestUrl;
Context context;
HttpURLConnection urlConnection;
List<Pair<String,String>> postData, headerData;
String method;
int responseCode = HttpURLConnection.HTTP_NOT_FOUND;
APIAccessTask(Context context, String requestUrl, String method){
this.context = context;
this.method = method;
try {
this.requestUrl = new URL(requestUrl);
}
catch(Exception ex){
ex.printStackTrace();
}
}
APIAccessTask(Context context, String requestUrl, String method, List<Pair<String,String>> postData,){
this(context, requestUrl, method);
this.postData = postData;
}
APIAccessTask(Context context, String requestUrl, String method, List<Pair<String,String>> postData,
List<Pair<String,String>> headerData){
this(context, requestUrl,method,postData);
this.headerData = headerData;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
setupConnection();
if(method.equals("POST"))
{
return httpPost();
}
if(method.equals("GET"))
{
return httpGet();
}
if(method.equals("PUT"))
{
return httpPut();
}
if(method.equals("DELETE"))
{
return httpDelete();
}
if(method.equals("PATCH"))
{
return httpPatch();
}
return null;
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(context,result,Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
void setupConnection(){
try {
urlConnection = (HttpURLConnection) requestUrl.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setChunkedStreamingMode(0);
if(headerData != null){
for (Pair pair: headerData)
{
urlConnection.setRequestProperty(pair.first.toString(), Base64.encodeToString(pair.second.toString().getBytes(),Base64.DEFAULT));
}
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
private String httpPost(){
try{
urlConnection.setRequestMethod("POST");
}
catch (Exception ex){
ex.printStackTrace();
return stringifyResponse();
}
String httpGet(){
try{
urlConnection.setRequestMethod("GET");
}
catch (Exception ex){
ex.printStackTrace();
}
return stringifyResponse();
}
String httpPut(){
try{
urlConnection.setRequestMethod("PUT");
}
catch (Exception ex){
ex.printStackTrace();
}
return stringifyResponse();
}
String httpDelete(){
try{
urlConnection.setRequestMethod("DELETE");
}
catch (Exception ex){
ex.printStackTrace();
}
return stringifyResponse();
}
String httpPatch(){
try{
urlConnection.setRequestMethod("PATCH");
}
catch (Exception ex){
ex.printStackTrace();
}
return stringifyResponse();
}
String stringifyResponse() {
StringBuilder sb = new StringBuilder();
try {
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
writer.write(getQuery(postData));
writer.flush();
writer.close();
out.close();
urlConnection.connect();
responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return sb.toString();
}
private String getQuery(List<Pair<String,String>> params) throws UnsupportedEncodingException{
Uri.Builder builder = null;
for (Pair pair : params)
{
builder = new Uri.Builder()
.appendQueryParameter(pair.first.toString(), pair.second.toString());
}
return builder.build().getEncodedQuery();
}
}
Run Code Online (Sandbox Code Playgroud)
IMO,你可以参考我的以下示例代码:
/**
* HTTP request using HttpURLConnection
*
* @param method
* @param address
* @param header
* @param mimeType
* @param requestBody
* @return
* @throws Exception
*/
public static URLConnection makeURLConnection(String method, String address, String header, String mimeType, String requestBody) throws Exception {
URL url = new URL(address);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(!method.equals(HTTP_METHOD_GET));
urlConnection.setRequestMethod(method);
if (isValid(header)) { // let's assume only one header here
urlConnection.setRequestProperty(KEYWORD_HEADER_1, header);
}
if (isValid(requestBody) && isValid(mimeType) && !method.equals(HTTP_METHOD_GET)) {
urlConnection.setRequestProperty(KEYWORD_CONTENT_TYPE, mimeType);
OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8");
writer.write(requestBody);
writer.flush();
writer.close();
outputStream.close();
}
urlConnection.connect();
return urlConnection;
}
Run Code Online (Sandbox Code Playgroud)
它requestBody是通过以下方法制成的:
public static String buildRequestBody(Object content) {
String output = null;
if ((content instanceof String) ||
(content instanceof JSONObject) ||
(content instanceof JSONArray)) {
output = content.toString();
} else if (content instanceof Map) {
Uri.Builder builder = new Uri.Builder();
HashMap hashMap = (HashMap) content;
if (isValid(hashMap)) {
Iterator entries = hashMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
builder.appendQueryParameter(entry.getKey().toString(), entry.getValue().toString());
entries.remove(); // avoids a ConcurrentModificationException
}
output = builder.build().getEncodedQuery();
}
} else if (content instanceof byte[]) {
try {
output = new String((byte[]) content, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在 AsyncTask 类中,您可以调用:
String url = "http://.......";
HttpURLConnection urlConnection;
Map<String, String> stringMap = new HashMap<>();
stringMap.put(KEYWORD_USERNAME, "bnk");
stringMap.put(KEYWORD_PASSWORD, "bnk123");
String requestBody = buildRequestBody(stringMap);
try {
urlConnection = (HttpURLConnection) Utils.makeURLConnection(HTTP_METHOD_POST, url, null, MIME_FORM_URLENCODED, requestBody);
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// do something...
} else {
// do something...
}
...
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
或者
String url = "http://.......";
HttpURLConnection urlConnection;
JSONObject jsonBody;
String requestBody;
try {
jsonBody = new JSONObject();
jsonBody.put("Title", "Android Demo");
jsonBody.put("Author", "BNK");
requestBody = Utils.buildRequestBody(jsonBody);
urlConnection = (HttpURLConnection) Utils.makeURLConnection(HTTP_METHOD_POST, url, null, MIME_JSON, requestBody);
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// do something...
} else {
// do something...
}
...
} catch (Exception e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)