Skip to content

New controller for Spring MVC using Lambda [SPR-12954] #17546

Closed
@spring-projects-issues

Description

@spring-projects-issues

Toshiaki Maki opened SPR-12954 and commented

After Java SE 8 has been released, some frameworks using lambda appear.
For example Spark, Siden.

These frameworks are inspired by Sinatra and will resolve "Annotation Hell" which revealed after "XML Hell" had been cleared.

Spring MVC has a good mechanism to abstract controller layer (HandlerMapping, HandlerAdopter).
To implement these, Spring MVC can have a power to make use of lambda.

I've created a prototype for Spring MVC to provide a router like Sinatra.
https://github.com/making/new-controller

RouterHandlerMapping is a key component.

So far, this prototype does not use the url matching algorithm which @MVC uses. But you can see how this controller could be used.

Sample code is following:

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    // omitted

    // Define request mapping using lambda
    @Bean
    RouterDefinition<Handler> routerDef() {
        return router -> router
                /* curl localhost:8080 ==> Sample*/
                .get("/", (req, res) -> res.body("Sample"))
                /* curl localhost:8080/hello ==> Hello World! */
                .get("/hello", (req, res) -> res.body("Hello World!"))
                /* curl localhost:8080/json ==> {"name":"John","age":30} */
                .get("/json", (req, res) -> res
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(new Person("John", 30)))
                /* curl localhost:8080/xml ==> <?xml version="1.0" encoding="UTF-8" standalone="yes"?><person><age>30</age><name>John</name></person> */
                .get("/xml", (req, res) -> res
                        .contentType(MediaType.APPLICATION_XML)
                        .body(new Person("John", 30)))
                /* curl localhost:8080/template ==> [templates/hello.html will be rendered via Thymeleaf] */
                .get("/template", (req, res) -> {
                    req.put("message", "Hello World!");
                    return res.view("hello");
                })
                /* curl localhost:8080/bar/aaa ==> foo = aaa */
                .get("/bar/{foo}", (req, res) ->
                        res.body("foo = " + req.param("foo")
                                .orElse("??")))
                /* curl localhost:8080/param -d name=John ==> Hi John */
                .post("/echo", (req, res) ->
                        res.body(req.param("name")
                                .map(name -> "Hi " + name)
                                .orElse("Please input name!")))
                /* curl localhost:8080/param -d name=John -d age=30 ==> {"name":"John","age":30} */
                .post("/param", (req, res) -> {
                    Person person = req.params(Person.class);
                    return res.body(person);
                })
                /* curl localhost:8080/body -H 'Content-Type: application/json' -d '{"name":"John","age":30}' ==> {"name":"John","age":30} */
                .post("/body", (req, res) -> {
                    Person person = req.body(Person.class);
                    return res.body(person);
                });
    }
}

How do you think about this idea?


Issue Links:

2 votes, 9 watchers

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions