5

I need to get user information by ID and by Username. Can I have 2 requests like this?

 @GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
    return userRepository.getOne(id);
}

@GetMapping("/user/{username}")
public User getUser(@PathVariable String username) {
    return userRepository.findUserByUsername(username);
}


public interface UserRepository extends JpaRepository<User,Long>{

@Query("SELECT u FROM u WHERE username= :#{username}")
User findUserByUsername(@Param("username") String username);
}

Error: findUserByUsername(java.lang.String) but parameter 'Optional[username]' not found in annotated query 'SELECT u FROM u WHERE username= :#{username}'!

  • Not sure to understand what is missing. – Vyncent May 16 '18 at 14:25
  • i mean. how does it know if it's an id or a username. Can I do this? –  May 16 '18 at 14:27
  • instead of using 2 different end points use same endpoint and return based on the condition weather it is Id / username – Kiran Kumar May 16 '18 at 14:31
  • btw if any of the answers helped you, you could accept that answer https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Eugene May 17 '18 at 08:56

4 Answers4

5

If I remember correctly you can do that via a regex like:

@GetMapping("/user/{id:[\\d]+}")
@GetMapping("/user/{username:^[a-fA-F]{100}$}")
Arnaud
  • 17,229
  • 3
  • 31
  • 44
Eugene
  • 117,005
  • 15
  • 201
  • 306
  • Didn't know about that, it looks like you are right , cf. https://stackoverflow.com/questions/20527321/what-is-the-meaning-of-id-in-a-spring-mvc-requestmapping-handler-method – Arnaud May 16 '18 at 14:46
  • @Berger I *vaguely* remember this to be honest, had to do it quite a lot of time ago – Eugene May 16 '18 at 14:47
2

No, You can't do that as both requests can be mapped to both the methods. A Better way to do it would be to,

@GetMapping("/user")
public User getUser(@RequestParam("username") String username, @RequestParam("userId") Long userId) {
   // find by Criteria.
}

And Call it like,

http://<host>:<port>/<context>/user?userId=123&username=abc, the query params atre optional and so you can omit whatever isn't needed.

Antho Christen
  • 1,369
  • 1
  • 10
  • 21
0

HTTP is a text based protocol so the path parameter is always a string.

You should solve that with @RequestParam.

saferJo
  • 497
  • 1
  • 5
  • 16
0

You can do it with request parameter:

@GetMapping(value = "/user", params = "id")
public User getUser(@RequestParam("id") Long id) {
    return userRepository.getOne(id);
}

@GetMapping(value = "/user", params = "username")
public User getUser(@RequestParam("username") String username) {
    return userRepository.findUserByUsername(username);
}
Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51