在运行时创建@RestController

时间:2017-09-22 12:27:19

标签: java spring

我在使用REST服务器和REST客户端的应用程序中使用Spring Boot。当我让人们选择URL映射时,我的问题出现了,因为那时我需要用这个URL映射动态创建一个REST控制器:

@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";
   }
}

“当你在RequestMapping中使用常量字符串时,为什么要使用url变量?”你可能会问。但这是一个简单的例子,我需要使用变量参数创建RequestMapping。

2 个答案:

答案 0 :(得分:1)

Github link - here

我发现了一个问题,可能是一个实时使用RequestMapping的解决方案。我创建了一个RestController,它接受所有的HTTP请求,它们请求一个哈希映射,它具有像key这样的uri映射和类似值的类控制器。

通用控制器:

@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());
 }
}

控制器类:

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);
}

}

答案 1 :(得分:0)

通过使用Map存储“子”路径并将所有请求传递给通用控制器,解决了我的用例。
我的用例需要用于多个后端的通用代理应用程序。与您描述的可能解决方案没有太大不同。

源代码- https://github.com/savantly-net/mesh-gateway

示例-

@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);
    }
}