Search code examples
restfilespring-bootmarshalling

How to marshal springframework.web.multipart.MultipartFile


I'm trying to Marshal Multipartfile but getting the below

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: java.io.FileInputStream["fd"]->java.io.FileDescriptor["parent"]->java.io.FileInputStream["fd"]->java.io.FileDescriptor["parent"]->java.io.FileInputStream["fd"]->java.io.FileDescriptor["parent"]->java.io.FileInputStream["fd"]->java.io.FileDescriptor["parent"]->java.io.FileInputStream["fd"]->java.io.FileDescriptor["parent"]->java.io.FileInputStream["fd"]->java.io

I tried to google ways to synchronize Multipartfile or convert Multipartfile into CommonsMultipartFile but always ran into issues, I'm using SpringBoot 2.1.2. Below is my code

Controller:

    @PostMapping(path = "/upload")
    public ResponseEntity<Void> save(@RequestPart("document") CommonsMultipartFile multipartfile, @RequestPart("userDTO") UserDTO userDTO) {
        fileService.save(multipartfile, userDTO);
        return new ResponseEntity<>(HttpStatus.CREATED);
    }

Service:

    public void jacksonDataFormat(UserDTO userDTO) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.registerModule(new JavaTimeModule());
            objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
            objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
            objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            objectMapper.writeValueAsString(userDTO);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
  public void save(MultipartFile multipartfile, UserDTO userDTO) {
        userDTO.setDocument(multipartfile);
        jacksonDataFormat(userDTO);
        publisher.publishEvent(new CreateEvent(saveDocumentDTO));
    }

Below is the code that is throwing JsonMappingException:

objectMapper.writeValueAsString(userDTO);

I appreciate for any help on this


Solution

  • After some research and few trail and errors, Below code fixed the issue I was getting.

    Service:

        public void jacksonDataFormat(UserDTO userDTO) {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.registerModule(new JavaTimeModule());
                objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
                objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
                objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
                objectMapper.writeValueAsString(userDTO);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
      public void save(MultipartFile multipartfile, UserDTO userDTO) {
            userDTO.setDocumentContent(multipartfile.getBytes());
            jacksonDataFormat(userDTO);
            publisher.publishEvent(new CreateEvent(saveDocumentDTO));
        }
    

    I have used byte array instead of multipartfile in the UserDTO and that solved the problem for me.