【问题标题】:RESTlet: How to process multipart/form-data requests?RESTlet:如何处理多部分/表单数据请求?
【发布时间】:2010-11-03 01:36:25
【问题描述】:

当它是一个多部分/表单数据请求时,如何捕获传入的 @Post 变量?

对于常规的 Post 请求,我会这样做:

@Post
public void postExample(Representation entity) throws Exception{
   Form form = new Form(entity);
   System.out.println(form.getFirstValue("something"));
}

但是因为它是一个多部分/表单数据请求,所以上面的输出 null

我是 Java 新手,所以要温柔 :)

PS:我对处理传入的文件不感兴趣,只对文本字段感兴趣。

【问题讨论】:

  • 可以将表单数据添加为html吗?

标签: java restlet multipartform-data


【解决方案1】:

这是我的一种方法(Restlet 2.0)的粘贴。这里我有一个表单,其中包括一个文件上传和其他字段,因此它相当完整:

@Post
public Representation createTransaction(Representation entity) {
    Representation rep = null;
    if (entity != null) {
        if (MediaType.MULTIPART_FORM_DATA.equals(entity.getMediaType(), true)) {
            // 1/ Create a factory for disk-based file items
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(1000240);

            // 2/ Create a new file upload handler
            RestletFileUpload upload = new RestletFileUpload(factory);
            List<FileItem> items;
            try {
                // 3/ Request is parsed by the handler which generates a list of FileItems
                items = upload.parseRequest(getRequest());

                Map<String, String> props = new HashMap<String, String>();
                File file = null;
                String filename = null;

                for (final Iterator<FileItem> it = items.iterator(); it.hasNext(); ) {
                    FileItem fi = it.next();
                    String name = fi.getName();
                    if (name == null) {
                        props.put(fi.getFieldName(), new String(fi.get(), "UTF-8"));
                    } else {
                        String tempDir = System.getProperty("java.io.tmpdir");
                        file = new File(tempDir + File.separator + "file.txt");
                        filename = name;
                        fi.getInputStream();
                        fi.write(file);
                    }
                }

                // [...] my processing code

                String redirectUrl = ...; // address of newly created resource
                getResponse().redirectSeeOther(redirectUrl);
            } catch (Exception e) {
                // The message of all thrown exception is sent back to
                // client as simple plain text
                getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
                e.printStackTrace();
                rep = new StringRepresentation(e.getMessage(), MediaType.TEXT_PLAIN);
            }
        } else {
            // other format != multipart form data
            getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
            rep = new StringRepresentation("Multipart/form-data required", MediaType.TEXT_PLAIN);
        }
    } else {
        // POST request with no entity.
        getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
        rep = new StringRepresentation("Error", MediaType.TEXT_PLAIN);
    }

    return rep;
}

我最终会将它重构为更通用的东西,但这就是我现在所拥有的。

【讨论】:

  • 但是您不需要为 Post 请求添加注释,例如 @Post("form") 之类的吗?我因为做了非常相似的事情而返回了 405
  • 我确实有一个 @Post 注释(但没有参数)。该参数限制您接受的表示形式 (restlet.org/documentation/2.0/jse/api/org/restlet/resource/…)。 HTTP 405 是不允许的方法 (w3.org/Protocols/rfc2616/rfc2616-sec10.html) - 如果不存在 @Post 注释,Restlet 可能无法将您的资源识别为“可发布”。
  • 我把它当作@Post,它继续返回405。然后我添加了这个:getMetadataService().addExtension("multipart", MediaType.MULTIPART_FORM_DATA, true);到资源构造函数,并将我的注释从 @Post 更改为 @Post("multipart") ,然后它就起作用了。
【解决方案2】:

将它打包成一行,在你的 Restlet Resource 类中:

Iterator it = new RestletFileUpload(new DiskFileItemFactory()).parseRequest(getRequest()).iterator();

然后在您的项目循环中,您可以使用以下方法测试它们是否为 fileItems:isFormField()。

测试 fileItem 是否为 formField... 有意义吗? ;)
但它有效。

祝你好运。

【讨论】:

    【解决方案3】:

    回答我自己的问题,这在 1.2 版中目前不可行

    【讨论】:

      猜你喜欢
      • 2013-04-27
      • 1970-01-01
      • 2015-09-28
      • 2014-09-21
      • 2012-09-10
      • 1970-01-01
      • 2012-11-17
      • 2017-10-26
      • 2020-03-14
      相关资源
      最近更新 更多