我正在尝试使用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);
但结果仍然相同。
我做错了什么?谢谢!
答案 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文件夹。然后重新部署应用程序。