HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean - 无法访问HTTP调用程序远程服务

时间:2012-10-08 10:31:54

标签: spring remote-access http-proxy httpinvoker

我正在尝试使用HttpInvokerServiceExporter + HttpInvokerProxyFactoryBean,但无论我做什么,我都会遇到异常:

org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [http://localhost:9999/testcaseapp/testcaseservice]; nested exception is java.io.IOException: Did not receive successful HTTP response: status code = 404, status message = [Not Found]

为简单起见,我创建了一个测试用例。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class RemoteTest {

    private static final Logger logger = LoggerFactory.getLogger("TestsLogger");

    static interface TestCaseService {
        public Integer add(Integer arg1, Integer arg2);
    }
    static class TestCaseServiceImpl implements TestCaseService {
        public Integer add(Integer arg1, Integer arg2) {
            return (arg1 != null ? arg1.intValue() : 0) + (arg2 != null ? arg2.intValue() : 0);
        }
    }

    @Configuration
    static class Config {
        @Bean
        public HttpInvokerServiceExporter httpInvokerServiceExporter() {
            HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
            httpInvokerServiceExporter.setService(new TestCaseServiceImpl());
            httpInvokerServiceExporter.setServiceInterface(TestCaseService.class);
            return httpInvokerServiceExporter;
        }
        @Bean
        public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
            HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean = new HttpInvokerProxyFactoryBean();
            httpInvokerProxyFactoryBean.setServiceInterface(TestCaseService.class);
            httpInvokerProxyFactoryBean.setServiceUrl("http://localhost:9999/testcaseapp/testcaseservice");
            httpInvokerProxyFactoryBean.afterPropertiesSet();
            return httpInvokerProxyFactoryBean;
        }
    }

    @Autowired
    private TestCaseService[] testCaseServices;
    private static Server server;

    @BeforeClass
    public static void setUp() {
        try {
            server = new Server();
            SelectChannelConnector connector = new SelectChannelConnector();
            connector.setPort(9999);
            server.addConnector(connector);
            //
            WebAppContext webAppContext = new WebAppContext();
            webAppContext.setContextPath("/testcaseapp");
            webAppContext.setWar("src/test/java/" + RemotingTest.class.getPackage().getName().replace('.', '/'));
            server.setHandler(webAppContext);
            //
            server.start();
        } catch (Exception ex) {
            logger.info("Could not permorm the set up: {}", ex.toString());
        }
    }

    @AfterClass
    public static void destroy() {
        try {
            server.stop();
        } catch (Exception e) {
        }
    }

    @Test
    public void addTest() {
        for (TestCaseService testCaseService : testCaseServices) {
            Integer sum = testCaseService.add(10, 5);
            Assert.assertNotNull(sum);
            Assert.assertEquals(15, sum.intValue());
        }
    }

}

我也试过创建一个TestCaseService bean

@Bean public TestCaseService testCaseService() ...

并将其作为httpInvokerServiceExporter参数提供

@Bean public HttpInvokerServiceExporter httpInvokerServiceExporter(TestCaseService testCaseService)
...
httpInvokerServiceExporter.setService(testCaseService);

但结果仍然相同。

我做错了什么?谢谢!

2 个答案:

答案 0 :(得分:2)

我认为问题在于Servlet不可访问。

服务器端

确保您的WEB-INF / web.xml(在公开方法-SERVER-的应用程序中)有以下代码:

<web-app>
...
<servlet>
    <servlet-name>remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>remoting</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>
...
</web-app>

这里,远程方法在“服务”下提供,也就是说,为了调用方法,URL应该是:

http://localhost:8080/sample/services/list

你必须通过创建一个bean(在我的情况下在WEB-INF / remoting-servlet.xml下)将这个Servlet定义为可访问的:

<bean name="/list" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
    <property name="service" ref="myObjectQueryService" />
    <property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>

客户端

如果您在客户端下使用Spring(而不是在您的示例中),则必须定义用于访问远程资源的bean,定义一些bean(每个公共资源一个):

在这种情况下,它将是:

<bean id="listService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
    <property name="serviceUrl" value="http://localhost:8080/sample/services/list" />
    <property name="serviceInterface" value="com.kategor.myapp.sample.service.ObjectQueryService" />
</bean>

在你的例子中是对的。

这样,调用服务“listService”,你就可以使用com.kategor.myapp.sample.service.ObjectQueryService类中的所有方法

@Controller
public class HomeController {

    // This is the remote service definition
    @Autowired
    private ObjectQueryService<MyObject, Long> objectQueryService;

    /* .... */

    /**
     * List all Objects retrieved through Web Service from a remote Server
     */
    @RequestMapping(value = "listRemoteWS", method = RequestMethod.GET)
    public String listRemoteWS(Locale locale, Model model) {

        StringBuilder result = new StringBuilder();
        try {

            // The Remote Service is called
            List objs = objectQueryService.findAll(0, 10);
            result.append(objs.size() + " objs found");

        for (MyObject o : objs) {
            result.append("<br>* ").append(o.getId()).append(" = ").append(o.getName());
        }


        } catch (Exception e) {

            result.append("No objs have been found");
            e.printStackTrace();

        }

        model.addAttribute("result", result);

        return "index";
    }

}

所以我认为问题来自URL:可能服务不可见或者这不是正确的路径。

有关详细信息,请查看此链接(第一个非常有用):

https://github.com/JamesEarlDouglas/barebones-spring-mvc/tree/master/reference/spring-remoting

http://www.ibm.com/developerworks/web/library/wa-spring3webserv/index.html

答案 1 :(得分:0)

对我来说问题是tomcat选择了两个版本的相同应用程序。这在调试模式下从STS运行客户端时引发了上述错误。 所以解决方案是清理tomcat中用于应用程序的所有扩展webapp文件夹。然后重新部署应用程序。