zoukankan      html  css  js  c++  java
  • Android中发送Http请求实例(包括文件上传、servlet接收)

    摘自:http://www.eoeandroid.com/thread-22679-1-1.html

    前天开始要准备实现手机端往服务器传参数,还要能传附件,找了不少文章和资料,现在总结一下分享分享:代码中的catch什么的就省略了,尝试了图片、txt、xml是没问题的.. 各位 尽情拍砖吧。
    发完发现代码部分的格式……这个编辑器不太会用,怎么感觉把换行都去掉了,处理好换行缩进也……
    首先我是写了个java工程测试发送post请求:可以包含文本参数和文件参数****************************************************

    1. /**
    2. * 通过http协议提交数据到服务端,实现表单提交功能,包括上传文件
    3. * @param actionUrl 上传路径
    4. * @param params 请求参数 key为参数名,value为参数值
    5. * @param file 上传文件
    6. */
    7. public static void postMultiParams(String actionUrl, Map<String, String> params, FormBean[] files) {
    8. try {
    9. PostMethod post = new PostMethod(actionUrl);
    10. List<art> formParams = new ArrayList<art>();
    11. for(Map.Entry<String, String> entry : params.entrySet()){
    12. formParams.add(new StringPart(entry.getKey(), entry.getValue()));
    13. }
    14. if(files!=null)
    15. for(FormBean file : files){
    16. //filename为在服务端接收时希望保存成的文件名,filepath是本地文件路径(包括了源文件名),filebean中就包含了这俩属性
    17. formParams.add(new FilePart("file", file.getFilename(), new File(file.getFilepath())));
    18. }
    19. Part[] parts = new Part[formParams.size()];
    20. Iterator<art> pit = formParams.iterator();
    21. int i=0;
    22. while(pit.hasNext()){
    23. parts[i++] = pit.next();
    24. }
    25. //如果出现乱码可以尝试一下方式
    26. //StringPart sp = new StringPart("TEXT", "testValue", "GB2312"); 
    27. //FilePart fp = new FilePart("file", "test.txt", new File("./temp/test.txt"), null, "GB2312"
    28. //postMethod.getParams().setContentCharset("GB2312");
    29. MultipartRequestEntity mrp = new MultipartRequestEntity(parts, post.getParams());
    30. post.setRequestEntity(mrp);
    31. //execute post method
    32. HttpClient client = new HttpClient();
    33. int code = client.executeMethod(post);
    34. System.out.println(code);
    35. } catch ...
    36. }
    复制代码

    通过以上代码可以成功的模拟java客户端发送post请求,服务端也能接收并保存文件 java端测试的main方法:

    1. public static void main(String[] args){
    2. String actionUrl = "http://192.168.0.123:8080/WSserver/androidUploadServlet";
    3. Map<String, String> strParams = new HashMap<String, String>();
    4. strParams.put("paramOne", "valueOne");
    5. strParams.put("paramTwo", "valueTwo");
    6. FormBean[] files = new FormBean[]{new FormBean("dest1.xml", "F:/testpostsrc/main.xml")};
    7. HttpTool.postMultiParams(actionUrl,strParams,files);
    8. }
    复制代码

    本以为大功告成了,结果一移植到android工程中,编译是没有问题的。 但是运行时抛了异常 先是说找不到PostMethod类,org.apache.commons.httpclient.methods.PostMethod这个类绝对是有包含的; 还有个异常就是VerifyError。 开发中有几次碰到这个异常都束手无策,觉得是SDK不兼容还是怎么地,哪位知道可得跟我说说~~ 于是看网上有直接分析http request的内容构建post请求的,也有找到带上传文件的,拿下来运行老是有些问题,便直接通过运行上面的java工程发送的post请求,在servlet中打印出请求内容,然后对照着拼接字符串和流终于给实现了!代码如下: ***********************************************************

    1. /**
    2. * 通过拼接的方式构造请求内容,实现参数传输以及文件传输
    3. * @param actionUrl
    4. * @param params
    5. * @param files
    6. * @return
    7. * @throws IOException
    8. */
    9. public static String post(String actionUrl, Map<String, String> params,
    10. Map<String, File> files) throws IOException {
    11. String BOUNDARY = java.util.UUID.randomUUID().toString();
    12. String PREFIX = "--" , LINEND = "\r\n";
    13. String MULTIPART_FROM_DATA = "multipart/form-data";
    14. String CHARSET = "UTF-8";
    15. URL uri = new URL(actionUrl);
    16. HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
    17. conn.setReadTimeout(5 * 1000); // 缓存的最长时间
    18. conn.setDoInput(true);// 允许输入
    19. conn.setDoOutput(true);// 允许输出
    20. conn.setUseCaches(false); // 不允许使用缓存
    21. conn.setRequestMethod("POST");
    22. conn.setRequestProperty("connection", "keep-alive");
    23. conn.setRequestProperty("Charsert", "UTF-8");
    24. conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);
    25. // 首先组拼文本类型的参数
    26. StringBuilder sb = new StringBuilder();
    27. for (Map.Entry<String, String> entry : params.entrySet()) {
    28. sb.append(PREFIX);
    29. sb.append(BOUNDARY);
    30. sb.append(LINEND);
    31. sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);
    32. sb.append("Content-Type: text/plain; charset=" + CHARSET+LINEND);
    33. sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
    34. sb.append(LINEND);
    35. sb.append(entry.getValue());
    36. sb.append(LINEND);
    37. }
    38. DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
    39. outStream.write(sb.toString().getBytes());
    40. // 发送文件数据
    41. if(files!=null)
    42. for (Map.Entry<String, File> file: files.entrySet()) {
    43. StringBuilder sb1 = new StringBuilder();
    44. sb1.append(PREFIX);
    45. sb1.append(BOUNDARY);
    46. sb1.append(LINEND);
    47. sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""+file.getKey()+"\""+LINEND);
    48. sb1.append("Content-Type: application/octet-stream; charset="+CHARSET+LINEND);
    49. sb1.append(LINEND);
    50. outStream.write(sb1.toString().getBytes());
    51. InputStream is = new FileInputStream(file.getValue());
    52. byte[] buffer = new byte[1024];
    53. int len = 0;
    54. while ((len = is.read(buffer)) != -1) {
    55. outStream.write(buffer, 0, len);
    56. }
    57. is.close();
    58. outStream.write(LINEND.getBytes());
    59. }
    60. //请求结束标志
    61. byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
    62. outStream.write(end_data);
    63. outStream.flush();
    64. // 得到响应码
    65. int res = conn.getResponseCode();
    66. if (res == 200) {
    67. InputStream in = conn.getInputStream();
    68. int ch;
    69. StringBuilder sb2 = new StringBuilder();
    70. while ((ch = in.read()) != -1) {
    71. sb2.append((char) ch);
    72. }
    73. }
    74. outStream.close();
    75. conn.disconnect();
    76. return in.toString();
    77. }
    复制代码

    ********************** button响应中的代码: **********************

    1. public void onClick(View v){
    2. String actionUrl = getApplicationContext().getString(R.string.wtsb_req_upload);
    3. Map<String, String> params = new HashMap<String, String>();
    4. params.put("strParamName", "strParamValue");
    5. Map<String, File> files = new HashMap<String, File>();
    6. files.put("tempAndroid.txt", new File("/sdcard/temp.txt"));
    7. try {
    8. HttpTool.postMultiParams(actionUrl, params, files);
    9. } catch ...
    复制代码

    *************************** 服务器端servlet代码: ***************************

    1. public void doPost(HttpServletRequest request, HttpServletResponse response)
    2. throws ServletException, IOException {
    3. //print request.getInputStream to check request content
    4. //HttpTool.printStreamContent(request.getInputStream());
    5. RequestContext req = new ServletRequestContext(request);
    6. if(FileUpload.isMultipartContent(req)){
    7. DiskFileItemFactory factory = new DiskFileItemFactory();
    8. ServletFileUpload fileUpload = new ServletFileUpload(factory);
    9. fileUpload.setFileSizeMax(FILE_MAX_SIZE);
    10. List items = new ArrayList();
    11. try {
    12. items = fileUpload.parseRequest(request);
    13. } catch ...
    14. Iterator it = items.iterator();
    15. while(it.hasNext()){
    16. FileItem fileItem = (FileItem)it.next();
    17. if(fileItem.isFormField()){
    18. System.out.println(fileItem.getFieldName()+" "+fileItem.getName()+" "+new String(fileItem.getString().getBytes("ISO-8859-1"),"GBK"));
    19. } else {
    20. System.out.println(fileItem.getFieldName()+" "+fileItem.getName()+" "+
    21. fileItem.isInMemory()+" "+fileItem.getContentType()+" "+fileItem.getSize());
    22. if(fileItem.getName()!=null && fileItem.getSize()!=0){
    23. File fullFile = new File(fileItem.getName());
    24. File newFile = new File(FILE_SAVE_PATH+fullFile.getName());
    25. try {
    26. fileItem.write(newFile);
    27. } catch ...
    28. } else {
    29. System.out.println("no file choosen or empty file");
    30. }
    31. }
    32. }
    33. }
    34. }
    35. public void init() throws ServletException {
    36. //读取在web.xml中配置的init-param  
    37. FILE_MAX_SIZE = Long.parseLong(this.getInitParameter("file_max_size"));//上传文件大小限制 
    38. FILE_SAVE_PATH = this.getInitParameter("file_save_path");//文件保存位置
    39. }
  • 相关阅读:
    读书笔记 effective c++ Item 53 关注编译器发出的警告
    读书笔记 effective c++ Item 52 如果你实现了placement new,你也要实现placement delete
    读书笔记 effective c++ Item 51 实现new和delete的时候要遵守约定
    读书笔记 effective c++ Item 50 了解何时替换new和delete 是有意义的
    读书笔记 effective c++ Item 49 理解new-handler的行为
    读书笔记 effective c++ Item 48 了解模板元编程
    读书笔记 effective c++ Item 47 使用traits class表示类型信息
    读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数
    读书笔记 effective c++ Item 45 使用成员函数模板来接受“所有兼容类型”
    读书笔记 effective c++ Item 44 将与模板参数无关的代码抽离出来
  • 原文地址:https://www.cnblogs.com/lzhitian/p/2424023.html
Copyright © 2011-2022 走看看