就现在Web框架铺天盖地的局面下,Spring依然还是那么有吸引力,毕竟好的产品总不会被人们忽略的。因最在Portal环境下开发,一点小小经验和大家分享,如有不解,尽可联系本人哦!
首先我们应该有的环境就不多说了,之前写过一篇文章是关于在Liferay下Spring Mvc的开发。本文就是基于这个环境,大体说下:
1、运行的Portal环境为Liferay Portal tomcat 6.0.5;
2、自己的项目是使用Spring MVC搭建的。
其他不多说,在上述环境下使用Ajax返回自己想要的数据是本文需要说明的问题;
一、客户端JS
此处客户端JS,即需要发送请求的一段采用的是Jquery 1.4.2,当然你可以使用你自己喜欢的Ajax方式。在Portal模式下最关键的地方是发送Ajax请求的地址,本人开始也很疑惑,但是Liferay的wiki还是给了咱很大的帮助。地址的取法如下:
<portlet:renderURL var="loadDisTagByParentIdUrl"
windowState="<%= LiferayWindowState.EXCLUSIVE.toString()%>">
<portlet:param name="action" value="loadDisTagByParentId"></portlet:param>
</portlet:renderURL>
最关键的地方是要设置windowState属性,看看属性值就应该明白,当这种状态时,portlet默认的Response是不会输出任何内容的,只是为了在服务端执行一个动作而已。此处采用actionUrl效果一样,注意发送请求是Jquery.ajax 参数类型 type 要设置为 post。客户端就是如此简单,其他的事情就到服务端再说。
二、服务端
首先看看Spring的MVC模式:

其实还是很简单的,对于开发者来讲只需要关心两点,第一是将请求转到Controller,这个过程是配置handler完成,第二是将输出交由Resolver完成,无论是Servlet还是Portlet环境都一样,这点Spring做的太好了,这点是由配置viewResolver来完成。明白了要做的事情,不难看出,要想请求输出能够按照你自己的想法来输出,最关键是要搞定Resolver。
1) AjaxViewResolver
我们可以自定义一个自己的Resolver,用来处理我们自己的Ajax请求,大致代码片段如下:
public class AjaxViewResolver extends AbstractCachingViewResolver {
public static final String AJAX_PREFIX = "ajax_";
protected String ajaxPrefix = AJAX_PREFIX;
private View ajaxView;
@Override
protected View loadView(String viewName, Locale locale) throws Exception {
View view = null;
if (viewName.startsWith(this.ajaxPrefix)) {
view = ajaxView;
}
return view;
}
public String getAjaxPrefix() {
return ajaxPrefix;
}
public void setAjaxPrefix(String ajaxPrefix) {
this.ajaxPrefix = ajaxPrefix;
}
public View getAjaxView() {
return ajaxView;
}
public void setAjaxView(View ajaxView) {
this.ajaxView = ajaxView;
}
}
此类的作用是将一个特殊的前最View交由AjaxView来处理,功能就如此简单,此处留意我们的View前缀;
2) AjaxView
来个自定的View处理器来处理有AjaxViewResolver转过来的请求,此类代码片段如下:、
public class AjaxView extends AbstractView {
public static final String JSONCONFIG_ATTRIBUTE = AjaxView.class.getName()+ ".JsonConfig";
private static final String DEFAULT_AJAX_CONTENT_TYPE = "text/plain; charset=UTF-8";
@Override
public String getContentType() {
String orgiContentType = super.getContentType();
if (StringUtils.isEmpty(orgiContentType))
orgiContentType = DEFAULT_AJAX_CONTENT_TYPE;
return orgiContentType;
}
@Override
public void setContentType(String contentType) {
super.setContentType(contentType);
}
// TODO filter and log
@Override
protected void renderMergedOutputModel(Map<String, Object> map,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
if (map == null || map.isEmpty()) {
JSONObject.fromObject("{}").write(response.getWriter());
return;
}
Object result = null;
for (Map.Entry<String, Object> entry : map.entrySet()) {
result = entry.getValue();
break;
}
JSON json = this.createJson(request, result);
json.write(response.getWriter());
}
private JSON createJson(HttpServletRequest request, Object obj) {
JsonConfig jsonConfig = (JsonConfig) request.getAttribute(JSONCONFIG_ATTRIBUTE);
if (jsonConfig == null)
return JSONSerializer.toJSON(obj);
else
return JSONSerializer.toJSON(obj, jsonConfig);
}
}
此类也很简单,注意两点,应为我们Ajax通常返回Json数据,所以此类就返回Json,其他的你可以自己重载了,第二注意重载的方法renderMergedOutputModel。方法最后一段所写出的东西就是最终返回到客户端的东西了。json.write(response.getWriter());也很简单,继续。
3)MyController
Controller 是Spring最最普通的Controller,正如前面地址所写,我们要执行一个action=loadDisTagByParentId的渲染,所以在Controller中有了如下的方法:
@RenderMapping(params = "action=loadDisTagByParentId")
public String loadDisTagByParentId(
@RequestParam(value = "tagId", required = false) Long tagId,
ModelMap map, PortletRequest req, PortletResponse response) {
List<Tag> tags = tagSvc.getTagsByParentId(tagId);
List<TreeNode> nodes = new ArrayList<TreeNode>();
for (Tag tag : tags) {
TreeNode node = new TreeNode();
node.setData(tag.getName());
JSONObject jsonAttrs = new JSONObject();
jsonAttrs.put("id", "tagid_" + tag.getId());
node.setAttr(jsonAttrs);
node.setState("closed");
nodes.add(node);
}
map.clear();
map.addAttribute("tags", nodes);
return AjaxViewResolver.AJAX_PREFIX;
}
此方法没什么特殊,唯一不同的是注意了,方法返回的View是 AjaxViewResolver.AJAX_PREFIX,即在AjaxViewResolver中指定的视图前缀,此时就明白了,当执行完此方法之后,就交由AjaxView去处理了。此方法中我们可以准备一下我们要放回到客户端的数据。依然放在ModelMap中,在AjaxView中可以通过Map取出来。是不是很简单呢。
到此我们客户端发送的请求已经经过我们的Resolver和AjaxView处理完毕,当然我们要感谢Liferay给了我们一个很好的模式,这个模式就是Portal默认不输出任何数据。返回到客户端的数据你可以通过自定义AjaxView来达到各种格式的效果。再次不再衍生。
三、总结下好处
1、在使用这种模式下的好处是不依赖任何Ajax框架,你可以使用最普通的XMLHttpRequest来发送请求,只需将发送请求的地址给对即可;
2、不跑出Portlet之外,此点和DWR+SPRING在Portlet模式有所不同,Dwr是通过一个单独的Servlet来处理他的Ajax请求。
3、原生的地址,无需构建其他地址。
4、Spring注入毫不影响,我们依然使用的是Spring的Controller方法,方法签名依然可以保持为Spring原有的模式,参数依然可以注入;
5、标准的Spring配置,无需其他文件的配置,如web,dwr.xml等。
也许你在使用Portlet,也许你在使用Liferay,希望此文能给你帮助,顶吧!谢谢!

- 大小: 51.2 KB
分享到:
相关推荐
【标题】"liferay-spring-web-mvc-portlets" 是一个基于 Liferay 框架,结合了 Spring 和 Web MVC 技术的portlet 开发项目。由 Youssef SOUROUR 创建,它展示了如何在 Liferay 平台上构建功能丰富的、交互式的Web...
#### 章节七:使用Spring Portlet MVC入门 - **Spring Portlet MVC框架**:介绍Spring Portlet MVC框架的核心概念和组件,包括控制器、视图和模型等。 - **示例应用开发**:通过一个具体的示例应用,展示如何利用...
学会使用Liferay的JSF团队领导开发的JSF和Portlet,Liferay是处于领导地位的JavaPortal开发商。 全面介绍JSF2.0、详述如何使用Ajax,以及按照JSF2.0、的方式构建组件、快速理解众多可以直接运行的代码示例。 作者 ...
学会使用Liferay的JSF团队领导开发的JSF和Portlet,Liferay是处于领导地位的JavaPortal开发商。 全面介绍JSF2.0、详述如何使用Ajax,以及按照JSF2.0、的方式构建组件、快速理解众多可以直接运行的代码示例。 作者 ...
内容概要:本文详细介绍了基于松下AFPX-C38AT PLC平台的双切刀三边封制袋机控制系统。该系统通过PLC控制四台伺服电机进行切刀和移刀动作以及二轴送袋定位,同时管理两台变频器实现主机和放料电机的同步调速,并利用WK8H模块进行16路温控输出。文中展示了具体的PLC编程实例,如伺服电机的DRVI指令、变频器的同步控制、温控模块的PID调节等。此外,还讨论了硬件配置、触摸屏界面设计、通信协议设置等方面的内容,强调了系统的灵活性和稳定性。 适合人群:从事工业自动化控制领域的工程师和技术人员,尤其是对PLC编程和伺服电机控制感兴趣的读者。 使用场景及目标:适用于需要深入了解PLC控制系统的开发人员,帮助他们掌握伺服电机控制、变频器同步调速和温控模块编程的具体方法,提高实际项目中的应用能力。 其他说明:文章不仅提供了详细的编程示例,还分享了许多实际调试的经验和技巧,有助于读者更好地理解和应用相关技术。
计算机审计软件的特点与应用.pdf
离散傅里叶变换(DFT)分析 函数[F,FT,Phase]=DFT(T,Signal,Fi,FF,Res,P,Cursor)计算离散傅里叶变换(DFT) 功能概述:离散傅立叶变换(DFT)分析 函数[F,FT,Phase]=DFT(T,Signal,Fi,FF,Res,P,Cursor)是频率域信号分析的通用工具。它在指定的频率范围内计算信号的离散傅立叶变换(DFT),提供可定制的可视化选项。 输入 T(采样时间向量,秒):表示与正在分析的信号样本相对应的时间点。 信号:您希望在频域中检查的数据集或信号。 FI(以赫兹为单位的初始频率):频率分析的起点。 FF(最终频率(Hz):频率分析范围的上限。 Res(分辨率以赫兹为单位):确定傅立叶变换的精度。较小的值会增加分辨率。 P(打印选项): 0:没有生成图。 1: 仅显示震级图。 2: 显示大小和相位图。 光标(在绘图上启用光标)(可选): 1: 当P不
内容概要:本文详细介绍了如何在Matlab中构建一个综合了垃圾焚烧、碳捕集和电转气(P2G)技术的虚拟电厂优化调度系统。该系统旨在通过合理的设备参数设置、多能流耦合约束以及分段碳价机制的目标函数设计,实现环保与经济效益的最大化。文中展示了具体的数学模型建立方法,如设备参数初始化、能量平衡约束、碳捕集与P2G物料平衡、分时碳成本计算等,并讨论了求解技巧,包括变量定义、求解器选择和约束条件处理等方面的内容。此外,还探讨了垃圾焚烧发电占比变化对P2G设备启停策略的影响,以及不同时间段内的最优调度策略。 适合人群:从事能源系统优化研究的专业人士,特别是那些熟悉Matlab编程并希望深入了解虚拟电厂调度机制的人群。 使用场景及目标:适用于希望提高虚拟电厂运行效率的研究机构或企业。通过本项目的实施,能够更好地理解如何整合多种能源技术,在满足电力供应需求的同时减少碳排放,降低成本。具体应用场景包括但不限于:制定更加科学合理的发电计划;评估新技术引入后的潜在效益;探索不同政策环境下的最佳运营模式。 其他说明:文中提到的一些关键技术点,如碳捕集与P2G的协同工作、垃圾焚烧发电的灵活应用等,对于推动清洁能源的发展具有重要意义。同时,作者也在实践中遇到了一些挑战,如约束条件之间的冲突等问题,并分享了解决这些问题的经验。
入栈和出栈的基本操作
内容概要:本文详细探讨了V型永磁同步电机中永磁体参数调整的方法和技术,特别是在Maxwell软件中的应用。首先介绍了V型永磁体的关键参数(如V型夹角、磁钢厚度、极弧系数等)及其对电机性能的影响。接着讨论了利用Maxwell进行参数化建模、参数扫描、优化方法(如响应面法、多目标遗传算法)的具体步骤和注意事项。文中还提供了多个实用脚本,涵盖从几何建模、材料属性设置到求解器配置、后处理分析等多个方面。此外,强调了优化过程中应注意的问题,如退磁校验、磁密饱和、涡流损耗等,并给出了一些实战技巧。 适合人群:从事电机设计与仿真的工程师、研究人员,尤其是熟悉Maxwell软件的用户。 使用场景及目标:帮助用户掌握V型永磁同步电机永磁体参数调整的技术要点,提高电机性能指标(如降低齿槽转矩、减少谐波失真、优化转矩波动等)。通过实例和脚本指导,使用户能够在Maxwell中高效地完成仿真和优化任务。 其他说明:文章不仅提供了详细的理论解释,还包括大量实践经验分享和常见问题解决方案,有助于读者更好地理解和应用相关技术。
内容概要:本文详细介绍了光伏发电系统的仿真建模及其控制策略。主要内容分为四个部分:首先是光伏发电系统仿真模型的搭建,通过数学公式和Python代码实现了太阳电池特性的模拟;其次,探讨了扰动观察法(PO)作为最大功率点跟踪(MPPT)的方法,展示了其实现逻辑和代码示例;第三部分讨论了带储能控制策略的设计,利用状态机管理储能系统的充放电过程,确保电力供应平稳;最后进行了负载突变验证实验,评估了系统在极端条件下的稳定性和可靠性。通过这些步骤,作者不仅解释了理论背景,还提供了具体的实现细节和技术挑战。 适合人群:对光伏发电系统感兴趣的研究人员、工程师以及相关领域的学生。 使用场景及目标:适用于希望深入了解光伏发电系统工作原理的人群,尤其是关注最大功率点跟踪技术和储能控制系统设计的应用开发者。目标是帮助读者掌握光伏系统仿真的关键技术,为实际项目提供理论支持和技术指导。 其他说明:文中提供的代码片段可以直接用于实验环境,便于读者动手实践。此外,针对可能出现的问题如耦合振荡等,给出了相应的解决方案。
内容概要:本文详细介绍了8极48槽辐条型电机转子桥的参数化建模方法及其优化过程。通过将桥的厚度、过渡圆弧半径和倒角角度作为变量进行参数化处理,利用Maxwell软件实现了自动化仿真和优化。文中展示了具体的Python和VBScript代码示例,用于动态调整桥部尺寸并监控磁密分布,最终通过参数扫描找到最佳设计参数组合,显著降低了磁密峰值和扭矩波动,提高了电机的整体性能。 适合人群:从事电机设计与仿真的工程师和技术人员,尤其是熟悉Maxwell软件的用户。 使用场景及目标:适用于需要优化电机转子桥结构的设计项目,旨在提高电机性能,降低磁密峰值和扭矩波动,确保机械强度的同时提升电磁性能。 其他说明:文章提供了详细的代码示例和操作步骤,帮助读者快速掌握参数化建模技巧,并强调了网格设置和多参数联动优化的重要性。
内容概要:本文详细介绍了用于风电调频并网系统的4机2区模型,该模型能够在短时间内完成长时间跨度的仿真,极大提高了科研和工程分析的效率。文中具体阐述了模型的结构特点,包括两个区域内的发电机组分布、连接方式以及风电场的虚拟惯量控制机制。此外,文章深入解析了四种PSS(电力系统稳定器)模式的工作原理及其在不同工况下的表现,特别是针对风电接入带来的低频振荡问题进行了讨论。通过实例展示了PSS模式对系统稳定性的显著提升效果,并分享了一些实用的调参技巧。 适合人群:从事电力系统仿真、风电并网研究的专业技术人员及高校相关专业师生。 使用场景及目标:适用于需要进行大规模风电调频并网系统仿真的场合,旨在帮助研究人员更好地理解和解决风电接入对电网稳定性的影响,优化风电并网友好度。 其他说明:文章不仅提供了理论分析,还包括具体的Python和Matlab代码示例,便于读者理解和实践。同时强调了在高风电渗透率条件下选择合适PSS模式的重要性。
内容概要:本文详细介绍了如何使用LabVIEW的Excel工具包来高效生成带有特定格式的测试报告。首先,准备一个Excel模板文件,设置好表头样式、公司LOGO和合并单元格,并用特殊标记占位。然后,通过LabVIEW代码进行Excel操作,如初始化Excel应用、打开和复制模板文件、写入测试数据、设置条件格式、调整列宽以及保存和关闭文件。文中强调了使用二维数组批量写入数据、条件格式设置超标数据标红、精确控制列宽、避免文件覆盖等问题。此外,还提到了一些常见问题及其解决方案,如Excel进程卡死、数据错位等。最终,通过这些方法可以将原本复杂的报告生成过程大幅简化,提高工作效率。 适合人群:熟悉LabVIEW编程的工程师和技术人员,尤其是从事自动化测试和数据分析工作的人员。 使用场景及目标:适用于需要频繁生成格式一致的测试报告的场景,如汽车电子测试、环境监测等领域。目标是通过LabVIEW的Excel工具包实现自动化、高效的报告生成,节省时间和精力。 阅读建议:读者可以通过本文学习如何利用LabVIEW的Excel工具包快速生成带格式的测试报告,掌握关键技术和最佳实践,从而提升工作效率。同时,在实践中应注意模板的设计和代码的优化,以应对各种复杂的需求变化。
main (4).ipynb
计算机数学基础(下).pdf
内容概要:本文详细介绍了如何利用MATLAB实现基于多智能体系统一致性算法的电力系统分布式经济调度策略。首先,通过构建邻接矩阵生成函数,处理电网拓扑结构,确保每个节点能够正确获取邻居信息。接着,定义发电机成本函数和负荷效用函数,将两者统一为二次函数形式,以便更好地兼顾发电侧和用电侧的经济性。然后,重点展示了核心的一致性迭代算法,通过拉普拉斯矩阵实现信息扩散,使发电机和负荷之间的增量成本和效益逐步趋于一致。此外,文中还提供了具体的测试案例,包括10台发电机和19个柔性负荷组成的系统,展示了算法的高效性和鲁棒性。最后,强调了通信拓扑设计对收敛速度的影响,并分享了一些调试经验和潜在的应用前景。 适合人群:电力系统研究人员、自动化控制工程师、MATLAB开发者以及对分布式优化算法感兴趣的学者。 使用场景及目标:适用于电力系统经济调度的研究与开发,旨在提高调度效率、降低成本的同时保障系统的稳定性。通过分布式算法替代传统的集中式调度方式,增强系统的隐私保护能力和计算效率。 其他说明:文中提供的MATLAB代码不仅可用于学术研究,还可以进一步应用于实际工程项目中,特别是在含有大量新能源接入的现代电力系统中,展现出更大的优势。
计算机数控装置课件.pdf
内容概要:本文详细介绍了RRT(快速扩展随机树)路径规划算法的多个优化方法及其具体实现。首先指出原始RRT存在的缺陷,如路径质量差、计算时间长等问题。然后提出了一系列改进措施,包括目标偏向采样、自适应步长控制、路径平滑处理以及椭圆约束采样等。每个改进都附有具体的Python代码片段,并解释了其实现思路和技术细节。此外,文中还讨论了不同改进方案之间的协同使用效果,强调了实际应用中的注意事项。 适合人群:从事机器人路径规划研究的技术人员,尤其是有一定编程基础并希望深入了解RRT算法优化的人群。 使用场景及目标:适用于各种需要高效路径规划的应用场合,如仓储机器人、无人机避障、机械臂运动规划等。主要目标是提高路径规划的速度和质量,同时减少计算资源消耗。 其他说明:尽管这些改进显著提升了RRT的表现,但在实际部署时仍需考虑传感器噪声和系统延迟等因素的影响。作者分享了许多个人实践经验,为读者提供了宝贵的参考。
计算机试题实例分析.pdf