Home > Software design >  Second hidden input is not read
Second hidden input is not read

Time:12-16

I have two hidden input fields to implement Friend system. I pass user and friend's ids in Model and then use them in thymeleaf page to pass them in form to PostMapping and save changes. However, PostMapping cannot see my second @RequestParam.

Both customer and friend are properly passed to model as I tried to output them on website using th:text

Snippets of code:
Adding both users to model:

@GetMapping("/customer/{customerId}")
    public String getCustomer(Model theModel, @PathVariable int customerId, @AuthenticationPrincipal MyUserDetails user) {
        Customer currUser = customerService.findById(user.getCustomer().getId());
        Customer foundCustomer = customerService.findById(customerId);
        theModel.addAttribute("friend", foundCustomer);
        theModel.addAttribute("customer", currUser);
        return "customerdetails";


Snippet of Thymeleaf code:

<form action="#" th:action="@{/home/addFriend}" th:object="${friend}" method="post">
                    <input type="hidden" th:field="${friend.id}" th:attr="name='friendId'" />
                    <input type="hidden" th:field="${customer.id}" th:attr="name='customerId'" />
                  <input type="submit" value="Add Friend"  />
</form>


PostMapping (where issue occurs):

@PostMapping("/addFriend")
    public String getPost(@RequestParam("friendId") int friendId, @RequestParam("customerId") int customerId) {
        Customer friendCustomer = customerService.findById(friendId);
        Customer currCustomer = customerService.findById(customerId);
        
        System.out.println(currCustomer.getFirstName());
        System.out.println(friendCustomer.getFirstName());
        
        return "redirect:/home";
    }


Code of error:

[org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'friendId' for method parameter type int is not present]

CodePudding user response:

It will be a lot easier to implement using a custom form object.

For example, create this class:

public class AssignFriendFormData {
  private String friendId;
  private String customerId;

  // getter and setters here
}

Use this in your @GetMappping:

@GetMapping("/customer/{customerId}")
    public String getCustomer(Model theModel, @PathVariable int customerId, @AuthenticationPrincipal MyUserDetails user) {
        Customer currUser = customerService.findById(user.getCustomer().getId());
        Customer foundCustomer = customerService.findById(customerId);

        AssignFriendFormData formData = new AssignFriendFormData();
        formData.setFriendId(foundCustomer.getId());
        formData.setCustomerId(currUser.getId());
        theModel.addAttribute("formData", formData);
        
        return "customerdetails";

Change the form to this:

<form action="#" th:action="@{/home/addFriend}" th:object="${formData}" method="post">
    <input type="hidden" th:field="*{friendId}" />
    <input type="hidden" th:field="*{customerId}" />
    <input type="submit" value="Add Friend"  />
</form>

Finally, update the @PostMapping to use the form data object:

@PostMapping("/addFriend")
    public String getPost(@Valid @ModelAttribute("formData") AssignFriendFormData formData) {
        Customer friendCustomer = customerService.findById(formData.getFriendId());
        Customer currCustomer = customerService.findById(formData.getCustomerId());
        
        System.out.println(currCustomer.getFirstName());
        System.out.println(friendCustomer.getFirstName());
        
        return "redirect:/home";
    }

See Form handling with Thymeleaf for a more in-depth tutorial on this.

  • Related