【问题标题】:Invoke controller method from java class从java类调用控制器方法
【发布时间】:2013-12-20 21:59:25
【问题描述】:
I just want to know whether controller class method is accessible from another java class.    

以下是我的控制器及其方法。

@Controller
public class TestResultUploadController {
    @RequestMapping(method = RequestMethod.POST,value="/uploadTestResult")  
    public @ResponseBody  
     String uploadTestResult(String testResultBarcode,int deviceLoc) {

         //some code goes here
    return something;
}

我只想从另一个 java 类调用这个控制器方法。 我怎样才能让它工作? 请建议..

【问题讨论】:

  • 如果您必须这样做,我认为您遇到了设计问题。也许您应该将该方法移至较低级别,以便其他控制器可以访问。
  • 仅供参考。我可以通过创建控制器对象并直接调用该方法来调用此方法。但在这种情况下,@Autowired 字段不会被初始化。我知道设计是错误的,但流程必须是这种方式,因为我试图从在上下文初始化时初始化的线程调用此方法。
  • @SwapnilWalivkar 您可以在不进行错误设置的情况下实现此流程。你可以把这个方法放在一个服务中,让控制器和你的线程各自调用这个服务,而不是违反mvc原则。
  • 你只是想打电话是什么意思?你在考虑服务吗?我想是的。如果您可以进一步指出,我可以提供具体答案
  • manocha_ak 我有在后台运行的线程类。从线程类我试图调用控制器类方法(但@autowired 给我null)。我尝试通过 new 关键字创建对象,但最终在 DAO 层中,EntityManager 变为空。这就是为什么我试图从控制器本身发出请求。

标签: java spring-mvc


【解决方案1】:

简短回答:是的,有可能。在你的其他类/线程中,你可以做

// this will create a new instance of that controller where no fields are wired/injected
TestResultUploadController controller = new TestResultUploadController();
controller.uploadTestResult("someString", 1234); 

但是,请记住,您的设置非常不寻常,您的所有自动连线字段都不会正确连线。如果您从上下文中获取控制器,您将能够正确连接/注入您的字段:

// obtain controller bean from context, should have fields wired properly
TestResultUploadController controller = ctx.getBean(TestResultUploadController.class);
controller.uploadTestResult("someString", 1234); 

或者你可以在你的其他班级有:

@Autowired private TestResultUploadController controller;

....
public void doStuff(){
    controller.uploadTestResult("someString", 1234); 
}

同样,这是非常不寻常的,但很有可能。但是,仅仅因为某事可以做,并不意味着你就应该去做。我会推荐更常见的 Spring/MVC 方法,将业务逻辑外包给服务。基本上,有这样的东西:

@Controller
public class TestResultUploadController {

    @Autowired private UploadTestResultService uploadTestResultService;

    @RequestMapping(method = RequestMethod.POST,value="/uploadTestResult")  
    public @ResponseBody String uploadTestResult(String testResultBarcode,int deviceLoc) {
        return uploadTestResultService.uploadTestResult(testResultBarcode, deviceLoc);
    }
}

在你的帖子中:

//somehow get the service
UploadTestResultService uploadTestResultService = //somehowGetTheService (whether from context or in some other way)
uploadTestResultService.uploadTestResult(testResultBarcode, deviceLoc);

这样,您就可以在控制器的测试中模拟 UploadTestResultService,并且您还可以自己测试该服务的 uploadTestResult 方法,而无需将它放在控制器中。

编辑: 如何获取 Spring 上下文超出了这个问题的范围。我假设您了解基本的 Spring 和基本的 java。

【讨论】:

  • 我尝试了你所有的解决方案,但它不起作用。自动装配在服务层给​​了我空实例。
  • 能否请您提供关于 ctx.getBean 的说明
  • 您是否在进行正确的组件扫描?您是否将您的服务声明为 bean 或组件?你似乎是春天的新人。这完全取决于您的项目是如何设置的。尝试让自动装配工作,如果你做不到,只需在某处创建一个静态方法并调用它而不是服务:gist.github.com/anonymous/4d072f266ae1bb7bc457
  • 我正在尝试使用自动接线。我有一些疑问。
  • 解释你有什么疑问。对我来说,您似乎无法完全理解 Spring 的工作原理。您以某种方式设法在控制器中自动装配字段,为什么不能在服务中自动装配字段?我的建议是让您在开始认真编码之前先学习基本的 Spring 速成课程。
猜你喜欢
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多