如何在 Spring 引导控制器和 return 适当的对象中接受 GET 参数

How to accept GET argument in Spring boot Controller and return appropriate object

我是 spring 引导的新手,我无法理解 @Controller class。如果我在 spring 启动时在我的数据库中找不到特定对象,我应该传递什么?如果我将我的 return 类型声明为 Response Entity 并发送一个 null User 对象会更好吗?

//Get single user
@GetMapping("/users/{id}")
public User getUser(@PathVariable String id){
    try {
        Long i = Long.parseLong(id);
    } catch (NumberFormatException ex) {
        return ????    //Can't figure out what to return here. 
    }
    return userService.getUser(id);
}

我想让消费者知道他们发送了一个无效的字符串。

2) 还有,User的变量id是Long类型的。那么我应该在 getUser 函数中将参数作为 Long 还是采用 String 并解析它?如果在 link.

中发送字符串,则采用 Long 会使我的服务器崩溃

这是我的 'get user by id' 请求的 REST 控制器的典型代码:

@RestController
@RequestMapping("/users") // 1
public class UserController {

    private final UserRepo userRepo;

    public UserController(UserRepo userRepo) {
        this.userRepo = userRepo;
    }

    @GetMapping("/{id}") // 2
    public ResponseEntity getById(@PathVariable("id") Long id) { // 3
        return userRepo.findById(id) // 4
                .map(UserResource::new) // 5
                .map(ResponseEntity::ok) // 6
                .orElse(ResponseEntity.notFound().build()); // 7
    }
}

其中:

1 - 是此控制器处理的所有请求的通用起始路径

2 - GET 请求的路径变量模式 (/users/{id})。

3 - 提供与GetMapping中的参数相对应的路径变量名称。 getById方法中的参数类型对应UserID的类型。

4 - 我使用 UserRepofindById 方法 return Optional

5 - 我在这里将 User 转换为某种类型的 DTO - UserResource(这是可选步骤)

6 - return OK 如果找到 User 则响应

7 - 或 return Not Found 否则响应。

我还在几个项目中使用了控制器-服务-存储库模式,这就是我的布局方式:

Controller.java

@RestController // 1
@RequestMapping(value = "/users")  // 2
public class UserController {

    private final UserService userService;

    @Autowired // 3
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(value = "/{user_id}", method = RequestMethod.GET) //4
    @ResponseStatus(HttpStatus.OK) //5
    public UserModel getUser(@PathVariable(value="user_id") long user_id) { //6
        return userService.getUserById(user_id);
    }

    @RequestMapping(method = RequestMethod.POST) // 7
    @ResponseStatus(HttpStatus.CREATED) // 8
    public UserModel getUser(@ResponseBody UserModel userModel) { // 9
        return userService.createUser(usermodel);
    }

}

1) @RestController 是@Controller 和@ResponseBody 的组合,这实质上意味着 class 中的每个方法都会有一个响应主体。

2) 在这个 class 中使用 /users

前缀 @RequestMapping 值

3) 构造函数中的自动装配是注入 bean 的最安全方法。

4) 可以通过对 /users/{user_id}

的 GET 请求访问此方法

5) 此方法将 return HttpStatus.OK 成功时的状态码 (200)

6) 从请求中提取路径变量 "user_id"。使用与此处用户 ID 相同的数字类型(即 int 或 long)。

7) 可以通过对 /users

的 POST 请求访问此方法

8) 此方法将 return HttpStatus.CREATED 成功状态码 (201)

9) 从请求正文中提取一个UserModel(应该与后面给出的json具有相同的结构)。

Cepr0 和我的方法没有真正的区别,这纯粹是一种风格偏好。

UserModel 可以是这样的 class:

UserModel.java

public class UserModel {

    private String username;

    // Constructor, Getter, Setter...
}

这将 return 响应正文中的一个 JSON 对象,如下所示:

{
    "username":"username"
}

如果你想在你的控制器中处理异常(甚至控制由异常编辑的数据return,你可以像这样使用@ExceptionHandler:

@ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponseWrapper> handleGenericException(Exception ex){
        return ResponseEntity
                .status(HttpStatus.I_AM_A_TEAPOT)
                .body(new CustomExceptionWrapper(ex)));
}

CustomExceptionHandler 将您的应用程序抛出的异常转换为您决定的格式(这也可以是 POJO,Spring Boot 会为您将其转换为 JSON!)

更具体地回答您的问题: 1) 如果找不到用户,您应该抛出一个异常,该异常将包含响应状态 404(未找到)。返回 null 通常不是一个好主意,因为它可能意味着很多事情。

1.1?)如果你的用户发送了一个无效的字符串,你可以在你的服务器中查找它导致的异常,并使用异常处理程序来处理它并return一个适当的响应(BAD_REQUEST 也许吧?)

2) 是的,如果您的用户 ID 是长整数,则使用长整数。

Check out the baeldung site,真的会推荐他们学习 Spring Boot.