封装一个类搞定90%安卓客户端与服务器端交互

来源:互联网 发布:pop3协议端口号 编辑:程序博客网 时间:2024/05/29 10:27

本文详情链接:http://blog.csdn.net/lk_blog/article/details/7706348

本实例封装了一个处理安卓客户端与服务器端交互的几个方法,对于中文乱码问题本实例也找到了解决方案.本例可以处理的场景如下:

1.与服务器端交互json数据.

2.Get方式与服务器端交互数据.

3.Post方式与服务器端交互数据.

4.HttpClient方式与服务器端交互数据.

5.上传文件到服务器端.

6.从服务器端下载文件.

7.从服务器端读取文本文件.

实例截图:


本篇文章将实例代码完整贴出,希望以本文作为一个交流的平台,大家集思广益封装出更好的处理类.交流地址: http://blog.csdn.net/lk_blog/article/details/7706348#comments

客户端的封装类NetTool.java:

package com.tgb.lk.demo.util;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLEncoder;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import android.os.Environment;/** * NetTool:封装一个类搞定90%安卓客户端与服务器端交互 *  * @author 李坤 五期信息技术提高班 */public class NetTool {private static final int TIMEOUT = 10000;// 10秒/** * 传送文本,例如Json,xml等 */public static String sendTxt(String urlPath, String txt, String encoding)throws Exception {byte[] sendData = txt.getBytes();URL url = new URL(urlPath);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("POST");conn.setConnectTimeout(TIMEOUT);// 如果通过post提交数据,必须设置允许对外输出数据conn.setDoOutput(true);conn.setRequestProperty("Content-Type", "text/xml");conn.setRequestProperty("Charset", encoding);conn.setRequestProperty("Content-Length", String.valueOf(sendData.length));OutputStream outStream = conn.getOutputStream();outStream.write(sendData);outStream.flush();outStream.close();if (conn.getResponseCode() == 200) {// 获得服务器响应的数据BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));// 数据String retData = null;String responseData = "";while ((retData = in.readLine()) != null) {responseData += retData;}in.close();return responseData;}return "sendText error!";}/** * 上传文件 */public static String sendFile(String urlPath, String filePath,String newName) throws Exception {String end = "\r\n";String twoHyphens = "--";String boundary = "*****";URL url = new URL(urlPath);HttpURLConnection con = (HttpURLConnection) url.openConnection();/* 允许Input、Output,不使用Cache */con.setDoInput(true);con.setDoOutput(true);con.setUseCaches(false);/* 设置传送的method=POST */con.setRequestMethod("POST");/* setRequestProperty */con.setRequestProperty("Connection", "Keep-Alive");con.setRequestProperty("Charset", "UTF-8");con.setRequestProperty("Content-Type", "multipart/form-data;boundary="+ boundary);/* 设置DataOutputStream */DataOutputStream ds = new DataOutputStream(con.getOutputStream());ds.writeBytes(twoHyphens + boundary + end);ds.writeBytes("Content-Disposition: form-data; "+ "name=\"file1\";filename=\"" + newName + "\"" + end);ds.writeBytes(end);/* 取得文件的FileInputStream */FileInputStream fStream = new FileInputStream(filePath);/* 设置每次写入1024bytes */int bufferSize = 1024;byte[] buffer = new byte[bufferSize];int length = -1;/* 从文件读取数据至缓冲区 */while ((length = fStream.read(buffer)) != -1) {/* 将资料写入DataOutputStream中 */ds.write(buffer, 0, length);}ds.writeBytes(end);ds.writeBytes(twoHyphens + boundary + twoHyphens + end);/* close streams */fStream.close();ds.flush();/* 取得Response内容 */InputStream is = con.getInputStream();int ch;StringBuffer b = new StringBuffer();while ((ch = is.read()) != -1) {b.append((char) ch);}/* 关闭DataOutputStream */ds.close();return b.toString();}/** * 通过get方式提交参数给服务器 */public static String sendGetRequest(String urlPath,Map<String, String> params, String encoding) throws Exception {// 使用StringBuilder对象StringBuilder sb = new StringBuilder(urlPath);sb.append('?');// 迭代Mapfor (Map.Entry<String, String> entry : params.entrySet()) {sb.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), encoding)).append('&');}sb.deleteCharAt(sb.length() - 1);// 打开链接URL url = new URL(sb.toString());HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setRequestProperty("Content-Type", "text/xml");conn.setRequestProperty("Charset", encoding);conn.setConnectTimeout(TIMEOUT);// 如果请求响应码是200,则表示成功if (conn.getResponseCode() == 200) {// 获得服务器响应的数据BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));// 数据String retData = null;String responseData = "";while ((retData = in.readLine()) != null) {responseData += retData;}in.close();return responseData;}return "sendGetRequest error!";}/** * 通过Post方式提交参数给服务器,也可以用来传送json或xml文件 */public static String sendPostRequest(String urlPath,Map<String, String> params, String encoding) throws Exception {StringBuilder sb = new StringBuilder();// 如果参数不为空if (params != null && !params.isEmpty()) {for (Map.Entry<String, String> entry : params.entrySet()) {// Post方式提交参数的话,不能省略内容类型与长度sb.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), encoding)).append('&');}sb.deleteCharAt(sb.length() - 1);}// 得到实体的二进制数据byte[] entitydata = sb.toString().getBytes();URL url = new URL(urlPath);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("POST");conn.setConnectTimeout(TIMEOUT);// 如果通过post提交数据,必须设置允许对外输出数据conn.setDoOutput(true);// 这里只设置内容类型与内容长度的头字段conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");// conn.setRequestProperty("Content-Type", "text/xml");conn.setRequestProperty("Charset", encoding);conn.setRequestProperty("Content-Length", String.valueOf(entitydata.length));OutputStream outStream = conn.getOutputStream();// 把实体数据写入是输出流outStream.write(entitydata);// 内存中的数据刷入outStream.flush();outStream.close();// 如果请求响应码是200,则表示成功if (conn.getResponseCode() == 200) {// 获得服务器响应的数据BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));// 数据String retData = null;String responseData = "";while ((retData = in.readLine()) != null) {responseData += retData;}in.close();return responseData;}return "sendText error!";}/** * 在遇上HTTPS安全模式或者操作cookie的时候使用HTTPclient会方便很多 使用HTTPClient(开源项目)向服务器提交参数 */public static String sendHttpClientPost(String urlPath,Map<String, String> params, String encoding) throws Exception {// 需要把参数放到NameValuePairList<NameValuePair> paramPairs = new ArrayList<NameValuePair>();if (params != null && !params.isEmpty()) {for (Map.Entry<String, String> entry : params.entrySet()) {paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));}}// 对请求参数进行编码,得到实体数据UrlEncodedFormEntity entitydata = new UrlEncodedFormEntity(paramPairs,encoding);// 构造一个请求路径HttpPost post = new HttpPost(urlPath);// 设置请求实体post.setEntity(entitydata);// 浏览器对象DefaultHttpClient client = new DefaultHttpClient();// 执行post请求HttpResponse response = client.execute(post);// 从状态行中获取状态码,判断响应码是否符合要求if (response.getStatusLine().getStatusCode() == 200) {HttpEntity entity = response.getEntity();InputStream inputStream = entity.getContent();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, encoding);BufferedReader reader = new BufferedReader(inputStreamReader);// 读字符串用的。String s;String responseData = "";while (((s = reader.readLine()) != null)) {responseData += s;}reader.close();// 关闭输入流return responseData;}return "sendHttpClientPost error!";}/** * 根据URL直接读文件内容,前提是这个文件当中的内容是文本,函数的返回值就是文件当中的内容 */public static String readTxtFile(String urlStr, String encoding)throws Exception {StringBuffer sb = new StringBuffer();String line = null;BufferedReader buffer = null;try {// 创建一个URL对象URL url = new URL(urlStr);// 创建一个Http连接HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();// 使用IO流读取数据buffer = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), encoding));while ((line = buffer.readLine()) != null) {sb.append(line);}} catch (Exception e) {throw e;} finally {try {buffer.close();} catch (Exception e) {e.printStackTrace();}}return sb.toString();}/** * 该函数返回整形 -1:代表下载文件出错 0:代表下载文件成功 1:代表文件已经存在 */public static int downloadFile(String urlStr, String path, String fileName)throws Exception {InputStream inputStream = null;try {inputStream = getInputStreamFromUrl(urlStr);File resultFile = write2SDFromInput(path, fileName, inputStream);if (resultFile == null) {return -1;}} catch (Exception e) {return -1;} finally {try {inputStream.close();} catch (Exception e) {throw e;}}return 0;}/** * 根据URL得到输入流 *  * @param urlStr * @return * @throws MalformedURLException * @throws IOException */public static InputStream getInputStreamFromUrl(String urlStr)throws MalformedURLException, IOException {URL url = new URL(urlStr);HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();InputStream inputStream = urlConn.getInputStream();return inputStream;}/** * 将一个InputStream里面的数据写入到SD卡中 */private static File write2SDFromInput(String directory, String fileName,InputStream input) {File file = null;String SDPATH = Environment.getExternalStorageDirectory().toString();FileOutputStream output = null;File dir = new File(SDPATH + directory);if (!dir.exists()) {dir.mkdir();}try {file = new File(dir + File.separator + fileName);file.createNewFile();output = new FileOutputStream(file);byte buffer[] = new byte[1024];while ((input.read(buffer)) != -1) {output.write(buffer);}output.flush();} catch (IOException e) {e.printStackTrace();} finally {try {output.close();} catch (IOException e) {e.printStackTrace();}}return file;}}


客户端main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/tvData"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="数据" />    <Button        android:id="@+id/btnTxt"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="与服务器端交互Json数据" />    <Button        android:id="@+id/btnGet"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="Get方式与服务器端交互数据" />    <Button        android:id="@+id/btnPost"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="Post方式与服务器端交互数据" />    <Button        android:id="@+id/btnHttpClient"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="HttpClient方式与服务器端交互数据" />    <Button        android:id="@+id/btnUploadFile"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="上传文件到服务器端" />    <Button        android:id="@+id/btnDownloadFile"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="从服务器端下载文件" />    <Button        android:id="@+id/btnReadTxtFile"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="从服务器端读取文本文件" /></LinearLayout>

客户端AppClientActivity.java:

package com.tgb.lk.demo.appclient;import java.util.HashMap;import java.util.Map;import com.google.gson.Gson;import com.tgb.lk.demo.model.Student;import com.tgb.lk.demo.util.NetTool;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class AppClientActivity extends Activity {private TextView tvData = null;private Button btnTxt = null;private Button btnGet = null;private Button btnPost = null;private Button btnHttpClient = null;private Button btnUploadFile = null;private Button btnReadTxtFile = null;private Button btnDownloadFile = null;//需要将下面的IP改为服务器端IPprivate String txtUrl = "http://192.168.1.46:8080/AppServer/SynTxtDataServlet";private String url = "http://192.168.1.46:8080/AppServer/SynDataServlet";private String uploadUrl = "http://192.168.1.46:8080/AppServer/UploadFileServlet";private String fileUrl = "http://192.168.1.46:8080/AppServer/file.jpg";private String txtFileUrl = "http://192.168.1.46:8080/AppServer/txtFile.txt";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);tvData = (TextView) findViewById(R.id.tvData);btnTxt = (Button) findViewById(R.id.btnTxt);btnGet = (Button) findViewById(R.id.btnGet);btnPost = (Button) findViewById(R.id.btnPost);btnHttpClient = (Button) findViewById(R.id.btnHttpClient);btnUploadFile = (Button) findViewById(R.id.btnUploadFile);btnReadTxtFile = (Button) findViewById(R.id.btnReadTxtFile);btnDownloadFile = (Button) findViewById(R.id.btnDownloadFile);btnTxt.setOnClickListener(btnListener);btnGet.setOnClickListener(btnListener);btnPost.setOnClickListener(btnListener);btnHttpClient.setOnClickListener(btnListener);btnUploadFile.setOnClickListener(btnListener);btnReadTxtFile.setOnClickListener(btnListener);btnDownloadFile.setOnClickListener(btnListener);}OnClickListener btnListener = new OnClickListener() {String retStr = "";@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btnTxt:Student student = new Student();student.setId(1);student.setName("李坤");student.setClasses("五期信息技术提高班");Gson gson = new Gson();String jsonTxt = gson.toJson(student);try {retStr = NetTool.sendTxt(txtUrl, jsonTxt,"UTF-8");} catch (Exception e2) {e2.printStackTrace();}break;case R.id.btnGet:Map<String, String> map = new HashMap<String, String>();map.put("name", "李坤");map.put("age", "26");map.put("classes", "五期信息技术提高班");try {retStr = NetTool.sendGetRequest(url, map, "utf-8");} catch (Exception e) {e.printStackTrace();}break;case R.id.btnPost:Map<String, String> map2 = new HashMap<String, String>();map2.put("name", "李坤");map2.put("age", "26");map2.put("classes", "五期信息技术提高班");try {retStr = NetTool.sendPostRequest(url, map2, "utf-8");} catch (Exception e) {e.printStackTrace();}break;case R.id.btnHttpClient:Map<String, String> map3 = new HashMap<String, String>();map3.put("name", "李坤");map3.put("age", "26");map3.put("classes", "五期信息技术提高班");try {retStr = NetTool.sendHttpClientPost(url, map3, "utf-8");} catch (Exception e) {e.printStackTrace();}break;case R.id.btnUploadFile:// 需要在sdcard中放一张image.jsp的图片,本例才能正确运行try {retStr = NetTool.sendFile(uploadUrl, "/sdcard/image.jpg","image1.jpg");} catch (Exception e) {e.printStackTrace();}break;case R.id.btnReadTxtFile:try {//本例中服务器端的文件类型是UTF-8retStr = NetTool.readTxtFile(txtFileUrl, "UTF-8");} catch (Exception e1) {e1.printStackTrace();}break;case R.id.btnDownloadFile:try {NetTool.downloadFile(fileUrl, "/download", "newfile.jpg");} catch (Exception e) {e.printStackTrace();}break;default:break;}tvData.setText(retStr);}};}

客户端Student.java:

package com.tgb.lk.demo.model;public class Student {private int id;private String name;private String classes;public int getId() {return id;}public void setId(int id) {this.id = id;}//get set方法略@Overridepublic String toString() {return "Student [classes=" + classes + ", id=" + id + ", name=" + name+ "]";}}

客户端AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.tgb.lk.demo.appclient"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk android:minSdkVersion="7" />    <application        android:icon="@drawable/ic_launcher"        android:label="@string/app_name" >        <activity            android:label="@string/app_name"            android:name=".AppClientActivity" >            <intent-filter >                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></manifest>

服务器端web.xml:

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><servlet><servlet-name>SynDataServlet</servlet-name><servlet-class>com.tgb.lk.demo.appserver.SynDataServlet</servlet-class></servlet><servlet><servlet-name>UploadFileServlet</servlet-name><servlet-class>com.tgb.lk.demo.appserver.UploadFileServlet</servlet-class></servlet>  <servlet>    <servlet-name>SynTxtDataServlet</servlet-name>    <servlet-class>com.tgb.lk.demo.appserver.SynTxtDataServlet</servlet-class>  </servlet><servlet-mapping><servlet-name>SynDataServlet</servlet-name><url-pattern>/SynDataServlet</url-pattern></servlet-mapping><servlet-mapping><servlet-name>UploadFileServlet</servlet-name><url-pattern>/UploadFileServlet</url-pattern></servlet-mapping>  <servlet-mapping>    <servlet-name>SynTxtDataServlet</servlet-name>    <url-pattern>/SynTxtDataServlet</url-pattern>  </servlet-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>

服务器端SynDataServlet.java:

package com.tgb.lk.demo.appserver;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class SynDataServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("---------get-------------");// 处理中文乱码问题解决办法String name = new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8");String age = request.getParameter("age");String classes = new String(request.getParameter("classes").getBytes("iso-8859-1"), "UTF-8");System.out.println("-------" + name + age + classes + "--------");response.setContentType("text/xml; charset=UTF-8");PrintWriter out = response.getWriter();out.print("GET method ");out.print("name=" + name + ",age=" + age + ",classes=" + classes);out.flush();out.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("---------post-------------");String name = new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8");String age = request.getParameter("age");String classes = new String(request.getParameter("classes").getBytes("iso-8859-1"), "UTF-8");System.out.println("--------" + name + age + classes + "---------");response.setContentType("text/xml; charset=UTF-8");PrintWriter out = response.getWriter();out.print("POST method");out.print("name=" + name + ",age=" + age + ",classes=" + classes);out.flush();out.close();}}

服务器端SynTxtDataServlet.java:

package com.tgb.lk.demo.appserver;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class SynTxtDataServlet extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));// 数据String retData = null;String responseData = "";while ((retData = in.readLine()) != null) {responseData += retData;}in.close();response.setContentType("text/xml; charset=UTF-8");PrintWriter out = response.getWriter();out.print("POST method");out.print(responseData);out.flush();out.close();}}

服务器端UploadFileServlet.java(服务器端需引入commons-fileupload-1.2.2.jar和commons-io-2.3.jar):

package com.tgb.lk.demo.appserver;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileUpload;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.apache.commons.fileupload.servlet.ServletRequestContext;public class UploadFileServlet extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置request编码,主要是为了处理普通输入框中的中文问题request.setCharacterEncoding("gbk");// 这里对request进行封装,RequestContext提供了对request多个访问方法org.apache.commons.fileupload.RequestContext requestContext = new ServletRequestContext(request);// 判断表单是否是Multipart类型的。这里可以直接对request进行判断,不过已经以前的用法了if (FileUpload.isMultipartContent(requestContext)) {DiskFileItemFactory factory = new DiskFileItemFactory();// 设置文件的缓存路径factory.setRepository(new File("d:/tmp/"));File dir = new File("d:\\download\\");if (!dir.exists()) {dir.mkdirs();}// System.out.print("已经生成临时文件");ServletFileUpload upload = new ServletFileUpload(factory);// 设置上传文件大小的上限,-1表示无上限upload.setSizeMax(100000 * 1024 * 1024);List items = new ArrayList();try {// 上传文件,并解析出所有的表单字段,包括普通字段和文件字段items = upload.parseRequest(request);} catch (FileUploadException e1) {System.out.println("文件上传发生错误" + e1.getMessage());}// 下面对每个字段进行处理,分普通字段和文件字段Iterator it = items.iterator();while (it.hasNext()) {DiskFileItem fileItem = (DiskFileItem) it.next();// 如果是普通字段if (fileItem.isFormField()) {System.out.println(fileItem.getFieldName()+ "   "+ fileItem.getName()+ "   "+ new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));} else {System.out.println(fileItem.getFieldName() + "   "+ fileItem.getName() + "   "+ fileItem.isInMemory() + "    "+ fileItem.getContentType() + "   "+ fileItem.getSize());// 保存文件,其实就是把缓存里的数据写到目标路径下if (fileItem.getName() != null && fileItem.getSize() != 0) {File fullFile = new File(fileItem.getName());File newFile = new File("d:\\download\\"+ fullFile.getName());try {fileItem.write(newFile);} catch (Exception e) {e.printStackTrace();}} else {System.out.println("文件没有选择 或 文件内容为空");}}}}}}

限于本人水平有限,有很多地方写的并不完美,希望大家不吝赐教.

源码下载地址: http://download.csdn.net/detail/lk_blog/4404383


0 0