Получил почти 50% ошибок неверного запроса http 400 в Spring Boot 2.1 MultipartFile - загрузка файлов при включении SSL (https) - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть сервер API, который построен с использованием Spring Boot 2.1 на домене publi c, который также обслуживает API и загрузку файлов.

В последние дни мы хотим обновить этот сервер Spring Boot для использования SSL (HTTPS). Прежде чем мы настроим настройки SSL в Spring Boot. API для загрузки файлов работает очень хорошо (загрузка 100% успешна).

После настройки SSL в Spring Boot. API для загрузки файлов работает, но только 50% успешных загрузок, остальные 50% получили неверный запрос http 400. (Мы уверены, что проблема не связана с интерфейсной сетью, потому что мы используем Swagger, который поставляется вместе с Spring Boot для тестирования, может получить тот же результат)

И мы просматриваем журналы сервера Spring Boot. Когда произошел неверный запрос http 400, не было журналов о неверном запросе http 400. Мы изучаем много дней и исследуем inte rnet, но все еще не можем решить эту проблему. Пожалуйста, помогите.

Мы уже пытаемся отключить csrf (либо в файле свойств, либо через класс конфигурации) и многие другие решения, которые предусмотрены для inte rnet, но все еще не работают.

Среда: Spring Boot 2.1.13 (последняя версия Spring Boot 2.1)

Настройки в файле свойств: (только добавлен раздел настроек SSL в файле свойств, и SSL (https) успешно включен)

# SSL setup
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=abcdef
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat
server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
server.http2.enabled=true
security.basic.enabled=false
security.enable-csrf=false

## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled = true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=100MB
# Max Request Size
spring.servlet.multipart.max-request-size=115MB

Мой контроллер для загрузки файла:

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.SwaggerDefinition;
import io.swagger.annotations.Tag;
import java.util.Collections;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@RestController
@RequestMapping(value = "/v1/fileupload")
@Api(tags = {"fileupload api"}, value = "fileupload")
@SwaggerDefinition(tags = {
    @Tag(name = "fileupload api", description = "apis for file upload")
})
public class FileUploadController {

    @Autowired
    private FileUploadService fileUploadService;

    private ApiUtilHelper helper = new ApiUtilHelper();

    @ApiOperation(value = "upload single data import file")
    @RequestMapping(
        value = "/dataimport",
        method = RequestMethod.POST,,
        consumes = { MediaType.MULTIPART_FORM_DATA_VALUE },
        produces = { MediaType.APPLICATION_JSON_UTF8_VALUE }
    )
    public ResponseEntity<?> uploadSingleFileForDataImport(@RequestParam("file") MultipartFile file) throws FileStorageException {
        log.info("Enter into uploadSingleFileForDataImport");
        FileUploadResponse fileUploadResponse = fileUploadService.storeFile(file, "dataImport");
        Map<String, Object> additionals = Collections.singletonMap("filupload", fileUploadResponse);
        BasicResponse br = helper.createSuccessBaseResponse(ApiSuccessCode.CreateSuccess, additionals);
        return new ResponseEntity<BasicResponse>(br, ApiSuccessCode.CreateSuccess.getHttpStatus());
    }

Результат теста Swagger:

Request URL: https://example.com:8443/v1/fileupload/dataimport
Request Method: POST
Status Code: 400 
Remote Address: 111.222.111.222:8443
Referrer Policy: no-referrer-when-downgrade

**Response http header from Spring Boot**
Connection: close
Content-Length: 0
Date: Mon, 20 Apr 2020 13:13:02 GMT

**Request http header from Swagger**
accept: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-CN;q=0.6,ja;q=0.5
Connection: keep-alive
Content-Length: 484098
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryiXmuHnaNthhXowmb
Cookie: _ga=GA1.2.1299976434.1580821082; JSESSIONID=2C157019D6560405CC75A5F5083DE0AE
Host: example.com:8443
Origin: https://example.com:8443
Referer: https://example.com:8443/swagger-ui.html
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36

2020.04.20 13:44 (UT C время) дополнить информацию как ниже: Спасибо @nbalodi, когда я настраиваю logging.level.org.springframework.web = DEBUG. Я получил журнал ошибок сейчас. Журналы прикреплены, как показано ниже:

HttpEntityMethodProcessor : No match for [application/json;charset=UTF-8], supported: []
ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present]
DispatcherServlet : Completed 400 BAD_REQUEST

Странная часть заключается в том, что эта ошибка возникает только при использовании настроек ssl, как я описал выше.

Ответы [ 2 ]

0 голосов
/ 20 апреля 2020

Попробуйте это может помочь. Невозможно увидеть любую другую проблему с вашим кодом.

@RequestBody MultipartFile[] submissions

должно быть

@RequestParam("file") MultipartFile[] submissions

Файлы не являются телом запроса, они являются его частью, и нет встроенного HttpMessageConverter, который может преобразовать запрос в массив MultiPartFile.

Вы также можете использовать MultipartHttpServletRequest, который дает вам доступ к заголовкам отдельных частей.

0 голосов
/ 20 апреля 2020

Возможно ли изменить уровень журнала на DEBUG? т.е. logging.level.org.springframework.web = DEBUG.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...