WebX实践指南_WebX RPC
来源:互联网 发布:网络密钥是wifi密码吗 编辑:程序博客网 时间:2024/06/05 02:20
WebX RPC顾名思义,是基于webx框架之上支持异步请求的一种扩展,是轻量级的RPC框架。
参考:http://docs.alibaba-inc.com/display/opentech/Web-RPC
WebX RPC说明
1.1、意义
1. 对webx框架的扩展,使webx能够更好的支持ajax请求2. 统一各个站点对webx ajax的使用规范
1.2、不解决的问题
1. 不提供类似DWR框架的client端js输出2. 不是一个REST的实现(**?**)
1.3、应用范围 & 特性
- 应用范围:
1. 需要使用ajax技术的webx项目
2. 已经用过ajax在webx当中的项目 - 特性:
1. 支持annotation的数据绑定和验证
2. 统一的错误处理流程
3. 支持json、xml、jsonp的输出格式
4. 可扩展MimeResult自定义输出格式
5. 可扩展RPCResultGenerator来完成对生成结果的自定义包装
6. 提供全局的拦截器和方法级别的拦截器
7. 框架内置的XSS和CSRF安全过滤器 [前端如何实现]
1.4、快速开始
- 添加Maven库依赖pom.xml 片段:
<dependency> <groupId>com.alibaba.platform.shared</groupId> <artifactId>webx3.extension.rpc</artifactId> <version>0.2.6</version></dependency><!--fasttext配置 begin --><dependency> <groupId>com.alibaba.platform.shared</groupId> <artifactId>fasttext.all</artifactId> <version>1.3</version></dependency>
- 配置Web-RPC的基础服务
- pipeline.xml中增加对RPC的拦截支持,pipeline.xml片段
<when> <pl-conditions:target-extension-condition extension="json,jsonp,xml,xhtml" /> <valve class="com.alibaba.citrus.extension.rpc.integration.RPCServiceHandlerValve" /></when>
- 在webx-component.xml中配置以下服务,Spring配置文件片段
<!-- =================================================== --><!-- WebX3 RPC 服务配置 (开始)--><!-- =================================================== --><!-- RPC 数据绑定服务 --><beans:bean id='rpcDatabindService' class='com.alibaba.citrus.extension.rpc.databind.RPCDatabindServiceImpl'> <beans:property name="registry"> <beans:bean id='databinderRegistry' class='com.alibaba.nonda.databind.impl.DatabinderRegistryImpl'> <beans:property name="binderFactories"> <beans:list> <beans:bean class="com.alibaba.citrus.extension.rpc.databind.RPCDatabinderFactory"/> </beans:list> </beans:property> </beans:bean> </beans:property></beans:bean><!-- RPC 数据验证服务 --><beans:bean id='rpcValidateService' class="com.alibaba.nonda.integration.webx3.validation.ValidateService4WebX3" /><!-- RPC URL与组件的映射服务 --><beans:bean id='rpcUrlComponentMapping' class="com.alibaba.citrus.extension.rpc.impl.URLComponentMappingImpl"> <!-- 标识RPC服务的命名空间(通过不同的namespace来模板化不同的业务) --> <beans:property name="namespace" value="${component}" /> <!-- 是否启用URL的驮峰转换,缺省为true --> <beans:property name="useCamelCaseURL" value="false" /></beans:bean><!-- RPC 处理请求的核心服务 --><beans:bean id='rpcServiceHandler' class="com.alibaba.citrus.extension.rpc.impl.RPCServiceHandlerImpl"> <!-- 示例:覆盖缺省的 resultGenerator --> <beans:property name="resultGenerator"> <beans:bean class="com.alibaba.sample.showcase.web.rpc.common.generator.MyCustomResultGenerator" /> </beans:property> <!-- 示例:添加全局自定义的Interceptor --> <beans:property name="interceptors"> <beans:list> <beans:bean class="com.alibaba.sample.showcase.web.interceptors.SecurityInterceptor" /> </beans:list> </beans:property> <!-- 示例:配置全局的属性过滤器 --> <beans:property name="propertyFilters"> <beans:list> <!-- Trim2Null过滤器 --> <beans:bean class="com.alibaba.citrus.extension.rpc.response.impl.Trim2NullPropertyFilter" /> </beans:list> </beans:property> <!-- xssType配置选择项有两种: 1.delete会直接删除xss标签 2.escape会将xss标签做转义输出 系统默认delete--> <beans:property name="xssType" value="escape" /></beans:bean>
• 在webx-应用模块.xml中增加对RPC类型组件的扫瞄支持
webx-应用模块.xml中的module-loader片段
<!-- 装载模块。 --><services:module-loader> <ml-factories:class-modules> <ml-factories:search-packages type="$1" packages="xxx.yyy.module.*" /> </ml-factories:class-modules> <ml-adapters:adapter class="com.alibaba.citrus.extension.rpc.integration.RPCModuleAdapterFactory" /></services:module-loader>
1.5、编写一个HelloRPCService类:
在module目录下添加新的package:rpc,编写对应的服务类。映射的实现可以参看上面配置文件的 rpcUrlComponentMapping部分.
例如对于:HelloRPCService.java 类
@WebResource("hello") public class HelloRPCService { // some fields // getter & setter @ResourceMapping("/loadUser") public String loadUser() { return user; }
访问的URL为:
http://localhost:8081/hello/loadUser.json (输出json格式)
http://localhost:8081/hello/loadUser.xml (输出xml格式)
参数传递:
public Object groupQuery(@RequestParam(name=”id”) Integer id, HttpSession session) {}
RPC返回的参数类型,一般采用JSON的方式传回,如何返回复杂的JSON数据结构,例如:
{“data”:[{},{},{}],“totalCount”:50,“pageSize”:10,“currentPage”:1}
针对这样的数据结构,产生结果时,采用Map
1.6、高级应用
1.6.1、定义自己的result generator
result generator代码示例:
public class ErrorMessageResultGenerator implements RPCResultGenerator {private static final Logger logger = LoggerFactory.getLogger( ErrorMessageResultGenerator.class );/*** code* 500: RPC服务异常* 404: 没有匹配的RPC服务* rpc_system_exception: RPC框架异常* rpc_invalid_arg: 数据绑定异常* null: 数据验证异常*/private static final Map
1.6.2、RPC Wraper对所有的RPC请求进行统一的包装,RPC Wraper
web-app.xml //针对应用的xml配置
示例程序的RPC Wraper:
package com.tmall.mastermind.web.rpcwraper;import java.lang.reflect.Field;import java.util.HashMap;import java.util.Map;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import phoenix.exception.DSLServiceException;import com.alibaba.common.lang.StringUtil;import com.tmall.mastermind.app.auth.service.api.AccessControlSwitcherService;import com.tmall.mastermind.exception.MastermindException;import com.tmall.mastermind.exception.MastermindExceptionType;import com.tmall.mastermind.web.helper.BUCUserInfoHelper;@Slf4jpublic class RpcResultWraper {@ResourceAccessControlSwitcherService accessControlSwitcherService;public Object doWrap(ProceedingJoinPoint pjp) throws MastermindException { Map<String, Object> result = new HashMap<String, Object>(); try { rpcSwitcher(pjp); return pjp.proceed(); } catch (MastermindException me) { result.put("result", "false"); result.put("errorMsg", me.getErrorMsg()); return result; } catch (DSLServiceException e) { result.put("result", "false"); result.put("errorMsg", "系统繁忙~" + MastermindExceptionType.TIME_OUT.getMsg()); log.error("erro on :" + pjp.getClass(), e); result.put("debugMsg", e.getMessage()); return result; } catch (Throwable e) { result.put("result", "false"); result.put("errorMsg", "系统开小差了~" + MastermindExceptionType.EXECUTION_FAILED); log.error("erro on :" + pjp.getClass(), e); result.put("debugMsg", e.getMessage()); return result; }}/** * rpc访问控制开关 * * @param pjp * @throws MastermindException */private void rpcSwitcher(ProceedingJoinPoint pjp) throws MastermindException { if (!accessControlSwitcherService.isSwitcherEnabled()) return; String url = getRequestUrl(pjp.getTarget()); if (StringUtil.isEmpty(url)) { return; } log.info("rpcSwitcher: get request url:" + url); String empId = BUCUserInfoHelper.getEmpId(getRequest(pjp.getTarget())); if (StringUtil.isEmpty(empId)) { log.error("rpcSwitcher error!! get empty empId from request"); throw new MastermindException(MastermindExceptionType.EXECUTION_FAILED, "无法获取用户信息"); } accessControlSwitcherService.checkWhiteList(url, empId);}private String getRequestUrl(Object target) { HttpServletRequest request = getRequest(target); if (null == request) { return ""; } return new String(((HttpServletRequest) request).getRequestURL());}private HttpServletRequest getRequest(Object t) { Field field = null; try { field = t.getClass().getDeclaredField("request"); } catch (Exception e) { log.error("rpcSwitcher error!! RPC-Object does not have request object", e); return null; } if (null == field) { return null; } HttpServletRequest request = null; boolean save = field.isAccessible(); field.setAccessible(true); try { request = (HttpServletRequest) field.get(t); } catch (Exception e) { log.error("rpcSwitcher error!! could not get request from field", e); } field.setAccessible(save); return request;}}
1.6.3、RPC timeout
1.7、WebX RPC原理
Pipeline任务的分发处理,RPC Service Handler, 处理的关键点,结果集合的重新生成,包括JSON、XML格式的结果集合。同时可以自己定义结果的生成集合。
RPC和Web服务区分 WebX的不同于Rest服务是一种RPC实现这种区分在于分布系统中的两种实现,一种是Web Service,一种是RPC实现。Web服务遵循SOAP协议。
RPC客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
Web Service本身其实是在实现应用程序间的通信。我们有两种应用程序通信的方法:RPC远程过程调用和消息传递。使用RPC的时候,客户端的概念是调用服务器上的远程过程,通常方式为实例化一个远程对象并调用其方法和属性。RPC系统试图达到一种位置上的透明性:服务器暴露出远程对象的接口,而客户端就好像在本地使用的这些对象的接口一样,这样就隐藏了底层的信息,客户端也就根本不需要知道对象是在哪台机器上。
Web Service是构造分布式、模块化应用程序和面向服务应用集成的最新技术和发展趋势。Web服务是基于Web容器的,使用Servlet来实现。
RPC OVER HTTP Microsoft RPC-over-HTTP 部署(RPC over HTTP)允许RPC客户端安全和有效地通过Internet 连接到RPC 服务器程序并执行远程过程调用。这是在一个名称为RPC-over-HTTP 代理,或简称为RPC 代理的中间件的帮助下完成的。
RPC代理运行在IIS计算机上。它接受来自Internet 的RPC 请求,在这些请求上执行认证,检验和访问检查,如果请求通过所有的测试,RPC 代理将请求转发给执行真正处理的RPC 服务器。通过RPC over HTTP,RPC客户端不和服务器直接通信,它们使用RPC 代理作为中间件。
WebX的实现也是类似的,是一种RPC over HTTP的实现。
转自:http://blog.csdn.net/fiboliu/article/details/50340011
- WebX实践指南_WebX RPC
- WebX实践指南_WebX RPC(四)
- WebX实践指南_请求处理(一)
- WebX实践指南_页面模板(二)
- WebX实践指南_持久化(三)
- Webx框架指南
- WebX入门指南
- Webx RPC 内部重定向的bug
- Webx框架指南(转载)
- webX
- Webx
- webx
- JSON-RPC-Java 指南
- xml-rpc的实践
- RPC实践(二)JsonRPC实践
- RPC实践(三)Hessian实践
- RPC实践(四)Dubbo实践
- webx- webx framework
- 标准标签库JSTL
- Cookie和Session详解
- 28.UITableView类详解
- bpf
- 十个开源库分享(二)
- WebX实践指南_WebX RPC
- View的位置--top, left, bottom, right
- Python基础--流程控制
- 深入理解JVM(2)—Java虚拟机内存区域
- ofstream的使用方法--C++文件写入、读出函数(转)
- 对Scanner的认识和用法
- bpf
- Fiddler抓取手机数据包(315晚会上出现了它的影子。。。)
- 动态图文讲解8大排序算法