在iOS上使用方法POST上传文件和文本 [英] Upload file and text with Method POST on iOS

查看:153
本文介绍了在iOS上使用方法POST上传文件和文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将JSON与文件和一些文本发送到Web服务,但是服务器回答为无效. 我已经看了3天了,但仍然无法解决问题,所以请您寻求帮助.

I'm trying to send a JSON to the web service with a file and some text, but the server answers as invalid. I have been looking through this for 3 days and can't get what's wrong, so I ask you for help.

这是与Web服务对话的Web表单:

This is the web form to talk to the web service:

<html>
<head>
  <title>Nova Dica Form</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
  <form action="http://serveraddress.com/newtip" method="post" enctype="multipart/form-data">
    <input type="hidden" name="textoDica" value="Ola teste dica">
    <input type="hidden" name="idUsuario" value="2">
    <input type="hidden" name="recomendou" value="true">
    <input type="hidden" name="idTags" value="2">
    <input type="hidden" name="idMarcas" value="1">    
    <input type="hidden" name="idLocais" value="">
    <input type="hidden" name="idCategorias" value="">
    <input type="hidden" name="idImpressoes" value="">
    <input name="foto1" type="file">
    <input name="foto2" type="file">
    <input name="foto3" type="file">
    <br>
    <input type="submit" value="Upload">
  </form>
</body>
</html>

这是php开发人员发送给我的:

And this is what the php developer sent me:

POST /newtip
Host: serveraddress.com
Content-Type: multipart/form-data
Representation:

Content-Disposition: form-data; name="textoDica"

texto-dica
Content-Disposition: form-data; name="foto1"
Content-Type: image/jpeg, image/png
Content-Transfer-Encoding: binary

foto1
Content-Disposition: form-data; name="foto2"
Content-Type: image/jpeg, image/png
Content-Transfer-Encoding: binary

foto2
Content-Disposition: form-data; name="foto3"
Content-Type: image/jpeg, image/png
Content-Transfer-Encoding: binary

foto3
Content-Disposition: form-data; name="recomendou";

recomendou
Content-Disposition: form-data; name="idUsuario";

id-usuario
Content-Disposition: form-data; name="idTags";

id-tag
Content-Disposition: form-data; name="idMarcas";

id-marca
Content-Disposition: form-data; name="idLocais";

id-local
Content-Disposition: form-data; name="idCategorias";

id-categoria
Content-Disposition: form-data; name="idImpressoes";

id-Impressao

Response
Content-Type: application/json
Representation:
{ "fotoDica" : "http://s3.amazonaws.com/cooltips/dicas/f23f89as.jpg",
  "horarioDica" : 1372711615696,
  "idDica" : 21,
  "recomendado" : 1,
  "textoDica" : "TesteDica1"
}

因此,基于此,我在代码中完成了此操作(在stackoverflow上找到了一些内容:

So, based on that, I did this in my code (with some content I found here at stackoverflow:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://serveraddress.com/newtip"]]];
[request setHTTPMethod:@"POST"];
// Header
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
// Body
NSMutableData *body = [NSMutableData data];

// Dica/Tip
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"textoDica\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Teste de texto blablabla." dataUsingEncoding:NSUTF8StringEncoding]];
// Usuario
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idUsuario\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"72" dataUsingEncoding:NSUTF8StringEncoding]];
// Recomendou
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"recomendou\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"true" dataUsingEncoding:NSUTF8StringEncoding]];
// Tags
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idTags\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"aaaaaa;bbbbbb;cccccc" dataUsingEncoding:NSUTF8StringEncoding]];
// Marca
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idMarcas\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"3" dataUsingEncoding:NSUTF8StringEncoding]];
// Local
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idLocais\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"4" dataUsingEncoding:NSUTF8StringEncoding]];
// Categorias
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idCategorias\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"1" dataUsingEncoding:NSUTF8StringEncoding]];
// Impressões
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"idImpressoes\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"bom;alegre" dataUsingEncoding:NSUTF8StringEncoding]];
// Fotos / Image Files
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: form-data; name=\"foto1\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: file/jpeg\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Transfer-Encoding: binary\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
NSData *imageData = UIImageJPEGRepresentation(_fotoArray[0], 0.40);
[body appendData:[NSData dataWithData:imageData]];
// Final Boundary
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// Set the body
[request setHTTPBody:body];

NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"%@", returnString);

我总是从服务器获得以下答案:

I always get this answer from the server:

{"idDica":0,"fotoDica":null,"horarioDica":null,"textoDica":null,"recomendado":0}

但是正确的应该是这样的:

But the right one should be something like this:

{"idDica":91,"fotoDica":"http://serveraddress.com/tips/91/6nyIZA8MPJ.png","horarioDica":1372960438226,"textoDica":"Hello","recomendado":1}

任何人都可以知道我在做什么错吗?

Can anyone have a clue on what am I doing wrong?

谢谢

这是Web服务代码(据我所知):

This is the web service code (out of my knowledge):

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public DicaRest uploadFile(
    @FormDataParam("foto1") InputStream uploadedInputStream1,
    @FormDataParam("foto1") FormDataContentDisposition fileDetail1,
    @FormDataParam("foto2") InputStream uploadedInputStream2,
    @FormDataParam("foto2") FormDataContentDisposition fileDetail2,
    @FormDataParam("foto3") InputStream uploadedInputStream3,
    @FormDataParam("foto3") FormDataContentDisposition fileDetail3,
    @FormDataParam("textoDica") String textoDica,
    @FormDataParam("idUsuario") long idUsuario,
    @FormDataParam("recomendou") boolean recomendou,
    @FormDataParam("idTags") String idTags,
    @FormDataParam("idMarcas") String idMarcas,
    @FormDataParam("idLocais") String idLocais,
    @FormDataParam("idCategorias") String idCategorias,
    @FormDataParam("idImpressoes") String idImpressoes)
{
    if(idTags == null)
        idTags = "";
    if(idMarcas == null)
        idMarcas = "";
    if(idLocais == null)
        idLocais = "";
    if(idCategorias == null)
        idCategorias = "";
    if(idImpressoes == null)
        idImpressoes = "";
    EntityManager em = EntityFactory.getEntityManager("RestCTPU");
    em.getTransaction().begin();
    DicaRest dicaRest = new DicaRest();
    Upload upload = new Upload();
    List<File> pathfoto = new ArrayList<File>();
    Dica novaDica = new Dica();
    int i = 0;

    try {
        novaDica.setTextoDica(textoDica);
        novaDica.setIdUsuario(new Usuario(idUsuario));
        novaDica.setRecomendado(recomendou);
        novaDica.setDataCadastro(new Date());
        novaDica.setEstadoHabilitado(true);
        novaDica = em.merge(novaDica);

        //LINUX AMI
        String pathLocal = "/var/lib/tomcat7/webapps/uploadtemp/"+novaDica.getIdDica() + "/";

        //WINDOWS
        //String pathLocal = "C:/teste/"+"dicas/"+novaDica.getIdDica() + "/";
        String pathAlvo = "dicas/"+novaDica.getIdDica() + "/";
        (new File(pathLocal)).mkdirs();
        if (fileDetail1.getFileName().length() > 0) {
            pathfoto.add( new File(pathLocal+Utilidades.getRandomPass(10)+fileDetail1.getFileName().substring(fileDetail1.getFileName().lastIndexOf("."))));
            saveToFile(uploadedInputStream1, pathfoto.get(i).getAbsolutePath());
            i++;
        }
        if (fileDetail2.getFileName().length() > 0) {
            pathfoto.add( new File(pathLocal +Utilidades.getRandomPass(10)+fileDetail1.getFileName().substring(fileDetail1.getFileName().lastIndexOf("."))));
            saveToFile(uploadedInputStream2, pathfoto.get(i).getAbsolutePath());
            i++;
        }
        if (fileDetail3.getFileName().length() > 0) {
            pathfoto.add( new File(pathLocal+Utilidades.getRandomPass(10)+fileDetail1.getFileName().substring(fileDetail1.getFileName().lastIndexOf("."))));
            saveToFile(uploadedInputStream3, pathfoto.get(i).getAbsolutePath());
            i++;
        }

        List<Tag> tags = new ArrayList<Tag>();
        if(idTags.length() > 0) {
            String[] tgs = idTags.split(";");
            for(String tag : tgs) {
                Tag nTag = new Tag(Long.valueOf(tag));
                tags.add(nTag);
            }
        }
        novaDica.setTagList(tags);
        List<Alvo> alvos = new ArrayList<Alvo>();
        if(idMarcas.length() > 0) {
                String[] marcas = idMarcas.split(";");
                for(String marca : marcas) {
                    Alvo nAlvo = new Alvo(Long.valueOf(marca));
                    alvos.add(nAlvo);
                }
        }
        if(idLocais.length() > 0) {
            String[] locais = idLocais.split(";");
            for(String local : locais) {
                Alvo nAlvo = new Alvo(Long.valueOf(local));
                alvos.add(nAlvo);
            }
        }
        novaDica.setAlvoList(alvos);
        List<CategoriaImpressao> categoriaImpressaoList = new ArrayList<CategoriaImpressao>();
        if(idCategorias.length() > 0) {
            String[] categorias = idCategorias.split(";");
            for(String categoria : categorias) {
                CategoriaImpressao nCat = new CategoriaImpressao(Long.valueOf(categoria));
                categoriaImpressaoList.add(nCat);
            }
        }
        if(idImpressoes.length() > 0) {
            String[] impressoes = idImpressoes.split(";");
            for(String impressao : impressoes) {
                CategoriaImpressao nImpress = new CategoriaImpressao(Long.valueOf(impressao));
                categoriaImpressaoList.add(nImpress);
            }
        }
        novaDica.setCategoriaImpressaoList(categoriaImpressaoList);
        //String uploadedFileLocation = fileDetail1.getFileName();
        // save it
        List<Foto> fts = new ArrayList<Foto>();
        for(String foto : upload.doUpload(pathfoto, pathAlvo)) {
            Foto ft = new Foto();
            ft.setUrlFoto(foto);
            ft.setIdDica(novaDica);
            ft.setDataCadastro(new Date());
            ft.setEstadoHabilitado(true);
            fts.add(ft);
        }
        novaDica.setFotoList(fts);
        em.persist(novaDica);
        em.getTransaction().commit();
        try {
            deleteDir(new File(pathLocal));
        } catch (Exception e){}
        dicaRest.setFotoDica(fts.get(0).getUrlFoto());
        dicaRest.setHorarioDica(new Date());
        dicaRest.setIdDica(novaDica.getIdDica());
        dicaRest.setRecomendado(recomendou);
        dicaRest.setTextoDica(textoDica);
    } catch (Exception e) {
        System.out.println(e);
    } finally {
        em.close();
        em.getEntityManagerFactory().close();
    }

    return dicaRest; 
}

推荐答案

我建议也尝试指定上传文件名,例如:

I'd suggest trying specifying the upload filename, too, e.g.:

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName, filename] dataUsingEncoding:NSUTF8StringEncoding]];

您还使用了file/jpegContent-Type,但是开发人员的规范说应该为image/jpegimage/png.所以您可能要使用:

You also use a Content-Type of file/jpeg, but the spec from the developer says it should be image/jpeg or image/png. So you might want to use:

[body appendData:[@"Content-Type: image/jpeg\r\n" dataUsingEncoding:NSUTF8StringEncoding]];

如果这两个都不做,我会注意到您的值与HTML示例不完全匹配,并且鉴于我们不知道验证规则是什么,我建议您使用完全相同的值(例如,HTML中的idTags2,而在Objective-C中是aaaaaa;bbbbbb;cccccc).但是我们无法知道PHP正在执行什么验证,因此消除了您未通过某些简单验证规则的可能性.确保您确信问题出在请求的形成,而不是请求中传递的数据.

If neither of those do it, I notice that your values don't exactly match the HTML example, exactly, and given that we don't know what the validation rules are, I'd suggest you use precisely the same values (e.g. idTags is 2 in the HTML, but aaaaaa;bbbbbb;cccccc in your Objective-C). But we have no way of knowing what validation the PHP is performing, so eliminate the possibility that you're just not passing some simple validation rule. Make sure you're confident the problem is the forming of the request, and not the data you're passing in the request.

希望您的PHP开发人员可以准确地告诉您正在进行什么验证.

Hopefully your PHP developer can tell you precisely what validation is taking place.

看看您的示例服务器源代码,我对该服务器代码不甚了解以进行诊断,但是有几点想法:

Looking at your sample server source code, I am not familiar enough with this server code to diagnose it, but a couple of thoughts:

  1. 在使用fileDetail2fileDetail3时,似乎抓住了fileDetail1扩展名的引用似乎是不对的(如果它们是不同的类型呢?!?).鉴于您只通过了一个,这不太可能成为问题的根源,但这似乎并不正确.

  1. It seems like the references that grab the extension of fileDetail1 when working with fileDetail2 and fileDetail3 seems like it can't be right (what if they were different types?!?). Given that you're passing only one, that's unlikely to be the source of the problem, but it doesn't seem right.

这将暗示,与我先前关于提供文件名的观察一致,这一点很重要,而且可能带有jpg扩展名.我鼓励您包括文件名(即使只是"test.jpg").

It would suggest, though, that consistent with my earlier observation about supplying a filename, it's important to do so, and probably one with a jpg extension. I would encourage you to include a filename (even if it's just "test.jpg").

这段代码使我想知道当您的请求未通过任何foto2foto3时会发生什么.希望它能优雅地处理该事件,不会引发任何异常,但我不能说.

This code makes me wonder what happens when your request doesn't pass any foto2 or foto3. Hopefully it handles that gracefully, not throwing any exception, but I can't say.

我可能误读了此内容,但看来您的idTags必须是用分号而不是aaaaaa;bbbbbb;cccccc分隔的数字.请参阅对Long的引用.

I may be misreading this, but it looks like your idTags must be numbers separated by semicolons, not aaaaaa;bbbbbb;cccccc. See the references to Long.

idImpressoes似乎也是如此,它应该是用分号分隔的数字,而不是bom;alegre.

It looks like the same is true with idImpressoes, that it should be numbers separate by semicolons, not bom;alegre.

让我惊讶的是,第4点和第5点是最直接的候选问题.我会把这两个数字都弄清楚,看看能不能解决这个问题.

It strikes me that point 4 and point 5 are the most immediate candidate issues. I'd make both of those numbers and see if that fixes it.

这篇关于在iOS上使用方法POST上传文件和文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆