如何从弹簧控制器返回未找到的状态

Ser*_*gey 6 model-view-controller spring controller spring-mvc

我有以下spring控制器代码,如果在数据库中找不到用户,想要返回未找到状态,该怎么办?

@Controller
public class UserController {
  @RequestMapping(value = "/user?${id}", method = RequestMethod.GET)
  public @ResponseBody User getUser(@PathVariable Long id) {
    ....
  }
}
Run Code Online (Sandbox Code Playgroud)

wyp*_*prz 25

JDK8方法:

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(@PathVariable Long id) {
    return Optional
            .ofNullable( userRepository.findOne(id) )
            .map( user -> ResponseEntity.ok().body(user) )          //200 OK
            .orElseGet( () -> ResponseEntity.notFound().build() );  //404 Not found
}
Run Code Online (Sandbox Code Playgroud)

  • `ResponseEntity.notFound().build()` 会导致以下警告(SpringWeb 4.3.1):`Lambda 表达式中的返回类型错误:ResponseEntity&lt;Void&gt; 无法转换为 ResponseEntity&lt;User&gt;` (2认同)

Sot*_*lis 20

将处理程序方法更改为返回类型ResponseEntity.然后你可以适当地返回

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = ...;
    if (user != null) {
        return new ResponseEntity<User>(user, HttpStatus.OK);
    }
    return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Run Code Online (Sandbox Code Playgroud)

Spring将使用相同的HttpMessageConverter对象来转换User对象@ResponseBody,除非现在您可以更好地控制要在响应中返回的状态代码和标头.


Roh*_*aik 13

使用最新的更新,您可以使用

return ResponseEntity.of(Optional<user>);
Run Code Online (Sandbox Code Playgroud)

其余由以下代码处理

    /**
     * A shortcut for creating a {@code ResponseEntity} with the given body
     * and the {@linkplain HttpStatus#OK OK} status, or an empty body and a
     * {@linkplain HttpStatus#NOT_FOUND NOT FOUND} status in case of a
     * {@linkplain Optional#empty()} parameter.
     * @return the created {@code ResponseEntity}
     * @since 5.1
     */
    public static <T> ResponseEntity<T> of(Optional<T> body) {
        Assert.notNull(body, "Body must not be null");
        return body.map(ResponseEntity::ok).orElse(notFound().build());
    }
Run Code Online (Sandbox Code Playgroud)


cde*_*etz 9

公共静态 ResponseEntity of(Optional body)

创建具有给定主体和 OK 状态的 ResponseEntity 的快捷方式,或者在 Optional.empty() 参数的情况下创建空主体和 NOT FOUND 状态。

Javadoc 响应实体

@GetMapping(value = "/user/{id}")
public ResponseEntity<User> getUser(@PathVariable final Long id) {
    return ResponseEntity.of(userRepository.findOne(id)));
}

public Optional<User> findOne(final Long id) {
    MapSqlParameterSource paramSource = new MapSqlParameterSource().addValue("id", id);
    try {
        return Optional.of(namedParameterJdbcTemplate.queryForObject(SELECT_USER_BY_ID, paramSource, new UserMapper()));
    } catch (DataAccessException dae) {
        return Optional.empty();
    }
}
Run Code Online (Sandbox Code Playgroud)


Oli*_*ssé 6

使用方法引用运算符可能会更短 ::

@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public ResponseEntity<User> getUser(@PathVariable Long id) {
   return Optional.ofNullable(userRepository.findOne(id))
        .map(ResponseEntity::ok)
        .orElse(ResponseEntity.notFound().build());
}
Run Code Online (Sandbox Code Playgroud)