iOS上传图片文件到J2EE Servlet保存

4 篇文章 0 订阅
2 篇文章 0 订阅

       项目中要用到一个从iPad上传截图到Server端的功能。在网上搜了好多资料,都只是简单的iOS端的代码,Server段的代码基本没有。

要有也是php的或者ASP.Net的,没有找到Java的。在这里把我参考网友资源,写的用Java Servlet接收iOS上传图片的方法贴出来,与大

家分享。

         首先是在iOS中的上传动作:

        第一种方式是把UIImage的data 转码成Base64,作为一个参数上传,关键代码如下:

 NSString  *imgPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Temp.png"];
       
 // Write a UIImage to JPEG with minimum compression (best quality)
 // The value 'image' must be a UIImage object
 // The value '1.0' represents image compression quality as value from 0.0 to 1.0
 //[UIImageJPEGRepresentation([_imgScreenShot image], 1.0) writeToFile:jpgPath atomically:YES];
 [UIImagePNGRepresentation([_imgScreenShot image]) writeToFile:imgPath atomically:YES];
       
 //NSData *imageData = [NSData dataWithContentsOfFile:imgPath];
 //纯代码的Base64 编码
 //NSString *base64= [Utilitys Base64Encode:imageData];
 //NSData扩展的Base64编码
 //NSString *base64= [imageData base64EncodedString];
 //GTMBase64编码
 //NSString *base64= [Utilitys encodeBase64Data:imageData];
 //iOS7 自带的Base64编码
 NSString *base64= [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
 [self sendScreenShot:[_txtAccount text] Password:[_txtPassword text] Report:[_txtReport text] To:[_txtTo text]
                     Content:base64];

以上把image的数据保存成文件,读取出来后编码成base64,调用sendScreenShot方法:

- (void) sendScreenShot:(NSString*)login Password:(NSString*)password
                 Report:(NSString*)report To:(NSString*)to Content:(NSString*)content{
    NSLog(@"Call web service send screen shoot");
    [[iBIService sharedService] setDelegate:self];
   
    [Utilitys showWaitingWithMessage:self.view alpha:0.7 Message:@"正在发送截屏邮件,请稍候..."];
   
    [[iBIService sharedService] sendScreenShot:login Password:password Report:report To:to Content:content];
}

再通过Service调用NSURLConnection上传图片:

-(void) sendScreenShot:(NSString *)account Password:(NSString *)password Report:(NSString *)report To:(NSString *)to Content:(NSString *)content{
    NSLog(@"send Screen Shot with account:%@, password:%@,Report:%@,To:%@,Content Length:%d",account,password,report,to,[content length]);
 
    [buf setData:nil];
    type = SENDSCREENSHOT;
   
    //added by Dumbbell Yang at 2014-08-07
    //[Utilitys showAlert:nil title:@"Base 64 Length" message:[NSString stringWithFormat:@"%d",[content length]]];
   
    content = [Utilitys encodeToPercentEscapeString:content];

    NSString *requestString = [NSString stringWithFormat:@"login=%@&password=%@&report=%@&to=%@&content=%@",
                               account,password,report,to,content];
   
    //NSLog(@"Request String:%@",requestString);
    NSData *requestData = [NSData dataWithBytes:[requestString UTF8String]
           length:[requestString length]];
   
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:URI_SEND_SCREEN_SHOT,
                                       [Utilitys getUserDefaults:KEY_IMS_SERVER DefaultValue:IMS_SERVER],
            [Utilitys getUserDefaults:KEY_IMS_PORT DefaultValue:IMS_SERVER_PORT]]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:requestData];
    //[request addValue:[[Utilitys getApp] httpHeader] forHTTPHeaderField:@"Cookie"];
   
    /*异步请求*/
    [self resetConnection];
    mconnection = [[NSURLConnection alloc] initWithRequest:request
              delegate:self startImmediately:YES];
    timer = [NSTimer scheduledTimerWithTimeInterval:DATA_TIMEOUT target:self
             selector:@selector(onTimeout) userInfo:nil repeats:NO];
}

J2EE Servlet端的接收代码如下:

//added by Dumbbell lYang at 2014-07-29
     else if (strRequestURI.equals(SEND_SCREEN_SHOT)){
      login = request.getParameter("login");
      password = request.getParameter("password");
      String report = request.getParameter("report");
      String to = request.getParameter("to");
      String content = URLDecoder.decode(request.getParameter("content"),"utf-8");  
      //added by Dumbbell Yang at 2014-08-11
      content = content.replaceAll(" ", "+");
      //added by Dumbbell Yang at 2014-08-06
      System.out.println("Content Length(Base64):" + content.length());
      
      writeToFile("Test64.jpg", content);
      
      strOutput = ServiceManager.sendScreenShot(login, password,
        report, to, content, mailServer,mailUserName,mailPassword);
     }

    这里要注意的就是对base64在iOS端编码后,要调用

content = [Utilitys encodeToPercentEscapeString:content]; 做一个URLEncode的动作。

   然后在Servlet端接收时,先要decode:

  String content = URLDecoder.decode(request.getParameter("content"),"utf-8");  

   然后因为还要记得把空格恢复成+:

//added by Dumbbell Yang at 2014-08-11
      content = content.replaceAll(" ", "+");

      然后就可以用base64 decode成byte文件,保存到Server了。

      第二种方式是在iOS端构建form,把图片数据以二进制方式发送,主要参考了网友BorisSun的代码:

     把UIImage的data保存成文件,然后传文件名:

     [self sendScreenShotFile:[_txtAccount text] Password:[_txtPassword text] Report:[_txtReport text] To:[_txtTo text]
                        FilePath:imgPath];

      调用sendScreenShotFile方法:

   
- (void) sendScreenShotFile:(NSString*)login Password:(NSString*)password
                     Report:(NSString*)report To:(NSString*)to FilePath:(NSString*)filePath{
    NSLog(@"Call web service send screen shoot File");
    [[iBIService sharedService] setDelegate:self];
   
    [Utilitys showWaitingWithMessage:self.view alpha:0.7 Message:@"正在发送截屏邮件,请稍候..."];
   
    [[iBIService sharedService] sendScreenShotFile:login Password:password Report:report To:to FilePath:filePath];
}

同样通过Service调用NSURLConnection,组织form Data上传图片:

//added by Dumbbell Yang at 2014-08-08
-(void) sendScreenShotFile:(NSString*)account Password:(NSString*)password Report:(NSString*)report To:(NSString*)to FilePath:(NSString*)filePath{
    NSLog(@"send Screen Shot File with account:%@, password:%@,Report:%@,To:%@,File Path:%@",account,password,report,to,filePath);
 
    [buf setData:nil];
    type = SENDSCREENSHOTFILE;
   
    NSString *TWITTERFON_FORM_BOUNDARY = @"0xKhTmLbOuNdArY";
    //根据url初始化request
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:URI_SEND_SCREEN_SHOT_FILE,
                                       [Utilitys getUserDefaults:KEY_IMS_SERVER DefaultValue:IMS_SERVER],
            [Utilitys getUserDefaults:KEY_IMS_PORT DefaultValue:IMS_SERVER_PORT]]];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
   // NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
    //                                                       cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
     //                                                  timeoutInterval:10];
    //分界线 --AaB03x
    NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
    //结束符 AaB03x--
    NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
   
    //得到图片的data
    NSData* imgData = [NSData dataWithContentsOfFile:filePath];
  
    //http body的字符串
    NSMutableString *body=[[NSMutableString alloc]init];
   
    //account or email
    //添加分界线,换行
    [body appendFormat:@"%@\r\n",MPboundary];
    //添加字段名称,换2行
    [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",@"login"];
    //添加字段的值
    [body appendFormat:@"%@\r\n",account];
   
    //password
    [body appendFormat:@"%@\r\n",MPboundary];
    //添加字段名称,换2行
    [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",@"password"];
    //添加字段的值
    [body appendFormat:@"%@\r\n",password];
   
    //report
    [body appendFormat:@"%@\r\n",MPboundary];
    //添加字段名称,换2行
    [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",@"report"];
    //添加字段的值
    [body appendFormat:@"%@\r\n",report];
   
    //to
    [body appendFormat:@"%@\r\n",MPboundary];
    //添加字段名称,换2行
    [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",@"to"];
    //添加字段的值
    [body appendFormat:@"%@\r\n",to];
   
    //image data length
    [body appendFormat:@"%@\r\n",MPboundary];
    //添加字段名称,换2行
    [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",@"datalength"];
    //添加字段的值
    [body appendFormat:@"%d\r\n", [imgData length]];
   
    if(filePath){
        //image data
        [body appendFormat:@"%@\r\n",MPboundary];
       
        //声明pic字段,文件名为report
        [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",@"file", report];
        //声明上传文件的格式
        [body appendFormat:@"Content-Type: image/png\r\n\r\n"];
    }

    //声明myRequestData,用来放入http body
    NSMutableData *myRequestData=[NSMutableData data];
    //将body字符串转化为UTF8格式的二进制
    [myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
    if(filePath){
        //将image data加入
        [myRequestData appendData:imgData];
    }
   
    //added by Dumbbell Yang at 2014-08-07
    //[Utilitys showAlert:nil title:@"Image Data Length" message:[NSString stringWithFormat:@"%d",[imgData length]]];
   
    //声明结束符:--AaB03x--
    NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
    //加入结束符--AaB03x--
    [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
   
    //设置HTTPHeader中Content-Type的值
    NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
    //设置HTTPHeader
    [request setValue:content forHTTPHeaderField:@"Content-Type"];
    //设置Content-Length
    [request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"];
    //设置http body
    [request setHTTPBody:myRequestData];
   
    //added by Dumbbell Yang at 2014-08-07
    //[Utilitys showAlert:nil title:@"HTTPBody Length" message:[NSString stringWithFormat:@"%d",[myRequestData length]]];
   
    //http method
    [request setHTTPMethod:@"POST"];
   
    /*异步请求*/
    [self resetConnection];
    mconnection = [[NSURLConnection alloc] initWithRequest:request
              delegate:self startImmediately:YES];
    timer = [NSTimer scheduledTimerWithTimeInterval:DATA_TIMEOUT target:self
             selector:@selector(onTimeout) userInfo:nil repeats:NO];
}

 

J2EE Servlet端代码如下(这里用到了ServletFileUpload组件,本来想写一个简单纯Servlet的方法的,无奈功力不够):

//added by Dumbbell Yang at 2014-08-08
     else if (strRequestURI.equals(SEND_SCREEN_SHOT_FILE)){
      try {
       boolean isMultipart = ServletFileUpload.isMultipartContent(request);
          if (isMultipart) {
           ServletFileUpload upload = new ServletFileUpload();
           FileItemIterator iter = upload.getItemIterator(request);

           String report = "";
     String to = "";
     String fileName = "";
     while (iter.hasNext()) {
                  FileItemStream item = iter.next();
                  String fieldName = item.getFieldName();
                     InputStream stream = item.openStream();       
                     if (item.isFormField()) {
                      //普通表单数据
             if (fieldName != null){
              System.out.println("Field Name:" + fieldName);
              if (fieldName.equalsIgnoreCase("login")){
               login = new String(readInputStream(stream),"UTF-8");
               System.out.println(fieldName + ":" + login);
              }
              else if (fieldName.equalsIgnoreCase("password")){
               password = new String(readInputStream(stream),"UTF-8");
               System.out.println(fieldName + ":" + password);
              }
              else if (fieldName.equalsIgnoreCase("report")){
               report = new String(readInputStream(stream),"UTF-8");
               System.out.println(fieldName + ":" + report);
              }
              else if (fieldName.equalsIgnoreCase("to")){
               to = new String(readInputStream(stream),"UTF-8");
               System.out.println(fieldName + ":" + to);
              }
             }
             else{
              System.out.println("field name is null");
             }
                     }
                     else {
                      //文件数据
             fileName = item.getName();
             if(fileName == null || fileName.equals("")){
              System.out.println("file name is null");
             }
             else{
              System.out.println("File Name:" + fileName);
              OutputStream out = new FileOutputStream(fileName);
              int len=-1;
              byte [] b = new byte[1024];
              while((len = stream.read(b))!=-1){
               out.write(b, 0, len);
              }
              stream.close();
              out.close();
             }
                     }
           }
           
           if (login.equals("")||password.equals("")||
            report.equals("")||to.equals("")||fileName.equals("")){
            strOutput = "{\"ErrorMessage\":\"Invalid post parameter!\"}";
           }
           else{
            FileInputStream fis = new FileInputStream(fileName);
            String content = Base64.encodeBytes(readInputStream(fis));
         strOutput = ServiceManager.sendScreenShot(login, password,
           report, to, content, mailServer,mailUserName,mailPassword);
           }
          }
          else {
           /*Enumeration en = request.getParameterNames();
           while (en.hasMoreElements()) {
            String paramName = (String) en.nextElement();
            String paramValue = request.getParameter(paramName);
                 
            System.out.println(paramName + ":" + paramValue);
           }*/
           strOutput = "{\"ErrorMessage\":\"Invalid content type!\"}";
          }
      }
      catch (FileUploadException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       strOutput = "{\"ErrorMessage\":\"file upload exception!\"}";
      }
      catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    strOutput = "{\"ErrorMessage\":\"file read exception!\"}";
   }

 

   欢迎批评指正,欢迎相互探讨,共同提高。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dumbbellyang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值