从Java到Coldfusion的多部分文件传输-无前导边界:%PDF-1.4

从Java到Coldfusion的多部分文件传输-无前导边界:%PDF-1.4,java,unit-testing,pdf,post,coldfusion,Java,Unit Testing,Pdf,Post,Coldfusion,在提问之前,我发布了一个关于使用HTML5的多部分/表单数据将多个文件上传到coldfusion的问题。它工作得很好。 我们的客户最终要求对我组装的RESTful函数进行一些单元测试,我已经完成了很多工作,但是我在上面设计的massUpload函数遇到了一个障碍 很抱歉提出了这么长的问题,请写下与问题相关的内容 以下是相关代码: 单元测试代码: //Outside class calling sendHTTPrequest HashMap<String,String> map =

在提问之前,我发布了一个关于使用HTML5的多部分/表单数据将多个文件上传到coldfusion的问题。它工作得很好。

我们的客户最终要求对我组装的RESTful函数进行一些单元测试,我已经完成了很多工作,但是我在上面设计的massUpload函数遇到了一个障碍

很抱歉提出了这么长的问题,请写下与问题相关的内容

以下是相关代码:

单元测试代码:

//Outside class calling sendHTTPrequest
HashMap<String,String> map = new HashMap<String,String>();
HashMap<String,File> getFiles = getFirstFileList();
map.put("testMethod", "massUploadTest");
map.put("method", "massUpload");
map.put("valueString1", valueString1);
map.put("valueString2", valueString2);
map.put("valueNumeric3", valueNumeric3);
map.put("valueBoolean4", valueBoolean4);
map.put("valueString5", valueString5);
map.put("valueBoolean6", valueBoolean6);
map.put("valueString7", valueString7);

try {                    
    sendHTTPrequest(map, getFiles);
} catch(RuntimeException e) {
    throw new RuntimeException("Fatal error in massUpload\n"
            + e.getMessage());
}
//End Call class code
//外部类调用sendHTTPrequest
HashMap=newHashMap();
HashMap getFiles=getFirstFileList();
map.put(“testMethod”、“massUploadTest”);
map.put(“方法”、“批量上传”);
映射放置(“valueString1”,valueString1);
map.put(“valueString2”,valueString2);
地图放置(“valueNumeric3”,valueNumeric3);
map.put(“valueBoolean4”,valueBoolean4);
map.put(“valueString5”,valueString5);
map.put(“valueBoolean6”,valueBoolean6);
map.put(“valueString7”,valueString7);
试试{
sendHTTPrequest(映射、获取文件);
}捕获(运行时异常e){
抛出新的RuntimeException(“massUpload中出现致命错误\n”
+e.getMessage());
}
//结束调用类代码
Coldfusion功能:

<cffunction name="massUpload" access="remote" returntype="string">    
    <cfargument name="valueString1"  type="string"  required="false">
    <cfargument name="valueString2"  type="string"  required="false">
    <cfargument name="valueNumeric3" type="numeric" required="false" default=0>
    <cfargument name="valueBoolean4" type="boolean" required="true"  default="false">
    <cfargument name="valueString5"  type="string"  required="false">
    <cfargument name="valueBoolean6" type="boolean" required="false" default="true">
    <cfargument name="valueString7"  type="string"  required="true">

    <!--- massUpload code --->
</cffunction>

下面是导致主要问题的代码。我尝试了不同的方法来让帖子正常工作,所以代码显然有问题。我试图在不下载多个软件/库的情况下完成这项工作,但如果没有其他方法,那么我将做出必要的安排。否则,我们希望通过标准Java库完成这项工作

功能代码:

//sendHTTPrequest method code
protected static final String BASE_URI = "<webaddress>/rest.cfc";
protected static final String CHARSET = "UTF-8";
protected String response;
protected int status;
protected String statusMessage;

protected void sendHTTPrequest(Map<String,String> map, Map<String, File> fileList) {

        Set<String> keys = map.keySet();
        status = 0;
        response = null;
        String boundary = "----" + System.currentTimeMillis();

        try {            
            URL_CONNECTION = BASE_URL.openConnection();
            HTTP_CONNECTION = (HttpURLConnection) (URL_CONNECTION);

            //Set the request headers
            HTTP_CONNECTION.setRequestMethod("POST");
            URL_CONNECTION.setRequestProperty("Accept-Charset", CHARSET);            
            URL_CONNECTION.setRequestProperty("Content-type", "multipart/form-data; boundary=" + boundary);

            //Set up a post request
            URL_CONNECTION.setDoOutput(true);

            OutputStream output = URL_CONNECTION.getOutputStream();
            ByteArrayOutputStream bOutput = new ByteArrayOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, CHARSET), true);

            for(String key : keys) {
                writer.write("--" + boundary);
                writer.write(lineFeed);
                writer.write("Content-Disposition: form-data; name=\"" + key + "\"");
                writer.write(lineFeed);
                writer.write(lineFeed);
                writer.write(map.get(key));
                writer.write(lineFeed);
            }

            FileInputStream inputStream;
            for(Map.Entry<String, File> entry : fileList.entrySet()){
                String name = entry.getKey();
                writer.write("--" + boundary);
                writer.write(lineFeed);
                writer.write("Content-Disposition: form-data; "
                        + "name=\"allfiles\"; filename=\"" + name + "\"");
                writer.write(lineFeed);

                String contentType = URLConnection.guessContentTypeFromName(name);
                writer.write("Content-Type: " + contentType);
                writer.write(lineFeed);    

                writer.write("Content-Transfer-Encoding: binary");
                writer.write(lineFeed);    

                writer.write("Content-Id: <" + boundary + ">");
                writer.write(lineFeed);  
                writer.write(lineFeed);  

                File temp = entry.getValue();

                byte[] buffer = FileUtils.readFileToByteArray(temp);
                output.write(buffer, 0, buffer.length);
                output.flush();

                writer.write(lineFeed);    
            }

            writer.write("--" + boundary + "--");
            writer.write(lineFeed);
            writer.flush();

            writer.close();

            status = HTTP_CONNECTION.getResponseCode();
            statusMessage = HTTP_CONNECTION.getResponseMessage();
            if(status == SUCCESS) {
                response = IOUtils.toString(URL_CONNECTION.getInputStream(), URL_CONNECTION.getContentEncoding());
            }
            System.out.println("Finished test " + map.get("testMethod") + " Status: " + status);
            System.out.println("Response: " + response);
            HTTP_CONNECTION.disconnect();

        } catch(UnknownServiceException use) {
            throw new RuntimeException("Protocol for the output is not supported");
        } catch(IOException ioe) {
            throw new RuntimeException("Unable to create the output stream");
        }
    }
//End sendHTTPrequest method code
//sendHTTPrequest方法代码
受保护的静态最终字符串BASE_URI=“/rest.cfc”;
受保护的静态最终字符串CHARSET=“UTF-8”;
受保护字符串响应;
受保护的int状态;
受保护的字符串状态消息;
受保护的void sendHTTPrequest(映射、映射文件列表){
Set keys=map.keySet();
状态=0;
响应=空;
字符串边界=“----”+System.currentTimeMillis();
试试{
URL\u CONNECTION=BASE\u URL.openConnection();
HTTP_连接=(HttpURLConnection)(URL_连接);
//设置请求头
HTTP_CONNECTION.setRequestMethod(“POST”);
URL_CONNECTION.setRequestProperty(“接受字符集”,字符集);
URL_CONNECTION.setRequestProperty(“内容类型”、“多部分/表单数据;边界=“+boundary”);
//设置post请求
URL_CONNECTION.setDoOutput(true);
OutputStream output=URL_CONNECTION.getOutputStream();
ByteArrayOutputStream bOutput=新建ByteArrayOutputStream();
PrintWriter writer=新的PrintWriter(新的OutputStreamWriter(输出,字符集),true);
用于(字符串键:键){
writer.write(“--”+边界);
writer.write(lineFeed);
write(“内容配置:表单数据;名称=\”“+key+\”);
writer.write(lineFeed);
writer.write(lineFeed);
writer.write(map.get(key));
writer.write(lineFeed);
}
文件输入流输入流;
对于(Map.Entry:fileList.entrySet()){
字符串名称=entry.getKey();
writer.write(“--”+边界);
writer.write(lineFeed);
write(“内容配置:表单数据
+“名称=\”所有文件“;文件名=\”+名称+”\”);
writer.write(lineFeed);
字符串contentType=URLConnection.guessContentTypeFromName(名称);
writer.write(“内容类型:”+contentType);
writer.write(lineFeed);
write(“内容传输编码:二进制”);
writer.write(lineFeed);
writer.write(“内容Id:”);
writer.write(lineFeed);
writer.write(lineFeed);
File temp=entry.getValue();
字节[]缓冲区=FileUtils.readFileToByteArray(临时);
输出.写入(缓冲区,0,缓冲区.长度);
output.flush();
writer.write(lineFeed);
}
writer.write(“-”+边界+“-”);
writer.write(lineFeed);
writer.flush();
writer.close();
status=HTTP_CONNECTION.getResponseCode();
statusMessage=HTTP_CONNECTION.getResponseMessage();
如果(状态==成功){
response=IOUtils.toString(URL\u CONNECTION.getInputStream(),URL\u CONNECTION.getContentEncoding());
}
System.out.println(“完成的测试”+map.get(“测试方法”)+“状态:”+Status);
System.out.println(“响应:+Response”);
HTTP_CONNECTION.disconnect();
}捕获(未知服务异常使用){
抛出新的RuntimeException(“输出协议不受支持”);
}捕获(ioe异常ioe){
抛出新的RuntimeException(“无法创建输出流”);
}
}
//结束sendHTTPrequest方法代码
在status、response和statusMessage的输出中,我看到一个500错误,null,内部服务器错误

查看Coldfusion服务器,我看到:

SEVERE: Servlet.service() for servlet [CFCServlet] in context with path [/] threw exception 
java.io.IOException: Corrupt form data: no leading boundary: %PDF-1.4 != ------1429222349902
at com.oreilly.servlet.multipart.MultipartParser.<init>(MultipartParser.java:182)
...
SEVERE:Servlet[CFCServlet]在路径为[/]的上下文中的Servlet.service()引发异常
java.io.IOException:损坏的表单数据:无前导边界:%PDF-1.4!=------1429222349902
位于com.oreilly.servlet.multipart.MultipartParser.(MultipartParser.java:182)
...
massUpload可以处理不同类型的文件,但专门针对PDF。因此,单元测试需要能够将不同的文件类型发送到massUpload,而不是
...
byte[] buffer = FileUtils.readFileToByteArray(temp);
writer.flush(); // flush stream here
output.write(buffer, 0, buffer.length);
...
POST http://localhost:8888/test.cfm HTTP/1.1
Accept-Charset: UTF-8
Content-Type: multipart/form-data; boundary=14cd4c75e24
...
Content-Length: 65570

%PDF-1.4
%    
2 0 obj <</Type/XObject/ColorSpace/DeviceGray/Subtype/Image/BitsPerComponent 8/Width 612/Length 11876/Height 792/Filter/FlateDecode>>stream

... more binary

--14cd4c75e24
Content-Disposition: form-data; name="allfiles"; filename="file0.pdf"
Content-Type: application/pdf
Content-Transfer-Encoding: binary
Content-Id: <14cd4c75e24>


--14cd4c75e24--
POST http://localhost:8888/test.cfm HTTP/1.1
Accept-Charset: UTF-8
Content-Type: multipart/form-data; boundary=14cd4c91d29
...
Content-Length: 65570

--14cd4c91d29
Content-Disposition: form-data; name="allfiles"; filename="file0.pdf"
Content-Type: application/pdf
Content-Transfer-Encoding: binary
Content-Id: <14cd4c91d29>

%PDF-1.4
%    
2 0 obj <</Type/XObject/ColorSpace/DeviceGray/Subtype/Image/BitsPerComponent 8/Width 612/Length 11876/Height 792/Filter/FlateDecode>>stream
...