如何使用Spring WebFlux返回404

时间:2017-08-18 08:31:28

标签: spring spring-boot project-reactor spring-webflux

我有一个像这样的控制器(在Kotlin中):

@ResponseStatus(code = NOT_FOUND)

我想知道是否有更好的方法而不是抛出用var all = $(".card-color").map(function() { oneToFive = Math.floor((Math.random() * 5) + 1); switch (oneToFive) { case 1: randColor = 'red'; break; case 2: randColor = "rgba(0, 0, 255, 0.25)"; break; case 3: randColor = "rgba(0, 0, 0, 0.25)"; break; case 4: randColor = "rgba(255, 0, 0, 0.25)"; break; case 5: randColor = "rgba(0, 255, 0, 0.25)"; break; default: randColor = "rgba(122, 122, 122, 0.25)"; break; } $(this).css('background-color', randColor); }).get() 注释的异常

3 个答案:

答案 0 :(得分:6)

当Spring 5稳定时,我想使用RouteFunction而不是@RestController。定义HandlerFunction来处理请求,然后声明RouteFunction将请求映射到HandlerFunction:

public Mono<ServerResponse> get(ServerRequest req) {
    return this.posts
        .findById(req.pathVariable("id"))
        .flatMap((post) -> ServerResponse.ok().body(Mono.just(post), Post.class))
        .switchIfEmpty(ServerResponse.notFound().build());
}

检查完整的示例代码here

Kotlin版本,定义一个处理请求的函数,使用RouteFunctionDSL将传入的请求映射到HandlerFuncation:

fun get(req: ServerRequest): Mono<ServerResponse> {
    return this.posts.findById(req.pathVariable("id"))
            .flatMap { post -> ok().body(Mono.just(post), Post::class.java) }
            .switchIfEmpty(notFound().build())
}

它可以是一个表达式,如:

fun get(req: ServerRequest): Mono<ServerResponse> = this.posts.findById(req.pathVariable("id"))
            .flatMap { post -> ok().body(Mono.just(post), Post::class.java) }
            .switchIfEmpty(notFound().build())

检查Kotlin DSL here的完整示例代码。

如果您更喜欢传统控制器来公开REST API,请尝试这种方法。

首先定义一个例外,例如。 PostNotFoundException。然后把它扔进控制器。

@GetMapping(value = "/{id}") public Mono<Post> get(@PathVariable(value = "id") Long id) { return this.posts.findById(id).switchIfEmpty(Mono.error(new PostNotFoundException(id))); }

定义ExceptionHandler来处理异常,并在HttpHandler中注册。

@Profile("default")
@Bean
public NettyContext nettyContext(ApplicationContext context) {
    HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context)
        .exceptionHandler(exceptionHandler())
        .build();
    ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
    HttpServer httpServer = HttpServer.create("localhost", this.port);
    return httpServer.newHandler(adapter).block();
}

@Bean
public WebExceptionHandler exceptionHandler() {
    return (ServerWebExchange exchange, Throwable ex) -> {
        if (ex instanceof PostNotFoundException) {
            exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
            return exchange.getResponse().setComplete();
        }
        return Mono.error(ex);
    };
}

在此处查看complete codes。对于Spring Boot用户,请检查this sample

答案 1 :(得分:4)

可以将方法的实现改为

,而不是抛出异常
fun findById(@PathVariable id: String,
             @RequestHeader(value = IF_NONE_MATCH) versionHeader: String?): Mono<ResponseEntity<KundeResource>> =
    return service.findById(id)
        .map {
            // ETag stuff ...
            ok().eTag("...").body(...)
        }
        .defaultIfEmpty(notFound().build())

答案 2 :(得分:2)

您可以使用ResponseStatusException,只需扩展例外即可:

public class YourLogicException extends ResponseStatusException {

public YourLogicException(String message) {
    super(HttpStatus.BAD_REQUEST, message);
}

public YourLogicException(String message, Throwable cause) {
    super(HttpStatus.BAD_REQUEST, message, cause);
}

并在使用中:

public Mono<String> doLogic(Mono<YourContext> ctx) {
    return ctx.map(ctx -> doSomething(ctx));
}

private String doSomething(YourContext ctx) {
    try {
        // some logic
    } catch (Exception e) {
        throw new YourLogicException("Exception message", e);
    }
}

然后,您可能会收到一条漂亮的消息:

 { "timestamp": 00000000, "path": "/endpoint", "status": 400, "error": "Bad Request", "message": "Exception message" }