javaspringspring-bootspring-mvcmedia-type

How to define a controller method as to accept a JSON that have a media type filed with Spring Boot?


I'm trying to take a Json object from front-end. This represent a course. The course have a field logo, the image of the course. In my Controller I have the following method:

@PostMapping(value="/register-course", consumes = "multipart/form-data" )
    public Response courseCreated(@RequestBody @Valid CourseCreatedRequest courseCreatedRequest, @RequestPart(value = "logo") MultipartFile file) throws IOException {
        return Response.ok().setPayload(registerCours(courseCreatedRequest, file));
    }

        private CourseDto registerCours(CourseCreatedRequest courseCreatedRequest, MultipartFile file) throws
        IOException {
            CourseDto courseDto = new CourseDto()
                    .setCourseName(courseCreatedRequest.getCourseName())
                    .setCourseDescription(courseCreatedRequest.getCourseDescription())
                    .setCoursePrice(courseCreatedRequest.getCoursePrice())
                    .setIsCourseActive(courseCreatedRequest.getIsCourseActive())
                    .setIsCourseFree(courseCreatedRequest.getIsCourseFree())
                    .setLogo(file.getBytes());

            return courseService.createNewCourse(courseDto);
        }

In the Service layer I have the logic to compress(when persisiting the image in DB) and uncomress (when render the image back to fend):

@PrePersist
public CourseDto createNewCourse(CourseDto newCourseDto) {

    Courses course = courseRepositoryDao.findByCourseName(newCourseDto.getCourseName());
    if (course == null) {

        course = new Courses()
                .setCourseName(newCourseDto.getCourseName())
                .setCourseDescription(newCourseDto.getCourseDescription())
                .setCoursePrice(newCourseDto.getCoursePrice())
                .setIsCourseFree(newCourseDto.getIsCourseFree())
                .setIsCourseActive(newCourseDto.getIsCourseActive())
                .setLogo(compressZLib(newCourseDto.getLogo()))
        ;
        return CourseMapper.toUserDtoFreeCourses(courseRepositoryDao.save(course));
    }
    throw exception(EntityType.NEWCOURSE, ExceptionType.DUPLICATE_ENTITY, newCourseDto.getCourseName());
}

When I send the JSON with the logo field as an image file via POSTMAN, I get 415 Error - Unsuported media type.

Where I am wrong? I think that I need to change my controller, but how? I need somehow to take the image from the JSON with MultipartFile class?

Update: I sent JSON and a file in body, and I think this is the problem. I need to put MultipartFile in controller.

I have followe other answers and still 415 error. In postman I left Content-Type with no value.


Solution

  • For me how I did something similar was like so: In the back end (Spring):

    @PostMapping(path = "/{your-route-goes-here}", consumes = "multipart/form-data")
    public Course addCourse(@RequestPart(required = false, name = "file") MultipartFile file,  @RequestPart("course") Course course) {
    
        // do stuff here
    }
    

    In the front end javascript (with axios for the http request):

       const course = {
          "property": "value"
       }
    
      const formData = new FormData();
      formData.append("file", file);
      formData.append("course", course);
      
      axios
        .post("/your-route-goes-here", formData)
    
      // etc
    

    Please check out the pictures for reference:

    backend: enter image description here

    postman: enter image description here

    the 'Course' model:

    enter image description here