Похоже, никто никогда не нуждался в этом. Я провел последние пару часов, просматривая код JSF и Spring MVC, и пришел с одним решением, которое работает для меня. Я хотел бы представить это здесь, и если вы, ребята, можете сделать некоторую экспертную оценку. Спасибо.
Решение состоит в том, чтобы создать новый bean-компонент на основе com.myproject.web.springmvc.AjaxViewResolver
и в свойство 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
, чтобы определить, как будет формироваться URL для моих файлов XHTML (необходимо для 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>