Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use @RequestMapping functionality (URL to Java method mapping) without HTTP request/servlet

I am trying to build a simple PoC to replace an app that currently relies on JAR files loaded in a main Java (Spring MVC 4.2) web app to declare additional controllers on start. It looks pretty much like that:

Client <--HTTP--> Gateway+app (Spring MVC + order.jar)

Exposed endpoints:
/ping via controller in core Spring app
/orderApp/doSomething via controller in order.jar

Ideally, I'd like to have each JAR file to be standalone Spring Boot apps, exchanging data using Spring Integration 4.2 (via AMQP) with my HTTP gateway facing the outside world. A little schema:

Client <--HTTP--> Gateway (Spring MVC) <--AMQP--> Standalone orderApp (Spring Boot)

Exposed endpoints:
/ping via controller in core Spring MVC app
/{appName}/** via controller in core Spring MVC app

I have logic in the controller in the MVC app that finds which AMQP exchange should receive the messages based on the appName, I serialise the HTTP request using a gateway, send it to the proper app, can process it, send back the answer to the main Spring app that forwards the response to the client. No problem here.

However, I'd like if possible to reuse the convenient @RequestMapping annotation that I am currently using in my JAR files. These JAR basically contain additional controllers, exposing endpoints under a given root.

Question

How to manually trigger the @RequestMapping logic, given a URL, a request body and headers as input? For instance, let's say that I have an implementation like that:

@RequestMapping("projects/{projectId}")
public Project projectById(@PathVariable final String projectId) {

    (...)
    return project;
}

Is there any way that from a custom service code somewhere in my standalone app I could do a call such as handler.getResponse("projects/123abc", requestBody, requestHeaders), that would automatically find which method to call given the input parameters/URL?

I do not want all the features from @RequestMapping (no direct access to HttpServletRequest/HttpServletResponse for instance of course). What I want to do is a bit like a mock of HttpServletRequest, but without all the overhead of servlets and everything. And it should be "production" code, not something used in tests.

Otherwise, I have nothing against using something else than @RequestMapping, provided that I can achieve the same kind of mapping between URIs and Java methods, automatically getting parameters extracted from the URI. A custom Spring Integration router? I know that SI has some request-mapping support, but only over HTTP from what I've seen.

like image 222
Nicolas Avatar asked Oct 08 '15 09:10

Nicolas


People also ask

What is the @RequestMapping annotation used for?

RequestMapping annotation is used to map web requests onto specific handler classes and/or handler methods. @RequestMapping can be applied to the controller class as well as methods.

Which of these can be the return type of a method annotated with @RequestMapping in Spring?

A Callable can be returned when the application wants to produce the return value asynchronously in a thread managed by Spring MVC. A DeferredResult can be returned when the application wants to produce the return value from a thread of its own choosing.

Which annotation is used with @RequestMapping to bind a web request?

The @RequestParam annotation is used with @RequestMapping to bind a web request parameter to the parameter of the handler method.

Can we use @RequestMapping at method level?

The @RequestMapping annotation can be applied to class-level and/or method-level in a controller. The class-level annotation maps a specific request path or pattern onto a controller. You can then apply additional method-level annotations to make mappings more specific to handler methods.


1 Answers

It's not entirely clear what you are looking for; you already said you are routing to the back-end app by determining the exchange/routing key in the controller.

If you mean that each back-end service needs to handle multiple request types and needs further routing then, yes, a router is probably the best solution.

The question is how you are going to communicate that information (route) to the back end - presumably in a message property / header.

You are correct in that SI only uses request mapping internally in the HTTP endpoints, but there's nothing stopping you from writing an annotation-based router that uses the same annotations.

like image 115
Gary Russell Avatar answered Oct 21 '22 00:10

Gary Russell