Reputation: 302
I'm using Spring Boot in an app that uses REST servers and REST clients. My problem occurs when I let people choose the URL mapping, because then I need to dynamically create a REST Controller with this URL mapping:
@SpringBootApplication
public static void main(String[] args){
SpringApplication.run(MyClass.class);
String urlMapping = "/url/url";
CreateNewRestController c = new CreateNewRestController(urlMapping);
}
@RestController
public class CreateNewRestController{
String url;
public CreateNewRestController(String url){
this.url = url
}
@RequestMapping(value = this.url,method = RequestMethod.GET)
public String getHello(){
return "Hello";
}
}
"Why are you using a url variable when you could use a constant string in the RequestMapping?" you may ask. But this is a simple example and I need to create the RequestMapping using a variable argument.
Upvotes: 1
Views: 4553
Reputation: 3548
I solved this for my use case by using a Map to store 'sub' paths and passing all the requests to a generalized controller.
My use case needed a generic proxy app for multiple back-ends. Not too much different than what as you described a possible solution.
Source code - https://github.com/savantly-net/mesh-gateway
Example -
@RestController
@RequestMapping(MeshGateway.PATH)
public class MeshGateway {
protected static final String PATH = "/gateway";
private static final Logger log = LoggerFactory.getLogger(MeshGateway.class);
private MeshGatewayConfig config;
public MeshGateway(MeshGatewayConfig config) {
this.config = config;
}
@GetMapping("/{child}/**")
public ResponseEntity<?> get(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).get();
}
@PostMapping("/{child}/**")
public ResponseEntity<?> post(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).post();
}
@PutMapping("/{child}/**")
public ResponseEntity<?> put(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).put();
}
@RequestMapping(path = "/{child}/**", method = RequestMethod.OPTIONS)
public ResponseEntity<?> options(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).options();
}
@RequestMapping(path = "/{child}/**", method = RequestMethod.PATCH)
public ResponseEntity<?> patch(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).patch();
}
@RequestMapping(path = "/{child}/**", method = RequestMethod.DELETE)
public ResponseEntity<?> delete(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).delete();
}
@RequestMapping(path = "/{child}/**", method = RequestMethod.HEAD)
public ResponseEntity<?> head(@PathVariable String child, ProxyExchange<byte[]> proxy) throws Exception {
log.debug("doing GET: {}", proxy.path());
return proxy.uri(getDestinationPath(child, proxy)).head();
}
private String getDestinationPath(String child, ProxyExchange<byte[]> proxy) {
String destination = this.config.getRoutes().get(child);
String path = proxy.path(String.format("%s/%s", PATH, child));
log.debug("with prefix removed: {}", path);
return String.format("%s%s", destination, path);
}
}
Upvotes: 0
Reputation: 302
I found a awnser to my question and maybe a solution to used RequestMapping in real time. I created a RestController that take all the HTTP petitions to it, them the petition ask to a hash map with have the uri mapping like key and a class controller like value.
The generic controller:
@RestController
public class GeneralController {
HashMap<String,PersonalizedController> petitions = new HashMap<String,PersonalizedController>();
@RequestMapping("**")
public ResponseEntity<Object> index(HttpServletRequest request,HttpServletResponse response,@RequestBody Object body) {
// Inicialization zone - this zone don't must exist
petitions.put("/dir/esta1", new PersonalizedController("esta1"));
petitions.put("/dir/esta2", new PersonalizedController("esta2"));
//-------------------------------------------------
return handlePetition(request,response);
}
private ResponseEntity<Object> handlePetition(HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
String petition = request.getRequestURI();
String method = request.getMethod();
return petitions.get(petition).makePetition(method,new String());
}
}
The controller class:
public class PersonalizedController {
private String name;
public PersonalizedController(String name) {
this.name = name;
}
public ResponseEntity<Object> makePetition(String method,Object body) {
// TODO Auto-generated method stub
switch (method) {
case "GET":
return doGet(body);
case "POST":
return doPost(body);
case "PUT":
return doPut(body);
case "DELETE":
return doDelete(body);
default:
return new ResponseEntity<Object>("",HttpStatus.METHOD_NOT_ALLOWED);
}
}
public ResponseEntity<Object> doGet(Object body) {
return new ResponseEntity<Object>("["+name+"] GET",HttpStatus.OK);
}
public ResponseEntity<Object> doPost(Object body) {
return new ResponseEntity<Object>("["+name+"] POST",HttpStatus.OK);
}
public ResponseEntity<Object> doDelete(Object body) {
return new ResponseEntity<Object>("["+name+"] DELETE",HttpStatus.OK);
}
public ResponseEntity<Object> doPut(Object body) {
return new ResponseEntity<Object>("["+name+"] PUT",HttpStatus.OK);
}
}
Upvotes: 1