参考:Spring 实现远程访问详解——httpinvoker
Spring httpInvoker使用标准java序列化机制,通过Http暴露业务服务。如果你的参数和返回值是比较复杂的,通过httpInvoker有巨大的优势。
远程访问流程如下
package com.lm.core.service;
import java.util.List;
import com.lm.core.entity.User;
public interface UserHttpService {
List<User> getUserByAcount(String name,String password);
void insert(User user);
}
package com.lm.core.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.lm.core.entity.User;
import com.lm.core.mapper.UserMapper;
import com.lm.core.service.UserHttpService;
import com.lm.core.service.UserRmiService;
public class UserHttpServiceImpl implements UserHttpService {
@Autowired
private UserMapper userMapper;
@Override
public List<User>getUserByAcount(String name, String password) {
System.err.println("httpInvoker获取用户信息:"+ name + password);
return new ArrayList<User>();
}
@Override
public void insert(User user) {
System.err.println("httpInvoker开始插入用户信息:"+ user.toString());
}
}
<!-- 也可以在java类里用注解定义这个bean -->
<bean name="userHttpService"class="com.lm.core.service.impl.UserHttpServiceImpl"/>
<!-- 这个name实际上是作为外部访问此服务对象的路径的一部分 -->
<bean name="userExporter" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="userHttpService"/>
<property name="serviceInterface" value="com.lm.core.service.UserHttpService"/>
</bean>
拿区块星空 tradeplatform.admin 来说,它把这些定义都放在 application-remote.xml 文件里:
<bean name="/sysUserRemoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="sysUserRemoteService" />
<property name="serviceInterface" value="com.tradeplatform.admin.api.user.remote.UserRemoteService" />
</bean>
而这个文件由在 web.xml 文件里定义的一个 servlet 负责加载,servlet 定义的拦截模式是 /remote/*,只有匹配这个路径的,才会进入到这个配置文件里找服务对象。假如这个项目部署到服务器的访问路径是 http://localhost:8100/admin ,那客户端要访问到这个服务对象,路径应该配置为 http://localhost:8100/admin/remote/sysUserRemoteService 。
package com.lm.core.service;
import java.util.List;
import com.lm.core.entity.User;
public interface UserHttpService {
List<User> getUserByAcount(Stringname,String password);
void insert(User user);
}
因为区块星空里客户端pom文件引用了服务端项目,所以可以在本项目直接引用服务端代码,不需要再手动定义接口。
<bean id="httpInvokerProxy" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<!-- 访问服务端接口的完整路径 -->
<property name="serviceUrl" value="http://127.0.0.1:8080/spring_remote_server/remoting/userExporter"/>
<property name="serviceInterface" value="com.lm.core.service.UserHttpService"/>
</bean>
@RequestMapping(value = "/httpInvokerTest")
@ResponseBody
public BaseMapVo httpInvokerTest(String name, String password) {
BaseMapVo vo = new BaseMapVo();
long startDate = Calendar.getInstance().getTimeInMillis();
System.out.println("httpInvoker客户端开始调用" + startDate);
// 客户端的HTTP调用代理对象可以强制转换为服务接口对象,其余的就和调用本地服务对象方法没什么区别了
UserHttpService rmi = (UserHttpService) ApplicationContextUtil.getInstance().getBean("httpInvokerProxy");
rmi.getUserByAcount("张三", ":张三的密码");
System.out.println("httpInvoker客户端调用结束" + (Calendar.getInstance().getTimeInMillis()-startDate));
vo.setRslt("sucess");
return vo;
}