知识点

相关文章

更多

最近更新

更多

Cannot expose request attribute 'website' because of an existing model object of the same name 的解决方案

2019-03-06 11:43|来源: 网路

在使用springmvc+freemarker,有可能你会遇到以下异常(如:资源找不到重定向到404的请求时):

javax.servlet.ServletException: Cannot expose request attribute 'website' because of an existing model object of the same name

at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:123)

at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)

at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)

at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)


看一下源码,可以发现如果exposeRequestAttributes设为true,model中已经存在该key,且allowRequestOverride为false是,就会报该错。session一样:

protected final void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
    String attribute;
    Object attributeValue;
    if(this.exposeRequestAttributes) {
        for(Enumeration en = request.getAttributeNames(); en.hasMoreElements(); model.put(attribute, attributeValue)) {
            attribute = (String)en.nextElement();
            if(model.containsKey(attribute) && !this.allowRequestOverride) {
                throw new ServletException("Cannot expose request attribute '" + attribute + "' because of an existing model object of the same name");
            }
 
            attributeValue = request.getAttribute(attribute);
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Exposing request attribute '" + attribute + "' with value [" + attributeValue + "] to model");
            }
        }
    }
 
    if(this.exposeSessionAttributes) {
        HttpSession session = request.getSession(false);
        Object attributeValue;
        String attribute;
        if(session != null) {
            for(Enumeration en = session.getAttributeNames(); en.hasMoreElements(); model.put(attribute, attributeValue)) {
                attribute = (String)en.nextElement();
                if(model.containsKey(attribute) && !this.allowSessionOverride) {
                    throw new ServletException("Cannot expose session attribute '" + attribute + "' because of an existing model object of the same name");
                }
 
                attributeValue = session.getAttribute(attribute);
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Exposing session attribute '" + attribute + "' with value [" + attributeValue + "] to model");
                }
            }
        }
    }
 
    if(this.exposeSpringMacroHelpers) {
        if(model.containsKey("springMacroRequestContext")) {
            throw new ServletException("Cannot expose bind macro helper 'springMacroRequestContext' because of an existing model object of the same name");
        }
 
        model.put("springMacroRequestContext", new RequestContext(request, response, this.getServletContext(), model));
    }
 
    this.applyContentType(response);
    this.renderMergedTemplateModel(model, request, response);
}


解决方法可以把allowRequestOverride 设为 true,下面是freemarker视图的配置:

<!-- 配置freeMarker视图解析器 -->
<bean id="viewResolverFtl" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>
    <property name="contentType" value="text/html; charset=UTF-8"/>
    <property name="exposeRequestAttributes" value="true"/>
    <property name="exposeSessionAttributes" value="true"/>
    <property name="exposeSpringMacroHelpers" value="true"/>
    <property name="allowSessionOverride" value="true" />
    <property name="allowRequestOverride" value="true" />
    <property name="cache" value="true"/>
    <property name="suffix" value=".ftl"/>
    <property name="order" value="0"/>
</bean>


相关问答

更多