HttpURLConnection openConnection = (HttpConnection)url.openConnection();
openConnection.setRequestMethod("GET");//设置请求方式
openConnection.setConnectTimeout(5000);//设置请求超时时间
String contentType = openConnection.getContentType();//获取返回的数据类型
Object content = openConnection.getContent();//获取放回的数据
int code = openConnection.getResponseCode();//获取响应码,200--返回正确,404--资源没找到,503--服务器内部错误
......
InputStream inputStream = openConnection.getInputStream();
Bitmap decodeStream = BitmapFactory.decodeStream(inputStream);
openConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64;Trident/4.0;SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; InfoPath.2");
URLEncoder.encode("中文",utf-8);
public class MainActivity extends Activity {
String path = "http://f.hiphotos.baidu.com/image/pic/item/a8014c086e061d9507500dd67ff40ad163d9cacd.jpg";
private SmartImageView smiv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.bt);
smiv = (SmartImageView) findViewById(R.id.smiv);
}
public void click(View v){
smiv.setImageUrl(path);
}
}
三、使用Get请求方式请求网络
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //01010101 String qq = request.getParameter("qq");//采用的编码是iso-8859-1 String pwd = request.getParameter("pwd"); System.out.println("qq:"+new String(qq.getBytes("iso-8859-1"),"utf-8")); System.out.println("pwd:"+new String(pwd.getBytes("iso-8859-1"),"utf-8")); //查询数据库 看qq和密码是否存在 if("10000".equals(qq)&&"abcde".equals(pwd)){ //tomcat容器如果发现字符串不识别就默认采用本地码表 response.getOutputStream().write("登陆成功".getBytes("utf-8")); }else{ response.getOutputStream().write("登陆失败".getBytes("utf-8")); } }
服务器端会通过 HttpServletRequest request getParameter()方法 获取到用户请求网络的参数,如用户名和密码。用户发送请求时,输入的请求参数都会展示在地址栏,即地址栏的所有的参数就是服务器端要获取到的所有参数。在发送请求时,只需要在请求地址后面加上相应的参数就能发送get请求,如www.qq.com/web/LogingServlet?qq=10000&pwd=abcde
2、客户端在发送get请求时,需要将请求的参数传递到URL中,然后在发送请求。 如:
//获取请求的参数 final String qq = et_qq.getText().toString().trim(); final String pwd = et_pwd.getText().toString().trim(); //将参数添加到请求地址中 String path = "http://192.168.1.103:8080/web/LoginServlet?qq="+URLEncoder.encode(qq, "utf-8")+"&pwd="+URLEncoder.encode(pwd, "utf-8");
3、get请求的优缺点
优点:使用方便,只需要的地址后面组拼请求参数即可发送请求
缺点:(1)请求参数在地址栏都能展示出来,不安全;
(2)数据的长度有限制
四、使用post请求方式发送网络请求
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("post过来的请求");
doGet(req, resp);
}
五、使用HTTPClient发送网络请求URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //1.设置请求方式为POST conn.setRequestMethod("POST"); //注意单词必须大写. conn.setConnectTimeout(5000); //2.设置http请求数据的类型为表单类型 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //3.设置给服务器写的数据的长度 //qq=10000&pwd=abcde String data = "qq="+URLEncoder.encode(qq, "utf-8")+"&pwd="+URLEncoder.encode(pwd, "utf-8"); conn.setRequestProperty("Content-Length", String.valueOf(data.length())); //4.记得指定要给服务器写数据 conn.setDoOutput(true); //5.开始向服务器写数据 conn.getOutputStream().write(data.getBytes());
2、发送post请求String path = "http://192.168.1.103:8080/web/LoginServlet?qq="+URLEncoder.encode(qq, "utf-8")+"&pwd="+URLEncoder.encode(pwd, "utf-8"); HttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(path); HttpResponse response = client.execute(httpGet); //获取状态码 int code = response.getStatusLine().getStatusCode(); if(code == 200){ InputStream is = response.getEntity().getContent(); String result = StreamTools.readStream(is); Message msg = Message.obtain(); msg.what = SUCCESS; msg.obj = result; handler.sendMessage(msg); }else{ Message msg = Message.obtain(); msg.what = ERROR; handler.sendMessage(msg); }
String path = "http://192.168.1.103:8080/web/LoginServlet"; HttpClient client = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(path); List
parameters = new ArrayList (); parameters.add(new BasicNameValuePair("qq", qq)); parameters.add(new BasicNameValuePair("pwd", pwd)); httpPost.setEntity(new UrlEncodedFormEntity(parameters, "utf-8")); HttpResponse response = client.execute(httpPost); //获取状态码 int code = response.getStatusLine().getStatusCode(); if(code == 200){ InputStream is = response.getEntity().getContent(); String result = StreamTools.readStream(is); Message msg = Message.obtain(); msg.what = SUCCESS; msg.obj = result; handler.sendMessage(msg); }else{ Message msg = Message.obtain(); msg.what = ERROR; handler.sendMessage(msg); }
StreamTools.readStream()
public class StreamTools { /** * 工具方法 * @param is 输入流 * @return 文本字符串 * @throws Exception */ public static String readStream(InputStream is) throws Exception{ ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer))!=-1){ baos.write(buffer, 0, len); } is.close(); String temp = baos.toString(); return temp; } }
六、使用过异步网络加载框架AsyncHttpClient请求网络1、 AsyncHttpClient进一步对 HttpClient进行了封装,这个框架考虑到了子线程问题,我们在使用时就不用再创建子线程,直接使用估计可,同时框架中还使用了线程池,使加载效率更高。
2、发送get请求3、发送post请求String path = "http://192.168.1.103:8080/web/LoginServlet?qq="+URLEncoder.encode(qq)+"&pwd="+URLEncoder.encode(pwd); AsyncHttpClient client = new AsyncHttpClient(); client.get(path, new AsyncHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { tv_status.setText(new String(responseBody)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { tv_status.setText("http请求失败"+new String(responseBody)); } });
String path = "http://192.168.1.103:8080/web/LoginServlet"; AsyncHttpClient client = new AsyncHttpClient(); RequestParams params = new RequestParams(); params.put("qq", qq); params.put("pwd", pwd); client.post(path, params, new AsyncHttpResponseHandler(){ @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { tv_status.setText("登陆结果:"+new String(responseBody)); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { tv_status.setText("请求失败请检查网络"); } });
七、使用post请求上传文件
AsyncHttpClient特性:
(1)采用异步http请求,并通过匿名内部类处理回调结果
(2)http请求独立在UI主线程之外
(3)采用线程池来处理并发请求
(4)采用RequestParams类创建GET/POST参数
(5)不需要第三方包即可支持Multipart file文件上传
(6)大小只有25kb
(7)自动为各种移动电话处理连接断开时请求重连
(8)超快的自动gzip响应解码支持
(9)使用BinaryHttpResponseHandler类下载二进制文件(如图片)
(10) 使用JsonHttpResponseHandler类可以自动将响应结果解析为json格式
(11)持久化cookie存储,可以将cookie保存到你的应用程序的SharedPreferences中
使用方法
(1)到官网http://loopj.com/android-async-http/下载最新的android-async-http-1.4.4.jar,然后将此jar包添加进Android应用程序 libs文件夹
(2)通过import com.loopj.android.http.*;引入相关类
(3)创建异步请求
- AsyncHttpClient client = new AsyncHttpClient();
- client.get("http://www.google.com", new AsyncHttpResponseHandler() {
- @Override
- public void onSuccess(String response) {
- System.out.println(response);
- }
- });
建议使用静态的Http Client对象
在下面这个例子,我们创建了静态的http client对象,使其很容易连接到Twitter的API
然后我们可以很容易的在代码中操作Twitter的API
- import com.loopj.android.http.*;
- public class TwitterRestClient {
- private static final String BASE_URL = "http://api.twitter.com/1/";
- private static AsyncHttpClient client = new AsyncHttpClient();
- public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
- client.get(getAbsoluteUrl(url), params, responseHandler);
- }
- public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
- client.post(getAbsoluteUrl(url), params, responseHandler);
- }
- private static String getAbsoluteUrl(String relativeUrl) {
- return BASE_URL + relativeUrl;
- }
- }
- import org.json.*;
- import com.loopj.android.http.*;
- class TwitterRestClientUsage {
- public void getPublicTimeline() throws JSONException {
- TwitterRestClient.get("statuses/public_timeline.json", null, new JsonHttpResponseHandler() {
- @Override
- public void onSuccess(JSONArray timeline) {
- // Pull out the first event on the public timeline
- JSONObject firstEvent = timeline.get(0);
- String tweetText = firstEvent.getString("text");
- // Do something with the response
- System.out.println(tweetText);
- }
- });
- }
- }
AsyncHttpClient, RequestParams ,AsyncHttpResponseHandler三个类使用方法
(1)AsyncHttpClient
public class AsyncHttpClient extends java.lang.Object
该类通常用在android应用程序中创建异步GET, POST, PUT和DELETE HTTP请求,请求参数通过RequestParams实例创建,响应通过重写匿名内部类 ResponseHandlerInterface的方法处理。
例子:
(2)RequestParams
- AsyncHttpClient client = new AsyncHttpClient();
- client.get("http://www.google.com", new ResponseHandlerInterface() {
- @Override
- public void onSuccess(String response) {
- System.out.println(response);
- }
- });
public class RequestParams extends java.lang.Object
用于创建AsyncHttpClient实例中的请求参数(包括字符串或者文件)的集合
例子:
(3)public class AsyncHttpResponseHandler extends java.lang.Object implements ResponseHandlerInterface
- RequestParams params = new RequestParams();
- params.put("username", "james");
- params.put("password", "123456");
- params.put("email", "[email protected]");
- params.put("profile_picture", new File("pic.jpg")); // Upload a File
- params.put("profile_picture2", someInputStream); // Upload an InputStream
- params.put("profile_picture3", new ByteArrayInputStream(someBytes)); // Upload some bytes
- Map
map = new HashMap (); - map.put("first_name", "James");
- map.put("last_name", "Smith");
- params.put("user", map); // url params: "user[first_name]=James&user[last_name]=Smith"
- Set
set = new HashSet (); // unordered collection- set.add("music");
- set.add("art");
- params.put("like", set); // url params: "like=music&like=art"
- List
list = new ArrayList (); // Ordered collection- list.add("Java");
- list.add("C");
- params.put("languages", list); // url params: "languages[]=Java&languages[]=C"
- String[] colors = { "blue", "yellow" }; // Ordered collection
- params.put("colors", colors); // url params: "colors[]=blue&colors[]=yellow"
- List
- Map
user1 = new HashMap (); - user1.put("age", "30");
- user1.put("gender", "male");
- Map
user2 = new HashMap (); - user2.put("age", "25");
- user2.put("gender", "female");
- listOfMaps.add(user1);
- listOfMaps.add(user2);
- params.put("users", listOfMaps); // url params: "users[][age]=30&users[][gender]=male&users[][age]=25&users[][gender]=female"
- AsyncHttpClient client = new AsyncHttpClient();
- client.post("http://myendpoint.com", params, responseHandler);
用于拦截和处理由AsyncHttpClient创建的请求。在匿名类AsyncHttpResponseHandler中的重写 onSuccess(int, org.apache.http.Header[], byte[])方法用于处理响应成功的请求。此外,你也可以重写 onFailure(int, org.apache.http.Header[], byte[], Throwable), onStart(), onFinish(), onRetry() 和onProgress(int, int)方法
例子:
- AsyncHttpClient client = new AsyncHttpClient();
- client.get("http://www.google.com", new AsyncHttpResponseHandler() {
- @Override
- public void onStart() {
- // Initiated the request
- }
- @Override
- public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
- // Successfully got a response
- }
- @Override
- public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error)
- {
- // Response failed :(
- }
- @Override
- public void onRetry() {
- // Request was retried
- }
- @Override
- public void onProgress(int bytesWritten, int totalSize) {
- // Progress notification
- }
- @Override
- public void onFinish() {
- // Completed the request (either success or failure)
- }
- });
利用PersistentCookieStore持久化存储cookie
PersistentCookieStore类用于实现Apache HttpClient的CookieStore接口,可以自动的将cookie保存到Android设备的SharedPreferences中,如果你打算使用cookie来管理验证会话,这个非常有用,因为用户可以保持登录状态,不管关闭还是重新打开你的app
(1)首先创建 AsyncHttpClient实例对象
(2)将客户端的cookie保存到PersistentCookieStore实例对象,带有activity或者应用程序context的构造方法
- AsyncHttpClient myClient = new AsyncHttpClient();
(3)任何从服务器端获取的cookie都会持久化存储到myCookieStore中,添加一个cookie到存储中,只需要构造一个新的cookie对象,并且调用addCookie方法
- PersistentCookieStore myCookieStore = new PersistentCookieStore(this);
- myClient.setCookieStore(myCookieStore);
- BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome");
- newCookie.setVersion(1);
- newCookie.setDomain("mydomain.com");
- newCookie.setPath("/");
- myCookieStore.addCookie(newCookie);
7.利用RequestParams上传文件
类RequestParams支持multipart file 文件上传
(1)在RequestParams 对象中添加InputStream用于上传
(2)添加文件对象用于上传
- InputStream myInputStream = blah;
- RequestParams params = new RequestParams();
- params.put("secret_passwords", myInputStream, "passwords.txt");
(3)添加字节数组用于上传
- File myFile = new File("/path/to/file.png");
- RequestParams params = new RequestParams();
- try {
- params.put("profile_picture", myFile);
- } catch(FileNotFoundException e) {}
- byte[] myByteArray = blah;
- RequestParams params = new RequestParams();
- params.put("soundtrack", new ByteArrayInputStream(myByteArray), "she-wolf.mp3");
用BinaryHttpResponseHandler下载二进制数据BinaryHttpResponseHandler用于获取二进制数据如图片和其他文件AsyncHttpClient client = new AsyncHttpClient(); String[] allowedContentTypes = new String[] { "image/png", "image/jpeg" }; client.get("http://example.com/file.png", new BinaryHttpResponseHandler(allowedContentTypes) { @Override public void onSuccess(byte[] fileData) { // Do something with the file } });
android-async-http 开源框架可以使我们轻松地获取网络数据或者向服务器发送数据,最关键的是,它是异步框架,在底层使用线程池处理并发请求,效率很高,使用又特别简单。
以往我们在安卓上做项目,比如要下载很多图片、网页或者其他的资源,多数开发者会选择一个线程一个下载任务这种模型,因为安卓自带的 AndroidHttpClient 或者 java 带的 java.net.URL ,默认都是阻塞式操作。这种模型效率不高,对并发要求高的 APP 来讲,并不适用。有的人会选择使用 nio 自己实现,代码复杂度又很高。
AsyncHttpClient 作为 android-async-http 框架的一个核心应用类,使用简单,可以处理文本、二进制等各种格式的 web 资源。下面提供一些代码来看如何使用:
public class Downloader { public static AsyncHttpClient mHttpc = new AsyncHttpClient(); public static String TAG = "Downloader"; public void downloadText(String uri){ mHttpc.get(uri, null, new AsyncHttpResponseHandler(){ @Override public void onSuccess(String data){ Log.i(TAG, "downloaded, thread id " + Thread.currentThread().getId()); // TODO: do something on } @Override public void onFailure(Throwable e, String data){ Log.i(TAG, "download failed."); // TODO: error proceed } }); } public void downloadImage(String uri, String savePath){ mHttpc.get(uri, new ImageResponseHandler(savePath)); } public class ImageResponseHandler extends BinaryHttpResponseHandler{ private String mSavePath; public ImageResponseHandler(String savePath){ super(); mSavePath = savePath; } @Override public void onSuccess(byte[] data){ Log.i(TAG, "download image, file length " + data.length); // TODO: save image , do something on image } @Override public void onFailure(Throwable e, String data){ Log.i(TAG, "download failed"); // TODO : error proceed } } };
public void upload(View view){
String path = et_path.getText().toString().trim();
File file = new File(path);
if(file.exists()&&file.length()>0){
//上传
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
try {
params.put("file", file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
client.post("http://192.168.1.103:8080/web/UploadServlet", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Toast.makeText(MainActivity.this, "上传成功", 0).show();
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
Toast.makeText(MainActivity.this, "上传失败", 0).show();
}
});
}else{
Toast.makeText(this, "请检查文件是否存在", 0).show();
}
}
HttpUtils http = new HttpUtils();
http.send(HttpRequest.HttpMethod.GET,
"http://www.lidroid.com",
new RequestCallBack(){
@Override
public void onLoading(long total, long current, boolean isUploading) {
testTextView.setText(current + "/" + total);
}
@Override
public void onSuccess(ResponseInfo responseInfo) {
textView.setText(responseInfo.result);
}
@Override
public void onStart() {
}
@Override
public void onFailure(HttpException error, String msg) {
}
});
HttpUtils http = new HttpUtils(); HttpHandler handler = http.download("http://apache.dataguru.cn/httpcomponents/httpclient/source/httpcomponents-client-4.2.5-src.zip", "/sdcard/httpcomponents-client-4.2.5-src.zip", true, // 如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。 true, // 如果从请求返回信息中获取到文件名,下载完成后自动重命名。 new RequestCallBack
() { @Override public void onStart() { testTextView.setText("conn..."); } @Override public void onLoading(long total, long current, boolean isUploading) { testTextView.setText(current + "/" + total); } @Override public void onSuccess(ResponseInfo responseInfo) { testTextView.setText("downloaded:" + responseInfo.result.getPath()); } @Override public void onFailure(HttpException error, String msg) { testTextView.setText(msg); } });
(8) 使用随机文件访问流的seek( int index)方法设置每个线程下载文件后在本地文件中写入的起始位置Range表示范围,后面的字符串为范围值
(9) 将获取到的数据写入到本地文件中
public void download(View view) {
path = et_path.getText().toString().trim();
if (TextUtils.isEmpty(path) || (!path.startsWith("http://"))) {
Toast.makeText(this, "对不起路径不合法", 0).show();
return;
}
new Thread(){
public void run() {
try {
//1、连接网络
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
//2、使用getContentLength()方法获取网络文件的大小
int length = conn.getContentLength();
System.out.println("服务器文件的长度为:" + length);
//3、使用RandomAccessFile在本地创建一个空文件
RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+getFileName(path), "rw");
//4、将空文件的大小设置为与网络文件大小相同
raf.setLength(length);
raf.close();
//5、设置将文件划分的块数,threadCount--线程数
int blocksize = length / threadCount;
runningThreadCount = threadCount;
//6、设置每个线程下载的文件区域
for (int threadId = 0; threadId < threadCount; threadId++) {
int startIndex = threadId * blocksize;
int endIndex = (threadId + 1) * blocksize - 1;
if (threadId == (threadCount - 1)) {
endIndex = length - 1;
}
new DownloadThread(threadId, startIndex, endIndex).start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
//创建线程下载文件 private class DownloadThread extends Thread { /** * 线程id */ private int threadId; /** * 线程下载的理论开始位置 */ private int startIndex; /** * 线程下载的结束位置 */ private int endIndex; /** * 当前线程下载到文件的那一个位置了. */ private int currentPosition; public DownloadThread(int threadId, int startIndex, int endIndex) { this.threadId = threadId; this.startIndex = startIndex; this.endIndex = endIndex; System.out.println(threadId + "号线程下载的范围为:" + startIndex + " ~~ " + endIndex); currentPosition = startIndex; } @Override public void run() { try { URL url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //检查当前线程是否已经下载过一部分的数据了 File info = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+threadId+".position"); RandomAccessFile raf = new RandomAccessFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+getFileName(path), "rw"); if(info.exists()&&info.length()>0){ FileInputStream fis = new FileInputStream(info); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); currentPosition = Integer.valueOf(br.readLine()); conn.setRequestProperty("Range", "bytes="+currentPosition+"-"+endIndex); System.out.println("原来有下载进度,从上一次终止的位置继续下载"+"bytes="+currentPosition+"-"+endIndex); fis.close(); raf.seek(currentPosition);//每个线程写文件的开始位置都是不一样的. }else{ //告诉服务器 只想下载资源的一部分 conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex); System.out.println("原来没有有下载进度,新的下载"+ "bytes="+startIndex+"-"+endIndex); raf.seek(startIndex);//每个线程写文件的开始位置都是不一样的. } InputStream is = conn.getInputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer))!=-1){ //把每个线程下载的数据放在自己的空间里面. // System.out.println("线程:"+threadId+"正在下载:"+new String(buffer)); raf.write(buffer,0, len); currentPosition+=len; File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+threadId+".position"); RandomAccessFile fos = new RandomAccessFile(file,"rwd"); //System.out.println("线程:"+threadId+"写到了"+currentPosition); fos.write(String.valueOf(currentPosition).getBytes()); fos.close();//fileoutstream数据是不一定被写入到底层设备里面的,有可能是存储在缓存里面. //raf 的 rwd模式,数据是立刻被存储到底层硬盘设备里面. int max = endIndex - startIndex; int progress = currentPosition - startIndex; if(threadId==0){ pb0.setMax(max); pb0.setProgress(progress); }else if(threadId==1){ pb1.setMax(max); pb1.setProgress(progress); }else if(threadId==2){ pb2.setMax(max); pb2.setProgress(progress); } } raf.close(); is.close(); System.out.println("线程:"+threadId+"下载完毕了..."); File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+threadId+".position"); f.renameTo(new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+threadId+".position.finish")); synchronized (MainActivity.class) { runningThreadCount--; if(runningThreadCount<=0){ for(int i=0;i
/** * 获取一个文件名称 * @param path * @return */ public String getFileName(String path){ int start = path.lastIndexOf("/")+1; return path.substring(start); }