0

The below is what I have;

 @PostMapping("/profile") public String showUserAppointment(@RequestParam(value = "userCpr", required = false) Long cpr, Model model) { cpr = Long.parseLong(currentPrincipal()); model.addAttribute("iTestCenterService", iTestCenterService); model.addAttribute("userCpr", iAppointmentService.findAppointmentByCpr(cpr)); return "profile/profile"; } @PostMapping("profile") public String showUserDetails(@RequestParam(value = "userCprDetails", required = false) long cpr, Model model) { cpr = Long.parseLong(currentPrincipal()); model.addAttribute("iAddressService", iAddressService); model.addAttribute("userCprDetails", iUserService.findUserByCpr(cpr)); return "profile/profile"; } 

Is this at all possible to do, while pointing both of that at the profile page?

How can I do this if it isn't possible?

8
  • 1
    1. What do you think, based on what handler method should be chosen when request arrives?; 2. Why do you need to have two distinct methods mapped at the same URI? Commented Aug 16, 2021 at 20:00
  • @GiorgiTsiklauri I'm not sure what you mean by the first question. And in regards to the 2nd one, it's because I have 2 separate tables that I need to display in the profile page that are completely different formats, so I'm assuming I can't do that in one method. Commented Aug 16, 2021 at 20:06
  • 1
    If you have different data to show, then you should have different endpoints to fetch those data. Separation of concerns. Commented Aug 16, 2021 at 20:09
  • 1
    It doesn't appear that either of these should be POST endpoints; they both look like GETs. It's also unclear what you intend your own logic to be, since you inject cpr from request parameters and then immediately overwrite them with some opaque value. Commented Aug 16, 2021 at 20:12
  • @chrylis-cautiouslyoptimistic- I overwrite them because they used to be a search function, so it would be user defined what the cpr was, but it was causing issues with users being able to see other users' details and since I don't know how to fix that with authorizations, I figured I'd simply try and pass the current Principal as the cpr and have it automatically display only the users' details, rather than giving them the ability to search. Commented Aug 16, 2021 at 20:15

1 Answer 1

1

Ignoring the drama about the design in the question comments, the answer is that you should have a single method annotated with @PostMapping and then delegate to an appropriate handler function based on the facts.

In the original, you have two versions: /profile?userCpr=123 and /profile?userCprDetails=456. Both userCpr and userCprDetails are optional, so it's up to you to decide how to handle the situation where neither is provided or both are. But for the other use cases, simply declare both optional request params in the endpoint definition:

@PostMapping("/profile") public String showUser( @RequestParam(value = "userCpr", required = false) Long userCpr, @RequestParam(value = "userCprDetails", required = false) Long userCprDetails, Model model) { // if both are defined, or neither is defined, you need to decide how to handle that (or // if you should error) if (userCpr == null && userCprDetails == null) || (userCpr != null && userCprDetails != null) { // TODO: handle this situation } else if (userCpr != null) { return showUserAppointment(model); } else { return showUserDetails(model); } } public String showUserAppointment(Model model) { Long cpr = Long.parseLong(currentPrincipal()); model.addAttribute("iTestCenterService", iTestCenterService); model.addAttribute("userCpr", iAppointmentService.findAppointmentByCpr(cpr)); return "profile/profile"; } public String showUserDetails(Model model) { Long cpr = Long.parseLong(currentPrincipal()); model.addAttribute("iAddressService", iAddressService); model.addAttribute("userCprDetails", iUserService.findUserByCpr(cpr)); return "profile/profile"; } 

We don't even bother passing the userCpr/userCprDetails values to the handler methods since we're going to ignore the value and use the result of currentPrincipal() instead.

Of course since the vast majority of both "handlers" is identical, you could just simplify to a single endpoint method and omit the "handler" methods entirely:

@PostMapping("/profile") public String showUser( @RequestParam(value = "userCpr", required = false) Long userCpr, @RequestParam(value = "userCprDetails", required = false) Long userCprDetails, Model model) { // if both are defined, or neither is defined, you need to decide how to handle that (or // if you should error) if (userCpr == null && userCprDetails == null) || (userCpr != null && userCprDetails != null) { // TODO: handle this situation } Long cpr = Long.parseLong(currentPrincipal()); model.addAttribute("iTestCenterService", iTestCenterService); if (userCpr != null) { model.addAttribute("userCpr", iAppointmentService.findAppointmentByCpr(cpr)); } else { model.addAttribute("userCprDetails", iUserService.findUserByCpr(cpr)); } return "profile/profile; } 

... but if you're actually doing more stuff in those handler methods than it might make sense to keep that out of the endpoint itself and in distinct handler functions.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.