jprism
jprism

Reputation: 3494

Spring Boot 2 handling form-data where json are values of keys

I have a situation where I have to implement post method to handle form-data where json are values of keys. Each JSON internally represent an object.

I can get the json as string via RequestParam and then convert to object using Jackson.

    @RequestMapping(value = "/rest/patient", consumes = {"multipart/form-data"},
                                                produces = "application/json", method= RequestMethod.POST)  
    public ResponseEntity<?> savePatient(@RequestParam("patient") String patient ) {
       // convert to Patient instance using Jackson

    }

Is there any out of box mapping from Spring boot?

Upvotes: 0

Views: 1448

Answers (1)

pcoates
pcoates

Reputation: 2307

I don't believe there is an out of the box mapping.

You could add a GenericConvertor to the WebConversionService that the WebDataBinder uses. You would need to list all your object types. Something like the following:

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class JsonFieldConverter implements GenericConverter {

    @Autowired
    private ObjectMapper objectMapper;

    // Add a new ConvertiblePair for each type you want to convert json 
    // in a field to using the objectMapper. This example has Patient and Doctor
    private static Set<ConvertiblePair> convertibleTypes = new HashSet<>();
    static {
        convertibleTypes.add(new ConvertiblePair(String.class, Patient.class));
        convertibleTypes.add(new ConvertiblePair(String.class, Doctor.class));
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return convertibleTypes;
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        try {
            return objectMapper.readValue(source.toString(), targetType.getType());
        } catch (Exception e) {
            // TODO deal with the error.
            return source;
        }

    }
}

And an @ControllerAdvice to plug it into the data binder:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
public class JsonFieldConfig {

    @Autowired
    private JsonFieldConverter jsonFieldConverter;

    @InitBinder
    private void bindMyCustomValidator(WebDataBinder binder) {
        ((WebConversionService)binder.getConversionService()).addConverter(jsonFieldConverter);
    }

}  

Upvotes: 1

Related Questions