Another way to write Spring MVC interface

1. Preface

In general, the paradigm for writing Spring MVC interface is as follows:

public class UserInfoController {
    public String foo() {
        return "";

Today, I'm going to use the new Functional Endpoints introduced by Spring 5 to play. Spring Webflux is also supported in this way.

Please note that the available Spring version of this feature is no less than Spring Five point two

2. Dependence

To demonstrate, it is very simple to introduce only the Spring MVC starter:


3. RouterFunction

In the functional endpoint writing, the traditional request mapping is replaced by the router function. The above is equivalent to:

    public RouterFunction<ServerResponse> fooFunction() {
        return RouterFunctions.route()
                .GET("/v1/userinfo/foo", request -> ServerResponse.ok()

In this example, I used RouterFunctions.route() creates a RouterFunction, which provides detailed operations from request to response.

4. ServerRequest/ServerResponse

ServerRequest is an abstraction of HTTP request on the server side, through which you can get the details of the request. Correspondingly, ServerResponse is an abstraction of the server-side response, through which you can build the details of the response. These two concepts are handled by the following HandlerFunction interface from request to response.

5. HandlerFunction

HandlerFunction is a functional interface that provides an abstraction of function mapping from a request to a response. Usually your business logic is implemented by this interface. Get the details of the request from ServerRequest, and then build a ServerResponse response based on the business.

HandlerFunction<ServerResponse> handlerFunction = request -> ServerResponse.ok().body("");

6. RequestPredicate

Requestpredict allows you to make assertions based on the details of the request, such as request method, request header, request parameter, etc. to decide whether to route or not.

For example, if we want to request the interface / v1/userinfo/predicate, we can process different services according to different parameters, and only when we carry the parameter plan can we process it. We can write as follows:

    public RouterFunction<ServerResponse> predicateFunction() {
        return RouterFunctions.route()
                        request -> request.param("plan").isPresent(),
                        request -> ServerResponse.ok().body(""))

Then let's test:

When carrying the parameter plan:

GET http://localhost:8080/v1/userinfo/predicate?plan=

HTTP/1.1 200 
Content-Type: text/plain;charset=UTF-8
Content-Length: 9
Date: Thu, 14 May 2020 07:57:35 GMT
Keep-Alive: timeout=60
Connection: keep-alive

When plan is not carried:

GET http://localhost:8080/v1/userinfo/predicate

HTTP/1.1 404 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 14 May 2020 08:00:15 GMT
Keep-Alive: timeout=60
Connection: keep-alive

  "timestamp": "2020-05-14T08:00:15.659+0000",
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/v1/userinfo/predicate"

7. Summary

Functional endpoint is a new interface paradigm style provided by Spring 5. For Spring MVC, spring five point two That's the support. It is also a future trend of conforming to functional programming. Because of the space, only the key concepts are explained here. In the next article, we will further explain and use this interface paradigm. Please pay attention to: small fat brother of minong.

Pay attention to the official account: Felordcn for more information

Personal blog:

Keywords: Java Spring WebFlux less JSON

Added by mynameisbob on Fri, 15 May 2020 07:48:02 +0300