Camel 2.24.0
我正在努力从一个带文件字段的web表单中加载一个不是拉丁字符集的简单csv文件。
<form action="/register/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="inputfile"/>
<input type="submit"/>
这是我当前的端点URL。
jetty:http://0.0.0.0:{{web.port}}/register/upload?httpMethodRestrict=POST
所发生的事情是,文件的内容被转换为字符串,并用多个黑色问号代替非拉丁字符。
当我试着加载一个二进制文件(如jpeg)时,它仍然将文件内容以一个丑陋的String形式放入HttpMessage的头部。
我看不出我要求把我的文件转换成String的地方,但对于一个文本(csv)文件来说,如果能够使用一些拉丁字母1以外的字符集就可以了。
我到处看了很多文章,也试过不同的魔法,但都没有用。我记得的是用一个url查询参数来关闭多部分过滤器,并在网页表单中添加一个隐藏的 _charset_
领域。
该 Apache Jetty组件 说Multi-part应该是开箱即用,甚至还提到了一些例子,但遗憾的是没有超链接。总之,HttpMessage附件是空的,所以实际上并不能像宣传的那样工作。
所以简单来说,问题是 "我如何指定我的端点URL,使我能够获得通过web表单上传的非损坏的文件内容,以及我如何获得文件内容"。或者说,"我是否需要在web表单中添加一些属性"
你需要考虑一些事情。
你提到了 "隐藏的charset字段"。 它实际上叫做 _charset_
(开头和结尾都有下划线),了解它在HTML表单中的工作原理很重要。
它的工作原理是在你的表单中创建一个隐藏的字段,就像这样......。
<html>
<body>
<form method="POST"
enctype="multipart/form-data"
action="/formsubmit">
<input type="hidden" name="_charset_"/>
<p>Japanese</p>
<input type="text" name="japanese" value="健治"/>
<p>Hello</p>
<input type="text" name="hello" value="ャユ戆タ"/>
<p></p>
<input type="Submit" value="Capture">
</form>
</body>
</html>
然而,这是个不完整的例子。
为什么这么说呢? 嗯,这将通过 _charset_
表单条目,无论浏览器的HTML文档字符集是什么。 在上面的例子中,它可以是几乎任何东西,而且是不可预测的。
您可以将文档字符集指定为一个元条目,像这样......。
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form ...>
这将以utf-8格式显示HTML 和 提交表格的地方 _charset_
条目为值 utf-8
. (它还可以使任何手打到你的表格中的文本字段成为UTF-8)
但是等等,如果你想让表格采用不同的字符集呢?
你可以这样做...
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<form accept-charset="windows-1251"
method="POST"
enctype="multipart/form-data"
action="/formsubmit">
<input type="hidden" name="_charset_"/>
...
这将声明所有提交的表格都是 windows-1251
,而这也是通过提交 _charset_
价值的条目 windows-1251
.
但这意味着您提交的表格将被 windows-1251
对于某些提交的文件来说,这可能是不可行的。
您还提到您正在进行CSV表格上传。
您可能需要考虑用表单文件上传来代替(因为这将不会通过 _charset_
或编码类型)。)
<form method="POST"
enctype="multipart/form-data"
action="/formupload">
<p>File</p>
<input type="file" name="file"/>
<input type="Submit" value="Capture">
</form>
这一切的前提是Apache Camel使用的是 HttpServletRequest.getParts()
和等价的)API,而不是一些自定义的东西。(比如古老的Apache FileUpload lib)。
API的工作方式是,多部分的所有部分都是二进制的,在你试图访问它之前,没有编码或字符集与它们相关联。
对于 <input>
条目,没有通过Servlet的 Part
API。
然而,如果Apache Camel使用 HttpServletRequest.getParameter()
风格的API,然后是 _charset_
是在返回String时应用于多部分持有的二进制数据。
相当于...
String charset = getPart("_charset_");
if(charset == null)
charset = "utf-8"
try(InputStream in = getPart(keyname).getInputStream();
InputStreamReader reader = new InputStreamReader(in, Charset.forName(charset));
StringWriter writer = new StringWriter()) {
IO.copy(reader, writer);
return writer.toString();
}