gpt4 book ai didi

java - 如何使用 springmvc 作为 Controller 渲染对 jsf 页面的 ajax 响应

转载 作者:行者123 更新时间:2023-12-01 15:55:21 29 4
gpt4 key购买 nike

我所在的项目使用 Spring-MVC 作为 Controller ,JSF 负责渲染。我现在需要在我的页面中实现一些 Ajax 功能。我所追求的是这样的:

  1. 用户点击按钮或其他可点击的“东西”
  2. 对 Controller 进行 Ajax 调用,直到返回响应为止,在按钮下方呈现某种带有文本“正在加载...”的面板
  3. Controller 将处理请求并以 HTML 形式返回结果。结果将被渲染到与“正在加载...”信息类似的面板中。

第三步是我迷路的时候。到目前为止,我发现我必须使用纯 JSP 和图 block ( Handling Ajax Requests with Spring MVC Controllers ) 来实现“开箱即用”的此类功能。但我需要使用 JSF 和我的 XHTML 片段之一作为"template"。
我已经在 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");
}

}

有什么想法吗?

最佳答案

看起来从来没有人需要这个。我花了几个小时浏览 JSF 和 Spring MVC 代码,并找到了一个适合我的解决方案。我想在这里介绍一下,如果你们可以做一些同行评审。谢谢。

解决方案是基于com.myproject.web.springmvc.AjaxViewResolver创建新的bean并进入房地产ajaxView注入(inject)新创建的类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>

如你所见,我必须传入 prefixsuffix属性来定义如何形成 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);
}
}

用作“ View ”的实际文件的定义可以在 renderMergedOutputModel 中看到。方法。它取自 map 上关键“ View ”下的“模型”。 “ View ”的完整路径是在重写方法 getUrl() 中实现的。因此,作为最后一步,我必须实现 Controller 的方法来返回其中包含预期值的 map :

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>

关于java - 如何使用 springmvc 作为 Controller 渲染对 jsf 页面的 ajax 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5187756/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com