Android一般通过http协议向服务端接口发送请求,常用有POST和GET传输方式。这种请求通常借助于HttpClient,HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包。通过HttpClient可以不借助浏览器,从而简化了客户端与服务器端之间的交互。
HttpPost httpPost=new HttpPost(reqUrl);
HttpResponse httpResponse=new DefaultHttpClient().execute(httpPost);
DefaultHttpClient是HttpClient接口的默认实现,new DefaultHttpClient().execute(httpPost);则是使用一个匿名内部类来处理请求。该匿名内部类继承自DefaultHttpClient,而DefaultHttpClient实现了HttpClient接口,所有可以重写HttpClient接口下execute的方法来处理请求。
Android Post请求的两种方式
(1)、HttpPost
HttpPost httpRequest =new HttpPost(url);
List <NameValuePair> params=new ArrayList<NameValuePair>();//Post方式用NameValuePair[]阵列储存
params.add(new BasicNameValuePair("name","name"));
try{
//设置请求参数
httpRequest.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
//创建HttpClient实例
HttpClient client = new DefaultHttpClient();
//请求超时
client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 20000);
//读取超时
client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 20000 );
//取得HTTP response
HttpResponse httpResponse = client.execute(httpRequest);
//若状态码为200 ok
if(httpResponse.getStatusLine().getStatusCode()==200){
//取出回应字串
String strResult=EntityUtils.toString(httpResponse.getEntity());
}else{;
}
}catch(ClientProtocolException e){
Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), e.getMessage().toString(),Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
(2)、HttpURLConnection
try{
//建立连接
URL url=new URL(url);
HttpURLConnection httpConn=(HttpURLConnection)url.openConnection();
设置连接属性
httpConn.setDoOutput(true);//使用 URL 连接进行输出
httpConn.setDoInput(true);//使用 URL 连接进行输入
httpConn.setUseCaches(false);//忽略缓存
httpConn.setRequestMethod("POST");//设置URL请求方法
String requestString = "客服端要以以流方式发送到服务端的数据...";
//设置请求属性
//获得数据字节数据,请求数据流的编码,必须和下面服务器端处理请求流的编码一致
byte[] requestStringBytes = requestString.getBytes("utf-8");
httpConn.setRequestProperty("Content-length", "" + requestStringBytes.length);
httpConn.setRequestProperty("Content-Type", "application/octet-stream");
httpConn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
httpConn.setRequestProperty("Charset", "UTF-8");
//
String name=URLEncoder.encode("张三","utf-8");
httpConn.setRequestProperty("name", name);
//建立输出流,并写入数据
OutputStream outputStream = httpConn.getOutputStream();
outputStream.write(requestStringBytes);
outputStream.close();
//获得响应状态
int responseCode = httpConn.getResponseCode();
if(HttpURLConnection.HTTP_OK == responseCode){//连接成功
//当正确响应时处理数据
StringBuffer sb = new StringBuffer();
String readLine;
BufferedReader responseReader;
//处理响应流,必须与服务器响应流输出的编码一致
responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), ENCODING_UTF_8));
while ((readLine = responseReader.readLine()) != null) {
sb.append(readLine).append("\n");
}
responseReader.close();
}
}catch(Exception ex){
ex.printStackTrace();
}
HttpClient和HttpURLConnection是访问HTTP的两种方式,
HttpURLConnection是一个抽象类,继承自URLConnection抽象类,基于标准Java接口(java.net),可以实现简单的基于URL请求、响应功能;HttpClient基于Apache接口(org.appache.http),使用起来更方面更强大。一般来说,使用这种接口比较多。运用这两种方式,android可以访问网页、下载图片或文件、上传文件,甚至参数配置适当时,可以抓取服务器的很多数据。如用android做多图上传到服务器。
首先我们先解析目标url请求时的一些参数
如提请求的url地址Request URL,提交的方式Request Method,服务器端的IP地址及端口Remote Address,请求头Request Headers,请求负载(表单参数)Request Payload,进而我们就可以在代码里面进行设置,然后发送请求
/**
* 解析multipart/form-data方式提交的请求,并以同样的方式再提交
*/
@SuppressWarnings("unchecked")
public static HttpURLConnection doPostMultipartFormData(java.net.URL url,MultipartHttpServletRequest request){
//分割字符串
String BOUNDARY = UUIDTool.getUUID().toUpperCase();
String BOUNDARYSP = "--";
String BOUNDARYSTR = BOUNDARYSP + BOUNDARY;
String LINESP = "\r\n";
HttpURLConnection conn = null;
try{
conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);// 是否输入参数
conn.setConnectTimeout(3000);
conn.setRequestMethod("POST");
conn.setRequestProperty(
"Accept",
"text/html, application/xhtml+xml, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Accept-Charset", "UTF-8");
//conn.setRequestProperty("contentType", "UTF-8");
conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY+"; charset=UTF-8");
OutputStream out = new DataOutputStream(conn.getOutputStream());
//byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();// 定义最后数据分隔线
StringBuffer multiParamsData = new StringBuffer();
//组装普通参数
Map params = request.getParameterMap();
for(Object key : params.keySet()){
Object paramvalue = params.get(key);
if(paramvalue!=null){
if(paramvalue instanceof String[]){
for(String param : (String[])paramvalue){
multiParamsData.append(BOUNDARYSTR);
multiParamsData.append(LINESP);
multiParamsData.append("Content-Disposition: form-data; name=\""+key+"\"");
multiParamsData.append(LINESP);
multiParamsData.append("Content-Type: text/plain; charset=UTF-8");
multiParamsData.append(LINESP);
multiParamsData.append(LINESP);
multiParamsData.append(param);
multiParamsData.append(LINESP);
}
}else{
multiParamsData.append(BOUNDARYSTR);
multiParamsData.append(LINESP);
multiParamsData.append("Content-Disposition: form-data; name=\""+key+"\"");
multiParamsData.append(LINESP);
multiParamsData.append("Content-Type: text/plain; charset=UTF-8");
multiParamsData.append(LINESP);
multiParamsData.append(LINESP);
multiParamsData.append(paramvalue);
multiParamsData.append(LINESP);
}
}
}
//System.out.println(multiParamsData.toString());
out.write(multiParamsData.toString().getBytes("UTF-8"));
//组装文件
Map<String, MultipartFile> files = request.getFileMap();
int i = 1;
for(String key : files.keySet()){
StringBuffer multiFilesData = new StringBuffer();
MultipartFile multipartFile = files.get(key);
multiFilesData.append(BOUNDARYSTR);
multiFilesData.append(LINESP);
multiFilesData.append("Content-Disposition: form-data; name=\""+key+"\"; filename=\""+multipartFile.getOriginalFilename()+"\"");
multiFilesData.append(LINESP);
multiFilesData.append("Content-Type:application/octet-stream");
multiFilesData.append(LINESP);
multiFilesData.append(LINESP);
//multiData.append(paramvalue);
out.write(multiFilesData.toString().getBytes("UTF-8"));
DataInputStream in = new DataInputStream(multipartFile.getInputStream());
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
out.write(LINESP.getBytes("UTF-8"));
in.close();
// System.out.println(multiFilesData.toString()+"<file content; length:"+readStream(multipartFile.getInputStream()).length+">");
}
//System.out.println(BOUNDARYSTR+BOUNDARYSP);
out.write((BOUNDARYSTR+BOUNDARYSP+LINESP).getBytes("UTF-8"));
out.flush();
out.close();
//byte[] bypes = params.getBytes("UTF-8");
//System.out.println("2>>>>>>"+new String(params,"UTF-8"));
// conn.getOutputStream().write(params);
}
catch(ConnectException e){
}
catch(Exception e){
logger.error("HttpRequest Error:",e);
}
return conn;
}
HttpPsot结合Handle
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Message message=new Message();
HttpPost httpPost=new HttpPost(reqUrl);
try{
httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
HttpResponse httpResponse;
try{
httpResponse=new DefaultHttpClient().execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
String result = EntityUtils.toString(httpResponse.getEntity());
if(!result.isEmpty()){
message.what=0;
message.obj=result;
myHandler.sendMessage(message);
}else{
message.what=1;
myHandler.sendMessage(message);
}
}else{
message.what=1;
myHandler.sendMessage(message);
}
}catch(Exception e){
e.printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
static Handler myHandler=new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
if(msg.what==1){
resultCallback.getReslt("1");
}else if(msg.what==0){
String result=(String) msg.obj;
}
};
};
涉及到网络数据传输,AndroidManifest.xml中要设置相应的权限。
<uses-permission android:name="android.permission.INTERNET" />
同时可以对网络状态做一些相应的处理。
/**
* 检测网络是否连接
* @return
*/
private boolean isNetConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
NetworkInfo[] infos = cm.getAllNetworkInfo();
if (infos != null) {
for (NetworkInfo ni : infos) {
if (ni.isConnected()) {
return true;
}
}
}
}
return false;
}
/**
* 设置网络
* @param context
*/
private void isNetworkAvailable(Context context) {
new AlertDialog.Builder(LoginActivity.this)
.setTitle("网络设置提示")
.setMessage("网络不可用,是否现在设置网络?")
.setPositiveButton("设置",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
if(android.os.Build.VERSION.SDK_INT > 10 ){
//3.0以上打开设置界面,也可以直接用ACTION_WIRELESS_SETTINGS打开到wifi界面
startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));
} else {
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
}
}).setNegativeButton("取消", null).show();