Att*_*lio 9 java apache http multipart
我认为标题说明了一切:我正在寻找解析包含 multipart/form-data HTTP 请求正文部分的String的方法。即字符串的内容看起来像这样:
--xyzseparator-blah
Content-Disposition: form-data; name="param1"
hello, world
--xyzseparator-blah
Content-Disposition: form-data; name="param2"
42
--xyzseparator-blah
Content-Disposition: form-data; name="param3"
blah, blah, blah
--xyzseparator-blah--
Run Code Online (Sandbox Code Playgroud)
我希望得到的是一张parameters地图,或者类似的东西。
parameters.get("param1"); // returns "hello, world"
parameters.get("param2"); // returns "42"
parameters.get("param3"); // returns "blah, blah, blah"
parameters.keys(); // returns ["param1", "param2", "param3"]
Run Code Online (Sandbox Code Playgroud)
xyzseparator-blah在这种情况下),,但如果我必须这样做,我可以忍受它。如果有一个满足上述条件的解决方案,但其输入是 ApacheHttpRequest而不是 a String,那也是可以接受的。(基本上,我确实收到了一个HttpRequest,但我使用的内部库是这样构建的,它将此请求的主体提取为字符串,并将其传递给负责进行解析的类。但是,如果需要的话,我也可以直接在HttpRequest.)
无论我如何尝试通过 Google、SO 和其他论坛找到答案,解决方案似乎总是使用commons fileupload来浏览各个部分。例如:here、here、here、here、here ... 但是,parseRequest该解决方案中使用的方法需要 a RequestContext,而我没有(只有HttpRequest)。
另一种方式,也在上面的一些答案中提到,是从HttpServletRequest(但同样,我只有HttpRequest)获取参数。
编辑:换句话说:我可以包括 Commons Fileupload(我可以访问它),但这对我没有帮助,因为我有一个HttpRequest,而 Commons Fileupload 需要RequestContext. (除非有一种简单的方法可以从 转换HttpRequest为RequestContext,而我忽略了这一点。)
您可以使用 Commons FileUpload 解析您的字符串,方法是将其包装在实现“org.apache.commons.fileupload.UploadContext”的类中,如下所示。
不过,出于几个原因,我建议将 HttpRequest 包装在您建议的替代解决方案中。首先,使用字符串意味着整个多部分 POST 主体,包括文件内容,需要适合内存。包装 HttpRequest 将允许您流式传输它,一次在内存中只有一个小缓冲区。其次,如果没有 HttpRequest,您将需要嗅出多部分边界,这通常位于“内容类型”标头中(请参阅RFC1867)。
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
public class MultiPartStringParser implements org.apache.commons.fileupload.UploadContext {
public static void main(String[] args) throws Exception {
String s = new String(Files.readAllBytes(Paths.get(args[0])));
MultiPartStringParser p = new MultiPartStringParser(s);
for (String key : p.parameters.keySet()) {
System.out.println(key + "=" + p.parameters.get(key));
}
}
private String postBody;
private String boundary;
private Map<String, String> parameters = new HashMap<String, String>();
public MultiPartStringParser(String postBody) throws Exception {
this.postBody = postBody;
// Sniff out the multpart boundary.
this.boundary = postBody.substring(2, postBody.indexOf('\n')).trim();
// Parse out the parameters.
final FileItemFactory factory = new DiskFileItemFactory();
FileUpload upload = new FileUpload(factory);
List<FileItem> fileItems = upload.parseRequest(this);
for (FileItem fileItem: fileItems) {
if (fileItem.isFormField()){
parameters.put(fileItem.getFieldName(), fileItem.getString());
} // else it is an uploaded file
}
}
public Map<String,String> getParameters() {
return parameters;
}
// The methods below here are to implement the UploadContext interface.
@Override
public String getCharacterEncoding() {
return "UTF-8"; // You should know the actual encoding.
}
// This is the deprecated method from RequestContext that unnecessarily
// limits the length of the content to ~2GB by returning an int.
@Override
public int getContentLength() {
return -1; // Don't use this
}
@Override
public String getContentType() {
// Use the boundary that was sniffed out above.
return "multipart/form-data, boundary=" + this.boundary;
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(postBody.getBytes());
}
@Override
public long contentLength() {
return postBody.length();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11866 次 |
| 最近记录: |