一、总结
- 在Webx的Velocity中获取url中参数:$rundata.getRequest().getParameter(‘userId‘)
- 在Webx项目中,防止CSRF攻击(Cross-site request forgery,跨站请求伪造),在form表单提交中要加入$!csrfToken.ajaxUniqueToken
二、Bug描述:Velocity从URL中获取parameter参数
在项目IDCM中,使用webx容器进行项目的开发。前端的模板引擎采用了velocity,在项目中,当从列表页跳到详情页的时候,通常我们的screen层是采用如下方式进行展现的:
public class EditRules extends BaseScreen { @Autowired private AutoAssignSupplierBo autoAssignSupplierBo; @Autowired private SupplierBo supplierBo; @Autowired private AddressBo addressBo; @Autowired private SiteBo siteBo; public void execute(@Param("id") String id, Context context) throws Exception { QueryAssignRulesrDo query = new QueryAssignRulesrDo(); if (StringUtils.isBlank(id)) { throw new ServiceException("id is empty "); } query.setRuleId(Long.parseLong(id)); BoResultDTO<List<AssignRulesVo>> result = autoAssignSupplierBo.selectByQuery(query); List<AssignRulesVo> list = result.getData(); if (CollectionUtils.isNotEmpty(list)) { // 当前规则的详情 if (StringUtils.isNotBlank(list.get(0).getType())) { list.get(0).setTypeVal(list.get(0).getType()); list.get(0).setType(WorkOrderCst.RelocationType.getNameByStrValue(list.get(0).getType())); } // 如果有数量信息需要展示 if (list.get(0).getRuleContent().contains("数量")) { String[] numDes = list.get(0).getRuleContent().split(" "); for (String str : numDes) { if (str.contains("数量")) { String[] sz = str.split(":"); if (2 == sz.length) { list.get(0).setAssetNum(sz[1]); } } } } context.put("ruleInfos", JSON.toJSONString(list.get(0))); // 补全控件信息 Map<String, Object> map = fullInfo(list.get(0).getRuleJsonVal()); if (list.get(0).getRuleContent().contains("数量")) { map.put("assetNum", list.get(0).getAssetNum()); } context.put("ruleDes", JSONUtils.toJSONString(map)); } // 初始化类型信息 Map<String, Object> RelocationTypeList = WorkOrderCst.RelocationType.getRelocationTypeList(); context.put("RelocationTypeList", RelocationTypeList); // 物流供应商信息 context.put("logisticsSps", supplierBo.queryAllByType(WorkOrderCst.SpType.logistics.name())); // 传入设备类型 this.setorderDeviceType(context); } }
上图代码是自动分配物流供应商从列表页跳转到详情页的时候,需要显示调用screen层的跟*.vm同名的*.java方法,通过传入参数id,即选择了指定行,后台会将查询到的数据封装到对象中,在vm中可以直接使用,而不用再走ajax请求,提升了系统的反映速度。其中在BaseScreen.java中负责公共日志的输出,当前权限的获取,以及一些公共属性的动态获取。但是,有一些业务场景中,我们在进行跳转的时候,只需要知道跳转过来的当前id,并不需要后端来加载数据。这时候,如果能从vm中直接获取跳转过来的url的parameter参数,那么就可以省去跟*.vm同名的*.java中的execute方法。
// 唯一正确的用法: <input type="hidden" id="user_id" value=" $rundata.getRequest().getParameter(‘userId‘)"/> //以下几种用法都无法获取到参数的值 $!request.parameter.userId $!request.paarmater.getParameter(‘userId‘)
此外,Velocity更多使用细节参考英文官方文档或前往此处。
三、Bug描述:$!csrfToken.hiddenField
CSRF(跨站请求伪造),它通过伪装来自受信任用户的请求来利用受信任的网站。在IDCM项目中,在*.vm页面会有大量的<from>表单提交,在表单提交的时候,为了防止跨站请求伪造,要在form标签之后紧跟$!csrfToken.ajaxUniqueToken。
<form name="xxx" action="xxx" method="post"> $!csrfToken.hiddenField </form>
上述代码中,在VM文件的form表单中添加了token。该表单请求极有可能涉及数据增删改,需要防范CSRF,请确认使用POST请求,增加token参数,并在服务端校验token。
三、Bug描述:
附录:
阿里巴巴-基础架构事业群业务,项目路径:
基础架构事业群业务。