使用Java中的Web代理签署PDF时的错误代码706

时间:2014-12-05 03:47:46

标签: cosign-api

在Java中测试Web代理示例时,我收到错误回复

<?xml version="1.0" encoding="utf-8"?>
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" type="error">
  <Error>
    <returnCode>706</returnCode>
    <errorMessage>Value cannot be null.
Parameter name: s</errorMessage>
  </Error>
</response>

我遵循了CoSign Web Agent样本中的Ruby示例和documentation

我使用了示例中提供的 demo.pdf 文件。

这是在POST请求中发送的XML(来自test app)(<content></content>具有Base64编码的PDF,但由于篇幅而省略)。

<?xml version="1.0" encoding="utf-8" ?>
<request>
  <Logic>
    <allowAdHoc>true</allowAdHoc>
    <workingMode>pull</workingMode>
    <enforceReason>false</enforceReason>
  </Logic>
  <Url>
    <finishURL>http://localhost:64956/retrieveSignedFile.aspx</finishURL>
  </Url>
  <Document>
    <fileID>1234567890</fileID>
    <contentType>pdf</contentType>
    <content>{BASE64 encoded pdf content}</content>
  </Document>
</request>

以下是我使用过的java代码:

public class CoSignTest {
    private static final String INPUT = "D:\\tmp\\demo.pdf";
    private static final String PRECONTENT = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
            "<request>\n" +
            "  <Logic>\n" +
            "    <allowAdHoc>true</allowAdHoc>\n" +
            "    <workingMode>pull</workingMode>\n" +
            "    <enforceReason>false</enforceReason>\n" +
            "  </Logic>\n" +
            "  <Url>\n" +
            "    <finishURL>http://localhost:64956/retrieveSignedFile.aspx</finishURL>\n" +
            "  </Url>\n" +
            "  <Document>\n" +
            "    <fileID>1234567890</fileID>\n" +
            "    <contentType>pdf</contentType>\n" +
            "    <content>";
    private static final String POSTCONTENT = "</content>\n" +
            "  </Document>\n" +
            "</request>";
    private static final String POST_URL = "https://webagentdev.arx.com/Sign/UploadFileToSign";
    private static final String PULL_URL = "https://webagentdev.arx.com/Sign/DownloadSignedFileG";
    public static final int TIMEOUT = 300000;

    public static void main(String[] args) throws Exception {
        InputStream is = new FileInputStream(INPUT);
        String content = PRECONTENT + new String(Base64.encodeBase64(loadResource(is)), "UTF-8") + POSTCONTENT;
        System.out.println(content);
        String reply = new String(sendDocForProcessing(URLEncoder.encode(content, "UTF-8")));
        System.out.println(reply);
        System.out.println("DONE");
    }

    private static String sendDocForProcessing(String content) throws Exception {
        HttpClient client = null;
        HttpMethodBase method = null;
        SimpleHttpConnectionManager mgr = new SimpleHttpConnectionManager();
        String reply = "";
        try {
            mgr.getParams().setConnectionTimeout(TIMEOUT);
            mgr.getParams().setSoTimeout(TIMEOUT);
            client = new HttpClient(mgr);
            method = new PostMethod(POST_URL);
            method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));
            method.getParams().setParameter("http.socket.timeout", TIMEOUT);
            client.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT);
            client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
            method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            method.getParams().setParameter("inputXML", content);
            client.executeMethod(method);
            reply = new String(method.getResponseBody());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(method != null) {
                method.releaseConnection();
            }
            client = null;
            mgr.shutdown();
        }
        if (isSigningSuccessful(reply)) {
            return reply;
        } else {
            throw new Exception("Failed in signing the document. Error: " + reply);
        }
    }

    private static boolean isSigningSuccessful(String reply) throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new ByteArrayInputStream(reply.getBytes()));
        Element elem = doc.getDocumentElement();
        String type = elem.getAttribute("type");
        return !"error".equals(type);
    }


    public static byte[] loadResource(InputStream in) {
        if (in == null) {
            return new byte[0];
        }
        try {
            int indice, tempIndice;
            byte[] tempArr;
            byte[] mainArr = new byte[0];
            byte[] byteArr = new byte[65535];
            for (indice = 0; (indice = in.read(byteArr)) > 0;) {
                tempIndice = mainArr.length + indice;
                tempArr = new byte[tempIndice];
                System.arraycopy(mainArr, 0, tempArr, 0, mainArr.length);
                System.arraycopy(byteArr, 0, tempArr, mainArr.length, indice);
                mainArr = tempArr;
            }
            in.close();
            return mainArr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new byte[0];
    }
}

2 个答案:

答案 0 :(得分:1)

XML元素区分大小写,必须按documentation所示传递(例如Document而不是documentAuth而不是auth等等)。此外,您的XML请求缺少必需的finishURL参数。

另请注意,XML请求中的某些参数已过时。请参阅上面链接中的更新请求参数列表。可以使用示例XML here

答案 1 :(得分:0)

感谢您添加Java代码。请注意,HttpClient实例配置不正确,因此http-post请求被发送为空。看看我在sendDocForProcessing函数中所做的修改,以便正确发布XML内容:

private static String sendDocForProcessing(String content) throws Exception {
    HttpClient client = null;
    PostMethod method = null;
    String reply = "";
    try {
        client = new HttpClient();
        method = new PostMethod(POST_URL);
        method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        NameValuePair[] data = { new NameValuePair("inputXML", content) };
        method.setRequestBody(data);
        client.executeMethod(method);
        reply = method.getResponseBodyAsString();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(method != null) {
            method.releaseConnection();
        }
    }
    if (isSigningSuccessful(reply)) {
        return reply;
    } else {
        throw new Exception("Failed in signing the document. Error: " + reply);
    }
}

传递给上述函数的内容不应进行URL编码,因为它已由HttpClient库完成。

此外,在分析响应时,我建议您检查returnCode元素的值而不是type属性。响应始终为“错误”类型。 另请注意,函数名称isSigningSuccessful具有误导性,因为此阶段仍然在签名行为之前。