Search code examples
javaajaxspringmodel-view-controllercontroller

How to maintain the model and bindingResult of the controller when moving the view of ajax


I tried the following. However, when moving a view by location.href, the model and bindingResult are not maintained. How to maintain the model and bindingResult? Maybe the approach is wrong...

Controller

    @PostMapping("/example")
    @ResponseBody
    public Map<String, Object> example(
            @RequestPart("formRequest") @Validated FormRequest formRequest,
            BindingResult bindingResult,
            @RequestPart(value = "file", required = false) MultipartFile file,
            @RequestPart(value = "files", required = false) MultipartFile[] files,
            Model model
    ) {
        Map<String, Object> response = new HashMap<>();
        
        if (bindingResult.hasErrors()) {
            log.warn("bindingResult={}", bindingResult);
            model.addAttribute("formRequest", formRequest);
            model.addAttribute("formStatus", FormStatus.CREATE);
            response.put("errors", bindingResult.getAllErrors());
            
            response.put("url", "/example");
            return response;
        }

        return response;
    }

formRequest

public record FormRequest(
        Long id,
        @NotBlank
        String content1,
        @NotBlank
        String content2,
        @NotBlank
        String content3,
        @NotNull
        Integer number1,
        @NotNull
        Integer number2,
        @NotNull
        List<GoodRequest> goodRequests,
        @NotNull
        List<DimRequest> dimRequests,
        String category
) {}

ajax

        $.ajax({
          url: url,
          type: "POST",
          data: formData,
          enctype: "multipart/form-data",
          contentType: false,
          processData: false,
          success: function (response) {
            location.href = response.url;
          }
        });

Solution

  • When you redirect the page using location.href, the current page is reloaded and any data stored in the model or BindingResult is lost. One way to maintain the data between requests is to store it in the session or pass it as URL parameters.

    In your case, you could modify your controller to store the formRequest and bindingResult objects in the session, and then retrieve them from the session when rendering the view. Modify you code as follow:

    @PostMapping("/example")
    @ResponseBody
    public Map<String, Object> example(
            @RequestPart("formRequest") @Validated FormRequest formRequest,
            BindingResult bindingResult,
            @RequestPart(value = "file", required = false) MultipartFile file,
            @RequestPart(value = "files", required = false) MultipartFile[] files,
            Model model,
            HttpSession session
    ) {
        Map<String, Object> response = new HashMap<>();
    
        if (bindingResult.hasErrors()) {
            log.warn("bindingResult={}", bindingResult);
            // Store formRequest and bindingResult in the session
            session.setAttribute("formRequest", formRequest);
            session.setAttribute("bindingResult", bindingResult);
            response.put("errors", bindingResult.getAllErrors());
    
            response.put("url", "/example");
            return response;
        }
    
        return response;
    }
    

    Then in your view, you can retrieve the formRequest and bindingResult objects from the session and use them.