Apache CXF REST 分段上传,编码异常

2024-01-23

我想使用多部分表单数据上传文件,但 URLDecoder 出现问题。服务代码如下:

@POST
@Path("/document")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response storeTravelDocument(
        @Context UriInfo uriInfo,
        @FormParam(value = "IDNR") String idnr,
        @FormParam(value="DOCNR") String documentNr,
        @FormParam(value="ISSUE_DATE") String issueDate,
        @Multipart(value = "image", type="image/jpeg") InputStream pictureStream)
{..

我测试了三个客户,例如放心:

given().
        formParam("IDNR", "A000000A").
        formParam("DOCNR", "00001").
        formParam("ISSUE_DATE", "14.06.2010").
        multiPart("image", new File(picturePath), "image/jpeg").
expect().
        statusCode(Response.Status.CREATED.getStatusCode()).
when().
        post("/document");

或 HttpClient:

    // build mulitpart entity
    MultipartEntity entity = new MultipartEntity();

    entity.addPart("IDNR", new StringBody("A000000A"));
    entity.addPart("DOCID", new StringBody("00001"));
    entity.addPart("ISSUE_DATE", new StringBody("14.06.2010"));

    FileBody fileBody = new FileBody(new File(picturePath), "image/jpeg");
    entity.addPart("image", fileBody);

    // build post request
    String uri = System.getProperty("service.url") + "/document"; 
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost = new HttpPost(uri);
    httpPost.setEntity(entity);

    // execute request
    HttpResponse response = httpClient.execute(httpPost);
    int code = response.getStatusLine().getStatusCode();

    // validate
    assert code == Response.Status.CREATED.getStatusCode();

在所有情况下我都会收到以下异常:

in escape (%) pattern - For input string: "¬ "
    at java.net.URLDecoder.decode(URLDecoder.java:192) ~[na:1.7.0_03]
    at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:55) ~[cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:63) ~[cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.HttpUtils.urlDecode(HttpUtils.java:81) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.FormUtils.populateMapFromMultipart(FormUtils.java:170) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processFormParam(JAXRSUtils.java:746) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.createHttpParameterValue(JAXRSUtils.java:667) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:625) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) [cxf-api-2.6.0.jar:2.6.0]
    ... 25 common frames omitted
2012-05-10 12:07:54,873 [http-bio-8080-exec-5] ERROR org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver - Error occurred during error handling, give up!
org.apache.cxf.interceptor.Fault: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "¬ "
    at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:75) ~[cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:322) [cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122) [cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:211) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:213) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:154) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:129) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:187) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:110) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [servlet-api.jar:na]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:166) [cxf-rt-transports-http-2.6.0.jar:2.6.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.27]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.27]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) [catalina.jar:7.0.27]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) [catalina.jar:7.0.27]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [catalina.jar:7.0.27]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [catalina.jar:7.0.27]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) [catalina.jar:7.0.27]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) [catalina.jar:7.0.27]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.27]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [catalina.jar:7.0.27]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) [tomcat-coyote.jar:7.0.27]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) [tomcat-coyote.jar:7.0.27]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307) [tomcat-coyote.jar:7.0.27]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_03]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_03]
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_03]
Caused by: java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern - For input string: "¬ "
    at java.net.URLDecoder.decode(URLDecoder.java:192) ~[na:1.7.0_03]
    at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:55) ~[cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.common.util.UrlUtils.urlDecode(UrlUtils.java:63) ~[cxf-api-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.HttpUtils.urlDecode(HttpUtils.java:81) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.FormUtils.populateMapFromMultipart(FormUtils.java:170) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processFormParam(JAXRSUtils.java:746) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.createHttpParameterValue(JAXRSUtils.java:667) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameter(JAXRSUtils.java:625) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.processParameters(JAXRSUtils.java:578) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:238) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:89) ~[cxf-rt-frontend-jaxrs-2.6.0.jar:2.6.0]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262) [cxf-api-2.6.0.jar:2.6.0]
    ... 25 common frames omitted

我知道 CXF 尝试解码我​​的文件(图片)并因无效字符而引发异常,但我想阻止这种解码。该文件应仅作为 UTF-8 流传输,保持不变且不解码。谁能帮我?


该问题在 Apache CXF 上得到解决邮件列表 http://mail-archives.apache.org/mod_mbox/cxf-users/201205.mbox/browser作者:谢尔盖·别廖兹金。

总结一下:

此声明所发生的情况是,表单有效负载处理器假定最后一个参数只是一个更简单的多部分/表单数据参数。当您有一个“混合”多部分/表单数据有效负载时,包含简单的字符串名称/值对以及二进制部分,最好避免使用 @FormParam 或 @Multipart 注释,而仅使用 MultipartBody 输入参数 - 它将提供对所有单独部分的类型安全访问。

用 @Multipart 替换 @FormParam 应该可以解决问题(作为引入 MultipartBody 的替代方案),但是 @FormParam 和 @Multipart 的混合也应该理想地工作。将检查此问题。

我选择用 @Multipart 替换 @FormParam 并且这有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Apache CXF REST 分段上传,编码异常 的相关文章

随机推荐