programing

스프링 부트 다중 부품 파일은 항상 null입니다.

i4 2023. 6. 30. 22:06
반응형

스프링 부트 다중 부품 파일은 항상 null입니다.

Spring Boot 버전 = '1.4.0을 사용하고 있습니다.스프링 부트 스톰 경로가 1.0.2인 'RC1'입니다.

멀티파트 파일 업로드를 사용하려고 하는데 컨트롤러에서 멀티파트 파일이 항상 null입니다.

@RequestPart("file")를 사용하면 다음과 같은 정보가 표시됩니다."status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present"

@RequestPart(이름 = "file", 필수 = false)를 사용할 때 해당 부품은 항상 null입니다.

그러나 HttpServletRequest 인수를 컨트롤러에 추가하면 요청에서 직접 파일 부분을 가져올 수 있으므로 실제로 존재하는 것으로 알고 있습니다.

이것은 컨트롤러이며 아래 코드에 있습니다.checkNotNull(part)항상 성공하고,checkNotNull(imageFile)항상 실패:

@PostMapping("{username}/profilePhoto")
public ResponseEntity<?> saveProfilePhoto(@PathVariable("username") String username,
                                          @RequestPart(name = "file", required = false) MultipartFile imageFile,
                                          HttpServletRequest request) {
    try {
        Part part = request.getPart("file");
        checkNotNull(part);
        checkNotNull(imageFile);
    } catch (IOException | ServletException ex) {
        throw InternalServerErrorException.create();
    }

    // Transfer the multipart file to a temp file
    File tmpFile;
    try {
        tmpFile = File.createTempFile(TMP_FILE_PREFIX, null);
        imageFile.transferTo(tmpFile);
    } catch (IOException ex) {
        log.error("Failed to create temp file", ex);
        throw InternalServerErrorException.create();
    }

    // Execute the use case
    updateUserProfilePhoto.execute(username, tmpFile);

    // Delete the temp file
    FileUtils.deleteQuietly(tmpFile);

    return ResponseEntity.status(HttpStatus.CREATED).build();
}

통합 테스트에서는 다음과 같이 개조를 사용합니다.

@Multipart
@POST("users/{username}/profilePhoto")
Call<Void> uploadProfilePhoto(@Path("username") String username,
                              @Part("file") RequestBody profilePhoto);

...

@Test
public void saveProfilePhoto_shouldSavePhoto() throws IOException {
    // Given
    String usernamme = usernames[0];
    Resource testImageResource = context.getResource("classpath:images/test_image.jpg");
    File imageFile = testImageResource.getFile();
    RequestBody body = RequestBody.create(okhttp3.MediaType.parse("image/*"), imageFile);

    // When
    Response<Void> response = getTestApi().uploadProfilePhoto(usernamme, body).execute();

    // Then
    assertThat(response.code()).isEqualTo(201);
}

자동 구성을 사용하여 유일한 사용자 지정 구성 클래스가 Stormpath를 구성합니다.

@Configuration
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.apply(stormpath());
    }
}

업데이트: 나가는 요청입니다.다중 부분 확인 프로그램 자체에서 로깅을 활성화하는 방법을 잘 모르겠습니다.

2016-08-18 14:44:14.714 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : --> POST http://localhost:8080/users/user1/profilePhoto http/1.1
2016-08-18 14:44:14.714 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : Content-Type: multipart/form-data; boundary=fe23ef21-3413-404c-a260-791c6921b2c6
2016-08-18 14:44:14.715 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : Content-Length: 181212
2016-08-18 14:44:14.715 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : Accept: application/json
2016-08-18 14:44:14.715 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : Authorization: Bearer [token]
2016-08-18 14:44:14.715 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : 
2016-08-18 14:44:14.735 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : --fe23ef21-3413-404c-a260-791c6921b2c6
Content-Disposition: form-data; name="file"
Content-Transfer-Encoding: binary
Content-Type: image/*
Content-Length: 180999

file data

--fe23ef21-3413-404c-a260-791c6921b2c6--

2016-08-18 14:44:14.762 DEBUG 13088 --- [           main] c.t.server.web.testutil.TestConfig$1     : --> END POST (181212-byte body)

무슨 일이 일어나고 있는지에 대한 아이디어가 있습니까?

Spring은 Multipart 기능을 활성화하지 않으므로 Spring Multipart Resolver를 활성화해야 합니다.

기본적으로 Spring은 다중 부품 처리를 수행하지 않습니다. 일부 개발자는 다중 부품을 직접 처리하기를 원하기 때문입니다.웹 응용프로그램의 컨텍스트에 다중 부품 확인기를 추가하여 스프링 다중 부품 처리를 사용하도록 설정할 수 있습니다.

구성 클래스에 다음 빈을 추가할 수 있습니다.

@Bean
public MultipartResolver multipartResolver() {
    return new CommonsMultipartResolver();
}

업데이트 *** 제 이전 답변이 댓글을 기준으로 정확하지 않았기 때문입니다.다음은 성공적으로 실행할 수 있었던 업데이트된 예입니다.

@SpringBootApplication
public class StackoverflowWebmvcSandboxApplication {
    public static void main(String[] args) {
        SpringApplication.run(StackoverflowWebmvcSandboxApplication.class, args);
    }

    @Controller
    public class UploadPhoto {
        @PostMapping("{username}/profilePhoto")
        public ResponseEntity<String> saveProfilePhoto(@PathVariable("username") String username,
                @RequestPart(name = "file", required = false) MultipartFile imageFile, HttpServletRequest request) {
            String body = "MultipartFile";
            if (imageFile == null) {
                body = "Null MultipartFile";
            }

            return ResponseEntity.status(HttpStatus.CREATED).body(body);
        }
    }
}

이것은 특별한 것이 없는 매우 기본적인 시험입니다.그런 다음 우체부 요청을 작성했고 다음은 컬 콜 샘플입니다.

curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 17e5e6ac-3762-7d45-bc99-8cfcb6dc8cb5" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "file=@" "http://localhost:8080/test/profilePhoto"

그 대답은.MultipartFile이는 null이 아니라는 의미이며 해당 라인에서 디버그를 수행하면 변수가 업로드하는 이미지로 채워집니다.

application.properties에 다음 행이 있는지 확인합니다.

spring.http.multipart.enabled = true

Spring은 Multipart 기능을 활성화하지 않으므로 Spring Multipart Resolver를 활성화해야 합니다.

기본적으로 Spring은 다중 부품 처리를 수행하지 않습니다. 일부 개발자는 다중 부품을 직접 처리하기를 원하기 때문입니다.웹 응용프로그램의 컨텍스트에 다중 부품 확인기를 추가하여 스프링 다중 부품 처리를 사용하도록 설정할 수 있습니다.

구성 클래스에 다음 빈을 추가할 수 있습니다.

@Bean
public MultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

1 3.0+를 하므로 스프 1.4+는 3.0+를에서 할 수 .StandardServletMultipartResolver고전적인 고이아 CommonsMultipartResolver

저는 Retrofit으로 제 요청을 작성하는 방식이 문제라는 것을 알게 되었습니다.

Spring의 다중 부품 확인기를 사용하려면 파일의 파일 이름이 부품의 내용-처분 필드에 있어야 합니다.이렇게 하지 않으면 파일이 다중 파트 요청에 추가되지 않습니다.

여기에 있는 정보에 따르면: https://futurestud.io/blog/retrofit-2-how-to-upload-files-to-server, 의 API 인터페이스는 다음과 같습니다.

@Multipart
@POST("users/{username}/profilePhoto")
Call<Void> uploadProfilePhoto(@Path("username") String username,
                              @Part MultipartBody.Part profilePhoto);

그리고 내 테스트에서 전화를 걸 때:

// Given
String usernamme = usernames[0];
Resource testImageResource = context.getResource("classpath:images/test_image.jpg");
File imageFile = testImageResource.getFile();
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile);

// When
Response<Void> response = testApi.uploadProfilePhoto(usernamme, filePart).execute();

다음 URL에서 내 대답을 참조하십시오: Spring Boot 다중 파트 업로드가 null 파일 개체를 가져오는 중입니다.

기본적으로 멀티파트에 대한 기본 Spring 구성을 피하고 요청 헤더에 Content-type 또는 경계를 설정하지 않아야 합니다.

언급URL : https://stackoverflow.com/questions/39007726/spring-boot-multipartfile-always-null

반응형