Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在不访问internet的情况下调用Spring控制器方法_Java_Spring_Spring Restcontroller - Fatal编程技术网

Java 在不访问internet的情况下调用Spring控制器方法

Java 在不访问internet的情况下调用Spring控制器方法,java,spring,spring-restcontroller,Java,Spring,Spring Restcontroller,tldr:有没有一种方法可以在不上网的情况下发出内部请求(使用方法的路径) -- 为什么我需要它?我有一个项目,收到了许多事件。由一名控制员决定由谁来处理每一事件。所以我有类似的东西: @RestController @请求映射(“/events”) 公共类EventHandlerAPI{ @自动连线 私人事件处理程序事件处理程序; @自动连线 私人EventBHandler EventBHandler; @邮戳(“/a”) public void handleEventA(@RequestBo

tldr:有没有一种方法可以在不上网的情况下发出内部请求(使用方法的路径)

--

为什么我需要它?我有一个项目,收到了许多事件。由一名控制员决定由谁来处理每一事件。所以我有类似的东西:

@RestController
@请求映射(“/events”)
公共类EventHandlerAPI{
@自动连线
私人事件处理程序事件处理程序;
@自动连线
私人EventBHandler EventBHandler;
@邮戳(“/a”)
public void handleEventA(@RequestBody EventA event){
句柄(id,事件);
}
@邮戳(“/b”)
public void handleEventB(@RequestBody EventB event){
句柄(id,事件);
}
}
我们最近增加了通过队列服务接收事件的支持。它向我们发送有效负载和事件类。我们的决定是让这两个接口都工作(rest和queue)。避免代码重复的解决方案是让控制器选择处理事件的处理程序。现在的代码与此类似:

@配置
公共类EventHandlerQueueConsumer{
@自动连线
私有EventHandlerAPI EventHandlerAPI;
私有映射事件处理程序;
@施工后
public void init(){
/*启动侦听队列*/
报关员();
}
私人无效申报人{
eventHandlers=newhashmap();
put(EventAHandler.class,(EventHandler)eventHandlerAPI::handleEventA);
put(EventBHandler.class,(EventHandler)eventHandlerAPI::handleEventB);
}
私有void onEventReceived(AbstractEvent事件){
EventHandler=eventHandlers.get(event.getClass());
句柄(事件);
}
私有接口事件处理程序{
无效句柄(T事件);
}
}
这段代码可以工作,但它不允许控制器选择谁来处理事件(我们的意图)。这个决定实际上是由地图决定的

我想做的是通过它的请求映射调用控制器方法,而不必访问internet。大概是这样的:

@Configuration
public class EventHandlerQueueConsumer {

    // MADE UP CLASS TO SHOW WHAT I WANT
    @Autowired
    private ControllerInkover controllerInvoker;

    @PostConstruct 
    public void init() { /* start listen queue */ }

   private void onEventReceived(AbstractEvent event) {
       controllerInvoker.post(event.getPath(), new Object[] { event });
   }

}
这种方式更加简洁,所有的决策都由控制者做出

我做了很多研究,但没有找到实现它的方法。在调试spring时,我发现他是如何在
DispatcherServlet
之后路由请求的,但是所有spring内部都使用
HttpServletRequest
HttpServletResponse
:(

有没有一种方法可以在不访问internet的情况下发出内部请求(使用方法的路径)

它们是同一应用程序的类

那就足够容易了

1) 您可以使用
restemplate
实用程序类在
http(s)://localhost:{port}/API/{path}
上调用自己的API。这是首选方法,因为您将遵循标准MVC模式。比如:

restTemplate.exchange(uri, HttpMethod.POST, httpEntity, ResponseClass.class);
@RequestMapping("foo")
 public void fooMethod() {
    System.out.println("mapping = " + getMapping("fooMethod")); // you can get all methods/mapping in @PostContruct initialization phase
 }

 private String getMapping(String methodName) {
    Method methods[] = this.getClass().getMethods();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName() == methodName) {
            String mapping[] = methods[i].getAnnotation(RequestMapping.class).value();
            if (mapping.length > 0) {
                return mapping[mapping.length - 1];
            }
        }
    }
    return null;
}
2) 如果您根本不想调用网络连接,那么您可以使用Spring的internal来查找映射/方法映射,或者使用一些反射来构建自定义的连接 在控制器启动时映射。然后,您可以按照模型类中显示的方式将事件/对象从映射传递给方法。比如:

restTemplate.exchange(uri, HttpMethod.POST, httpEntity, ResponseClass.class);
@RequestMapping("foo")
 public void fooMethod() {
    System.out.println("mapping = " + getMapping("fooMethod")); // you can get all methods/mapping in @PostContruct initialization phase
 }

 private String getMapping(String methodName) {
    Method methods[] = this.getClass().getMethods();
    for (int i = 0; i < methods.length; i++) {
        if (methods[i].getName() == methodName) {
            String mapping[] = methods[i].getAnnotation(RequestMapping.class).value();
            if (mapping.length > 0) {
                return mapping[mapping.length - 1];
            }
        }
    }
    return null;
}
@RequestMapping(“foo”)
公共方法(){
System.out.println(“mapping=“+getMapping(“fooMethod”);//您可以在@PostContract初始化阶段获取所有方法/映射
}
私有字符串getMapping(字符串方法名){
方法方法[]=this.getClass().getMethods();
for(int i=0;i0){
返回映射[mapping.length-1];
}
}
}
返回null;
}

是同一应用程序的
EventHandlerQueueConsumer
EventHandlerAPI
类,还是这两个类位于不同的应用程序中(即不同的微服务)?@MikhailKholodkov他们是同一应用程序的类第二个是想要做的,但是我想知道是否有Spring特性可以做这样的事情,我只能想到点击Spring启动执行器的
/mapping
端点(第17条),然后解析响应。它包含您需要的所有信息。但这又是一个过度工程化的解决方案,我仍然建议使用普通的
restemplate
call。