本篇主要介绍如何利用HttpURLConnection在手机端使用HTTP协议和服务器端进行交互,主要流程是首先向服务器发送请求,请求成功后再获取服务器返回的数据和结果等。
网络通讯需要声明联网权限,所以首先在AndroidManifest声明权限
< uses-permission android:name=“android.permission.INTERNET” />
而请求方式分为两种,一种是get,一种为post,get和post都可以向服务器传递参数发送请求。最大的区别在于get方式是将要传递的参数放到连接的url中,而post方式会用一个数据操作流入dataOutputStream来写入数据。我理解的是get方式要简单一些,安全性低一些,post方式复杂一些,安全性高一些,所以一般发送数据类型简单且不重要的数据时会使用get方式,反之则选择post方式。
注意网络请求HttpURLConnection要放在子线程中,处理完了之后要用disconnect方法关闭连接
1.使用get方式发送请求
int room_id=1;//传给服务器的参数
int section=1;//传递服务器的参数
final Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
URL url=new URL("http://39.**.***.***:8080/MeetingManager/MeetingAndRooms/topThreeDepartmentRatio?room_id="
+URLEncoder.encode(String.valueOf(room_id))
+"§ion="+URLEncoder.encode(String.valueOf(section)));//url为网络连接地址,:后面的为端口号,最后放入传到服务器的参数。比如我要传room_id和section两个变量
HttpURLConnection connection= (HttpURLConnection) url.openConnection();//实例HttpURLConnection
connection.setRequestMethod("GET");//设置请求方式为get
connection.setConnectTimeout(5*1000);//设置连接时间
connection.connect();//连接
int code = connection.getResponseCode();//获取状态码
Log.d("interfaces code ",String.valueOf(code));
if(code==200){//code为200时表示请求正常
InputStream inputStream=connection.getInputStream();//获得请求所返回的结果
String result = stremToString(inputStream);
JSONObject root_json = new JSONObject(result);//将一个字符串封装成一个json对象root_json
/**然后把返回的数据分别拿出来,比如我的返回体为
* {"code":0,"message":"请求成功", "data":{{"department_name":"后勤部","ratio":"0.5"},{"department_name":"公关部","ratio":"0.2"},{"department_name":"宣传部","ratio":"0.1"}},"meta":null}
* **/
JSONArray jsonArray = root_json.getJSONArray("data");//获取root_json中的data作为jsonArray对象
int codes=root_json.getInt("code");
proportions.clear();//清除beans
Log.d("interfaces 0",String.valueOf(jsonArray.length()));
for(int i=0;i<jsonArray.length();i++){
JSONObject proportion_json=jsonArray.getJSONObject(i);
proportion proportion=new proportion(proportion_json.getString("department_name"),proportion_json.getDouble("ratio"));
proportions.add(proportion);
Log.d("interfaces ",proportion.getName());
}
Log.d("interfaces 1",String.valueOf(jsonArray.length())+"+"+String.valueOf(proportions.size()));
byte[] data=new byte[1024];
StringBuffer sb=new StringBuffer();
int length=0;
while ((length=inputStream.read(data))!=-1){
String s=new String(data, Charset.forName("utf-8"));
sb.append(s);
}
message[0] =sb.toString();
inputStream.close();
connection.disconnect();
Log.d("interfaces 2",String.valueOf(jsonArray.length())+"+"+String.valueOf(proportions.size()));
}
} catch (Exception e) {
Log.e("interfaces: ",e.toString());
}
}
});
thread.start();
这里用了URLEncoder.encode方法来拼接传给服务器的参数到url里。注意第一个参数先写?再接参数名字,接下来的参数以&开头。
2.使用post方式发送请求
流程和使用get方式差不多,都是先设置连接然后向服务器传递参数,连接成功后再获取服务器返回的参数,主要是传递参数的方式不同,这里举一个上传文件和一个下载文件的例子
//上传文件
public String uploadFile(final File file, int parent_room_id){
final String[] message = {""};
final String url="http://39.**.**.**:8080/Common/FileUpload/upload.do";//网络地址
final String boundary="123456";//分割线
final Map<String ,String> params=new HashMap<>();//以键值对的方式放传给服务器的参数
params.put("id",String.valueOf(parent_room_id));
params.put("type",",meeting_room_pic");
final Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
URL url1=new URL(url);
HttpURLConnection connection= (HttpURLConnection) url1.openConnection();
connection.setRequestMethod("POST");//设置请求方式为post
connection.addRequestProperty("Connection","Keep-Alive");//设置与服务器保持连接
connection.addRequestProperty("Charset","UTF-8");//设置字符编码类型
connection.addRequestProperty("Content-Type","multipart/form-data;boundary="+boundary);//post请求,上传数据时的编码类型,并且指定了分隔符
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在
// http正文内,因此需要设为true, 默认情况下是false;
connection.setDoOutput(true);
//设置是否从httpUrlConnection读入,默认情况下是true;
connection.setDoInput(true);
// Post 请求不能使用缓存
connection.setUseCaches(false);
connection.setConnectTimeout(20000);
//getOutStream会隐含的进行connect,所以也可以不调用connect
DataOutputStream dataOutputStream=new DataOutputStream(connection.getOutputStream());
FileInputStream fileInputStream=new FileInputStream(file);
dataOutputStream.writeBytes("--"+boundary+"\r\n");
// 设定传送的内容类型是可序列化的java对象
// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\""
+ URLEncoder.encode(file.getName(),"UTF-8")+"\"\r\n");
dataOutputStream.writeBytes("\r\n");
byte[] b=new byte[1024];
while ((fileInputStream.read(b))!=-1){
dataOutputStream.write(b);
}
dataOutputStream.writeBytes("\r\n");
dataOutputStream.writeBytes("--"+boundary+"\r\n");
try {
Set<String > keySet=params.keySet();
for (String param:keySet){
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\""
+encode(param)+"\"\r\n");
dataOutputStream.writeBytes("\r\n");
String value=params.get(param);
dataOutputStream.writeBytes(encode(value)+"\r\n");
dataOutputStream.writeBytes("--"+boundary+"\r\n");
}
}catch (Exception e){
Log.e("uploadFile ",e.toString());
}
InputStream inputStream=connection.getInputStream();//得到一个输入流(服务端发回的数据
byte[] data=new byte[1024];
StringBuffer sb1=new StringBuffer();
int length=0;
while ((length=inputStream.read(data))!=-1){
String s=new String(data, Charset.forName("utf-8"));
sb1.append(s);
}
message[0] =sb1.toString();
inputStream.close();
fileInputStream.close();
dataOutputStream.close();
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return message[0];
}
//下载文件或图片到外部存储
public void doSDCard(Context context, final int parent_room_id){
if (isExternalStorageWritable()){
final Thread thread=new Thread(){
@Override
public void run() {
try {
String boundary="123456";
File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
if (!file.exists()){
file.mkdirs();//创建路径
}
// Map<String ,String> params=new HashMap<>();
// params.put("id",String.valueOf(parent_room_id));
// params.put("type","meeting_room_pic");
File newFile=new File(file.getPath(),System.currentTimeMillis()+".jpg");
// newFile.createNewFile();
URL url = new URL("http://47.***.***.134/wechat/Public/uploads/huiyishi.jpg");//接口地址
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setConnectTimeout(5*1000);
DataOutputStream dataOutputStream=new DataOutputStream(connection.getOutputStream());
String content = "id=" + URLEncoder.encode(String.valueOf(parent_room_id))+"&type=meeting_room_pic";
dataOutputStream.writeBytes(content);
// try {
// Set<String > keySet=params.keySet();
// for (String param:keySet){
// dataOutputStream.writeBytes(encode(param)+"=");
// String value=params.get(param);
// dataOutputStream.writeBytes(encode(value));
// dataOutputStream.writeBytes(boundary);
// }
// }catch (Exception e){
// Log.e("下载 ",e.toString());
// }
InputStream inputStream = connection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(newFile.getAbsolutePath());
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes);
}
inputStream.close();
fileOutputStream.close();
connection.disconnect();
} catch (Exception e) {
Log.e("interfaces e:",e.toString());
}
}
};
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
AlertDialog.Builder builder=new AlertDialog.Builder(context);
builder.setMessage("外部存储不可用!");
builder.create().show();
}
}