当前位置: 代码网 > it编程>编程语言>Java > Resttemplate上传文件500异常的原因及解决方法

Resttemplate上传文件500异常的原因及解决方法

2024年08月20日 Java 我要评论
一、问题背景使用 resttemplate 调用 dms 文件服务器 http 接口,出现 500 异常报错二、问题描述通过 clienthttprequestinterceptor 拦截器设置 co

一、问题背景

使用 resttemplate 调用 dms 文件服务器 http 接口,出现 500 异常报错

二、问题描述

通过 clienthttprequestinterceptor 拦截器设置 contenttype 和 basicauth 后,调用dms 文件服务器 http 接口,出现 500 异常报错

三、相关代码

resttemplate 及自定义 clienthttprequestinterceptor bean 对象代码

@bean(name = "dmsresttemplate")
public resttemplate resttemplate(
    @qualifier("dmsrequestinterceptor") clienthttprequestinterceptor dmsrequestinterceptor) {
    resttemplate resttemplate = new resttemplate();
    ((allencompassingformhttpmessageconverter) resttemplate.getmessageconverters().get(4))
        .setmultipartcharset(standardcharsets.utf_8);
    resttemplate.getinterceptors().add(dmsrequestinterceptor);
    resttemplate.seterrorhandler(new defaultresponseerrorhandler() {
        @override
        public boolean haserror(clienthttpresponse response) throws ioexception {
            return super.haserror(response.getstatuscode())
                && !httpstatus.not_found.equals(response.getstatuscode());
        }

        @override
        public void handleerror(clienthttpresponse response) throws ioexception {
            super.handleerror(response);
        }
    });
    return resttemplate;
}

@bean
public clienthttprequestinterceptor dmsrequestinterceptor(filestorageproperties filestorageproperties) {
    string username = filestorageproperties.getdms().getusername();
    string password = filestorageproperties.getdms().getpassword();
    return (request, body, execution) -> {
        httpheaders headers = request.getheaders();
        mediatype type = mediatype.parsemediatype(mediatype.multipart_form_data_value);
        headers.setcontenttype(type);
        headers.setbasicauth(username, password, standardcharsets.utf_8);
        return execution.execute(request, body);
    };
}

文件上传代码

@override
public filestoragebo upload(string filepath) throws baseappexception {
    logger.debug("dmsfilestorage upload by file path start.");
    if (stringutils.isempty(filestorageproperties.getdms().getresturl())) {
        logger.error("dms rest url config not exist!");
        exceptionhandler.publish("epa-common-0010", exceptionhandler.buss_error);
    }
    file tempfile = new file(filepath);
    filestoragebo result = new filestoragebo(tempfile);
    multivaluemap<string, object> postparameters = new linkedmultivaluemap<>();
    filesystemresource resource = new filesystemresource(tempfile.getabsolutepath());
    postparameters.add("file", resource);
    postparameters.add("shardingkey", "epa_" + getshardingkey());
    httpentity<multivaluemap<string, object>> httpentity = new httpentity<>(postparameters);
    try {
        string dmsid = dmsresttemplate.postforobject(filestorageproperties.getdms().getresturl() + "/file",
            httpentity, string.class);
        result.setfileidentity(dmsid);
        logger.debug("dmsfilestorage upload by file path end. dms id is {}", dmsid);
    }
    catch (restclientexception e) {
        logger.error(e);
        exceptionhandler.publish("epa-common-0011", exceptionhandler.buss_error, e.getlocalizedmessage());
    }

    return result;
}

四、问题原因

拦截器中设置 contenttype 为 multipart/form-data 时,无法自动生成 boundary 信息,导致无法根据该分隔符信息来解析请求体

在使用multipart/form-data格式发送http请求时,请求体的数据会被分割成多个部分,每个部分之间使用一个特定的分隔符(boundary)进行分隔。这个boundary是在content-type头部中指定的,用于告诉服务器如何识别每个部分的开始和结束。

当使用resttemplate发送multipart/form-data请求时,resttemplate会自动处理boundary的生成和添加到请求的content-type头部中。这样服务器就能够正确解析请求体中的各个部分。

使用resttemplate构建multipart/form-data请求时,只需设置正确的content-typemultipart/form-dataresttemplate会负责生成请求体的各个部分,并在content-type头部中添加正确的boundary信息。

不需要手动追加boundary到请求体中,resttemplate会在内部处理这一细节,确保请求能够正确地被服务器解析。

因此,使用resttemplate发送multipart/form-data请求时,只需设置正确的content-typemultipart/form-dataresttemplate会负责处理boundary的生成和添加,确保请求能够正确发送到服务器并被正确解析。

通常情况下,content-type的设置应该由发送请求的代码负责,而不是在clienthttprequestinterceptor中进行设置。clienthttprequestinterceptor主要用于在发送请求之前或之后对请求进行修改或处理,例如添加认证信息、日志记录、错误处理等。

五、问题修复

将 contenttype 移到上传代码中

拦截器 bean:

@bean
public clienthttprequestinterceptor dmsrequestinterceptor(filestorageproperties filestorageproperties) {
    string username = filestorageproperties.getdms().getusername();
    string password = filestorageproperties.getdms().getpassword();
    return (request, body, execution) -> {
        httpheaders headers = request.getheaders();
        headers.setbasicauth(username, password, standardcharsets.utf_8);
        return execution.execute(request, body);
    };
}

上传代码:

@override
public filestoragebo upload(string filepath) throws baseappexception {
    logger.debug("dmsfilestorage upload by file path start.");
    if (stringutils.isempty(filestorageproperties.getdms().getresturl())) {
        logger.error("dms rest url config not exist!");
        exceptionhandler.publish("epa-common-0010", exceptionhandler.buss_error);
    }
    file tempfile = new file(filepath);
    filestoragebo result = new filestoragebo(tempfile);
    multivaluemap<string, object> postparameters = new linkedmultivaluemap<>();
    filesystemresource resource = new filesystemresource(tempfile.getabsolutepath());
    postparameters.add("file", resource);
    postparameters.add("shardingkey", "epa_" + getshardingkey());
    httpheaders headers = new httpheaders();
    mediatype type = mediatype.parsemediatype(mediatype.multipart_form_data_value);
    headers.setcontenttype(type);
    httpentity<multivaluemap<string, object>> httpentity = new httpentity<>(postparameters, headers);
    try {
        string dmsid = dmsresttemplate.postforobject(filestorageproperties.getdms().getresturl() + "/file",
            httpentity, string.class);
        result.setfileidentity(dmsid);
        logger.debug("dmsfilestorage upload by file path end. dms id is {}", dmsid);
    }
    catch (restclientexception e) {
        logger.error(e);
        exceptionhandler.publish("epa-common-0011", exceptionhandler.buss_error, e.getlocalizedmessage());
    }

    return result;
}

以上就是resttemplate上传文件500异常的原因及解决方法的详细内容,更多关于resttemplate上传文件500的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com