`
webee
  • 浏览: 8908 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类

使用Liferay 中 Spring portlet mvc 模式下的Ajax探讨,实例代码分享!

阅读更多

就现在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
分享到:
评论
2 楼 webee 2010-09-17  
真liuyake 写道
可惜我现在还没研究那么深。。。

加油啊!
1 楼 真liuyake 2010-09-15  
可惜我现在还没研究那么深。。。

相关推荐

Global site tag (gtag.js) - Google Analytics