我正在使用Spring-MVC作为控制器的项目,JSF负责渲染。我现在需要在页面中实现一些Ajax功能。我所追求的是这样的:
第3步是我迷路的时候。到目前为止,我发现我必须使用普通的JSP和tile(Handling Ajax Requests with Spring MVC Controllers)来实现“开箱即用”的这种功能。但我需要使用JSF和我的一个XHTML片段作为“模板”
我已经在我的spring配置文件中配置了AJAX解析器,但它用于返回JSON对象。现在我需要返回整个HTML。我想使用服务器进行渲染,而不是从JSON对象模拟它并将HTML粘贴到页面上的正确位置。有没有办法如何“说服”org.springframework.faces.mvc.JsfView
在AJAX请求中工作?这是我正常的JSF解析器配置:
<bean id="jsfViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".xhtml" />
</bean>
这是我的JSON Ajax解析器配置:
<bean id="ajaxViewResolver" class="com.myproject.web.springmvc.AjaxViewResolver">
<property name="ajaxView">
<bean class="com.myproject.web.springmvc.AjaxView" />
</property>
<property name="ajaxPrefix" value="ajax_"></property>
</bean>
以下是我的JSON AjaxViewResolver
中的代码:
public class AjaxViewResolver extends AbstractCachingViewResolver {
private Logger logger = Logger.getLogger(AjaxViewResolver.class);
private String ajaxPrefix;
private View ajaxView;
@Override
protected View loadView(String viewName, Locale locale) throws Exception {
logger.debug("loadView - enter");
logger.debug("loadView - viewName : " + viewName);
logger.debug("loadView - locale : " + locale);
View view = null;
if (viewName.startsWith(this.ajaxPrefix)) {
view = ajaxView;
}
logger.debug("loadView - returns : " + view);
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;
}
}
这是我的JSON AjaxView
类:
public class AjaxView extends AbstractView {
private Logger logger = Logger.getLogger(AjaxView.class);
/**
* Serialises the modelMap into a JSON string and writes the string to the outputStream
*/
@Override
protected void renderMergedOutputModel(Map map, HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.debug("renderMergedOutputModel - enter");
logger.debug("renderMergedOutputModel - map : " + map);
logger.debug("renderMergedOutputModel - request : " + request);
logger.debug("renderMergedOutputModel - response : " + response);
JSONSerializer serializer = new JSONSerializer();
serializer.exclude("*.class");
String jsonString = serializer.deepSerialize(map);
response.setContentType("text/plain; charset=UTF-8");
response.getOutputStream().write(jsonString.getBytes());
logger.debug("renderMergedOutputModel - response : " + response);
logger.debug("renderMergedOutputModel - exit");
}
}
有什么想法吗?
答案 0 :(得分:1)
看起来没有人需要这个。我花了最后几个小时浏览JSF和Spring MVC代码,我找到了一个适合我的解决方案。我想在这里介绍它,如果你们可以做一些同行评审。感谢。
解决方案是基于com.myproject.web.springmvc.AjaxViewResolver
创建新bean并进入属性ajaxView
注入新创建的类nz.co.bnz.olb.ib.web.springmvc.AjaxJsfView
,扩展org.springframework.faces.mvc.JsfView
。
这是剪辑的Spring配置:
<bean id="ajaxJsfViewResolver" class="nz.co.bnz.olb.ib.web.springmvc.AjaxViewResolver">
<property name="ajaxView">
<bean class="nz.co.bnz.olb.ib.web.springmvc.AjaxJsfView">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".xhtml" />
</bean>
</property>
<property name="ajaxPrefix" value="ajaxJsf_"></property>
</bean>
正如您所看到的,我必须传递prefix
和suffix
属性来定义如何形成我的XHTML文件的URL(JsfView
所必需的)。我还为此解析器创建了新的前缀ajaxJsf_
。这是新课程:
public class AjaxJsfView extends JsfView {
private Logger logger = Logger.getLogger(AjaxJsfView.class);
private String prefix;
private String suffix;
private String viewName;
@Override
protected void renderMergedOutputModel(Map map, HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.debug("renderMergedOutputModel - enter");
logger.debug("renderMergedOutputModel - map : " + map);
logger.debug("renderMergedOutputModel - request : " + request);
logger.debug("renderMergedOutputModel - response : " + response);
viewName = (String)map.get("view");
super.renderMergedOutputModel(map, request, response);
logger.debug("renderMergedOutputModel - response : " + response);
logger.debug("renderMergedOutputModel - exit");
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
@Override
public String getUrl() {
return getPrefix() + viewName + getSuffix();
}
@Override
public void setUrl(String arg0) {
super.setUrl(arg0);
}
}
在renderMergedOutputModel
方法中可以看到用作“视图”的实际文件的定义。它取自关键“视图”下的地图中的“模型”。 “视图”的完整路径在重写方法getUrl()
中实现。因此,作为最后一步,我必须实现我的控制器方法,以返回具有预期值的地图:
public ModelAndView getSomeTest(HttpServletRequest request, HttpServletResponse response){
Map<String, Object> map = new HashMap<String, Object>();
map.put("view", "pathToMyXHTMLFile/someTest");
map.put("name", "tomik");
ModelAndView returnModelAndView = new ModelAndView("ajaxJsf_increaseLimit", map);
return returnModelAndView;
}
最后这是使用的XHTML,最终以带有填充值的HTML格式返回:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core">
<p>Hello <h:outputText value="#{name}"/></p>
</ui:composition>