最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot文件上傳同時接收復(fù)雜參數(shù)的過程詳解

 更新時間:2022年12月19日 16:02:37   作者:lzhfdxhxm  
這篇文章主要介紹了SpringBoot文件上傳同時,接收復(fù)雜參數(shù),本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

環(huán)境信息

        Spring Boot:2.0.8.RELEASE

        Spring Boot內(nèi)置的tomcat:tomcat-embed-core 8.5.37

問題描述

        收到文件上傳的開發(fā)工作,要求能適配各種場景,并且各場景的請求參數(shù)不一樣,因此接收的參數(shù)不能是固定的幾個字段,要有類似Map的字段來接收動態(tài)參數(shù)。

        擬使用MultipartFile[] files來接收文件列表,用自定義對象UploadFileDto來接收上傳參數(shù)(里面包含一個Map)

        UploadFileDto.java

@ApiModel("文件上傳dto")
@Data
public class UploadFileDto {
    @ApiModelProperty("處理器,在Spring容器里的名稱")
    private String handlerName;
 
    @ApiModelProperty("交易代碼")
    private String bizCode;
 
    @ApiModelProperty("交易ID")
    private String bizId;
 
    @ApiModelProperty("上傳配置名稱,對應(yīng)配置文件里的配置")
    private String uploadConfigName;
 
    @ApiModelProperty("動態(tài)信息")
    private Map<String, Object> dynamicDto;
 
    @ApiModelProperty("上傳時間")
    private String uploadDt;
 
    @ApiModelProperty("限定文件大小")
    private long defaultFileSize;
 
    @ApiModelProperty("限定文件格式,多個用逗號隔開")
    private String defaultFileSuffix;
 
    @ApiModelProperty("默認路徑之后的文件上級目錄")
    private String parentDir;
 
    @ApiModelProperty("備注信息")
    private String remark;
 
    @ApiModelProperty("上傳后的文件信息")
    private List<FileInfoDto> fileInfoDtos;
 
}

Controller:

@RestController
@RequestMapping("/fileCommmon")
@Api(tags = "公共-文件操作")
public class FileUpDownLoadController extends BaseController {
 
    @Resource
    private UpDownLoadService upDownLoadService;
 
    @PostMapping(value = "/upload")
    @ApiOperation("文件上傳")
    public ResponseDto<UploadFileDto> uploadFile(@RequestParam("files") MultipartFile[] files, @RequestPart() UploadFileDto uploadFileDto) {
        upDownLoadService.uploadFile(uploadFileDto, files);
        return getResponseDto(uploadFileDto);
    }
}

Controller方法,使用@RequestParam("files") MultipartFile[] files來接收文件列表

使用@RequestPart() UploadFileDto uploadFileDto來接收復(fù)雜參數(shù)。

UpDownLoadService是上傳實現(xiàn)類,這里暫時不暫時源碼。

可是,在訪問該接口的時候,報錯了:org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:226)
    at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:134)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:981)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:884)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:858)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)

錯誤分析

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/octet-stream' not supported,意思是應(yīng)用不支持'application/octet-stream'這種文件類型

Swagger2里的請求參數(shù):

 分析異常堆棧,是在AbstractMessageConverterMethodArgumentResolver的readWithMessageConverters方法里拋出的:

         分析這個方法里的代碼,發(fā)現(xiàn)Spring在嘗試使用各個消息轉(zhuǎn)換器(HttpMessageConverter)來處理請求。這里的contentType值是'application/octet-stream',發(fā)現(xiàn)找不到可用的消息轉(zhuǎn)換器:

genericConverter.canRead(targetType, contextClass, contentType) ,因此無法解析、轉(zhuǎn)換消息,因此拋出了異常。

         確切的說,上面說的是處理請求參數(shù)uploadFileDto,第一個請求參數(shù)files已經(jīng)在下面這個地方處理了(文件類型參數(shù)使用MultipartResolutionDelegate.resolveMultipartArgument來處理):

注:

messageConverters的值(這個看各個應(yīng)用里注冊的消息轉(zhuǎn)換器類型、順序):

經(jīng)常使用的是MappingJackson2HttpMessageConverter消息轉(zhuǎn)換器,這個是SpringBoot默認用來處理消息的,將原始請求轉(zhuǎn)成json格式,再轉(zhuǎn)成目標類型的格式,是Jackson

targetClass是UploadFileDto對應(yīng)的Class

解決方法

        明白了問題產(chǎn)生的原因之后,就有了解決思路:增加一個消息轉(zhuǎn)換器,用于支持'application/octet-stream'。

最簡單的添加方式,新增一個類,繼承AbstractJackson2HttpMessageConverter,這個也是上面說的MappingJackson2HttpMessageConverter的父類

@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
 
    /**
     * Converter for support http request with header Content-Type: multipart/form-data
     */
    public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
        super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
    }
 
    @Override
    public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
        return false;
    }
 
    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return false;
    }
 
    @Override
    protected boolean canWrite(MediaType mediaType) {
        return false;
    }
}

 加了上面的轉(zhuǎn)換器之后:

 讀取之后的body類型就是UploadFileDto

 至此,問題解決,后端程序能夠正常接收、處理前端發(fā)過來的文件列表,以及復(fù)雜參數(shù)。

簡單參數(shù)

如果后端程序不需要接收復(fù)雜參數(shù),而是只需要固定的幾個簡單參數(shù),那么就很簡單,比如:

Controller:

    @PostMapping(value = "/upload2")
    @ApiOperation("文件上傳2")
    public ResponseDto<String> uploadFile(@RequestParam("files") MultipartFile[] files,  @RequestPart() String remark) {
        System.out.println("remark = " + remark);
        upDownLoadService.uploadFile(remark, files);
        return getResponseDto(remark);
    }

此時,contentType值是'application/octet-stream'的String的參數(shù),Spring有提供了默認的消息轉(zhuǎn)換器StringHttpMessageConverter,支持所有的格式,就不需要自定義MappingJackson2HttpMessageConverter消息轉(zhuǎn)換器了。

總結(jié)

回顧一下,如果需要復(fù)雜參數(shù)(自定義對象接收前端參數(shù)),那么需要自定義消息轉(zhuǎn)換器(如AbstractJackson2HttpMessageConverter),來支持contentType值是'application/octet-stream'類型的參數(shù),并將其轉(zhuǎn)換成目標格式;

如果不需要復(fù)雜參數(shù),只是String等類型,那么不需要自定義消息轉(zhuǎn)換器;

消息轉(zhuǎn)換器是SpringBoot處理前端傳輸?shù)臄?shù)據(jù),并轉(zhuǎn)換成接口參數(shù)的類型的轉(zhuǎn)換器,轉(zhuǎn)換前、轉(zhuǎn)換后還支持自定義插件處理。詳見AbstractMessageConverterMethodArgumentResolver的readWithMessageConverters

@RequestParam和@RequestPart的區(qū)別,可以自行查找資料

參考文獻:

 rest - @RequestPart with mixed multipart request, Spring MVC 3.2 - Stack Overflow

@RequestPart同時接收文件和json后端報錯 - 簡書 (jianshu.io)

到此這篇關(guān)于SpringBoot文件上傳同時,接收復(fù)雜參數(shù)的文章就介紹到這了,更多相關(guān)SpringBoot文件上傳接收參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)帶緩沖的輸入輸出流

    Java實現(xiàn)帶緩沖的輸入輸出流

    本文詳細講解了Java實現(xiàn)帶緩沖的輸入輸出流,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • springboot 跨域配置類及跨域請求配置

    springboot 跨域配置類及跨域請求配置

    這篇文章主要介紹了springboot 跨域配置類及跨域請求配置,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • Java線程操作的常見方法【線程名稱獲取、設(shè)置、線程啟動判斷等】

    Java線程操作的常見方法【線程名稱獲取、設(shè)置、線程啟動判斷等】

    這篇文章主要介紹了Java線程操作的常見方法,結(jié)合實例形式總結(jié)分析了java線程的創(chuàng)建、線程名稱的獲取、設(shè)置以及線程啟動的判斷等相關(guān)操作實現(xiàn)技巧,需要的朋友可以參考下
    2019-10-10
  • java 實現(xiàn)DES 加密解密的示例

    java 實現(xiàn)DES 加密解密的示例

    這篇文章主要介紹了java 實現(xiàn)DES 加密解密的示例代碼,幫助大家更好的理解和使用Java進行加解密,感興趣的朋友可以了解下
    2020-12-12
  • SpringBoot前后端json數(shù)據(jù)交互的全過程記錄

    SpringBoot前后端json數(shù)據(jù)交互的全過程記錄

    現(xiàn)在大多數(shù)互聯(lián)網(wǎng)項目都是采用前后端分離的方式開發(fā),下面這篇文章主要給大家介紹了關(guān)于SpringBoot前后端json數(shù)據(jù)交互的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • MyBatis主鍵生成策略中useGeneratedKeys和<selectKey>的區(qū)別

    MyBatis主鍵生成策略中useGeneratedKeys和<selectKey>的區(qū)別

    本文主要介紹了MyBatis主鍵生成策略中useGeneratedKeys和<selectKey>的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • Java SpringBoot高級用法詳解

    Java SpringBoot高級用法詳解

    這篇文章主要為大家詳細介紹了Java Spring Boot的一些高級用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-09-09
  • myeclipse智能提示設(shè)置的實現(xiàn)方法

    myeclipse智能提示設(shè)置的實現(xiàn)方法

    本篇文章介紹了,myeclipse智能提示設(shè)置的實現(xiàn)方法。需要的朋友參考下
    2013-05-05
  • Java?Stream流中的filter()使用方法舉例詳解

    Java?Stream流中的filter()使用方法舉例詳解

    filter()是Java?Stream?API中的中間操作,用于根據(jù)給定的Predicate條件篩選流中的元素,它通過接收一個返回boolean值的函數(shù)(斷言)作為參數(shù),篩選出滿足條件的元素并收集到新的流中,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-11-11
  • SpringBoot集成PostgreSQL并設(shè)置最大連接數(shù)

    SpringBoot集成PostgreSQL并設(shè)置最大連接數(shù)

    本文主要介紹了SpringBoot集成PostgreSQL并設(shè)置最大連接數(shù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-11-11

最新評論

荆州市| 汨罗市| 黑山县| 出国| 昌平区| 海兴县| 西青区| 密山市| 开阳县| 神农架林区| 郑州市| 弥渡县| 华宁县| 长葛市| 吴川市| 大悟县| 罗甸县| 安徽省| 阿克陶县| 东港市| 乃东县| 卢氏县| 勃利县| 皮山县| 万山特区| 富锦市| 陆川县| 郁南县| 商城县| 高青县| 克拉玛依市| 长海县| 黄大仙区| 南康市| 岑巩县| 清苑县| 正阳县| 榕江县| 贵德县| 景德镇市| 松江区|