java - JSP 文件中的拦截器、图 block 、注释和自定义包含

标签 java spring jsp spring-mvc interceptor

背景

在 Spring 3.x 应用程序中使用图 block 。该应用程序使用一个 standard.jsp 文件作为网站模板,它定义了典型的元素:文档类型、导航、标题、正文等。

standard.jsp 文件应动态包含特定于页面的自定义内容。例如,如果 URL 为“http://localhost/account ”,则 <head>元素应包含:

<link rel="stylesheet" href="styles/account.css" />

每个tile定义可以写成如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions ...>
<tiles-definitions>
    <definition ...>
        <put-attribute name="viewName" value="account" />
    </definition>
</tiles-definitions>

然后,在 standard.jsp 文件中:

<link rel="stylesheet" href="<tiles:insertAttribute name="viewName" />.css"/>

问题

这会产生所需的结果,但tiles属性是硬编码的,为每个tiles.xml文件有效地复制。

问题

如何避免重复 put-attribute无处不在的定义,但仍然导入与正在渲染的 View 相对应的特定 CSS 文件?

想法

使用拦截器仅适用于 / URI,仅此而已。例如:

@EnableWebMvc
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("intro");
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        registry.addInterceptor(new BaseInterceptor()).addPathPatterns("/**");
    }
}

配置额外的 View Controller 不会触发拦截器代码:

registry.addViewController("/account").setViewName("account");

如果有效,那么我们可以通过扫描类路径来迭代所有 JSP 文件(请参阅 herehere )。磁贴代码可能会干扰 JSP 的 View Controller 注册表:

@Bean
public TilesViewResolver tilesViewResolver() {
    TilesViewResolver viewResolver = new TilesViewResolver();
    viewResolver.setViewClass(TilesView.class);

    return viewResolver;
}

@Bean
public TilesConfigurer tilesConfigurer() {
    TilesConfigurer tilesConfigurer = new TilesConfigurer();
    tilesConfigurer.setDefinitions("/WEB-INF/**/tiles.xml");

    return tilesConfigurer;
}

拦截器仅在 / 时触发并可用于注入(inject) View 名称:

public class BaseInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(BaseInterceptor.class);

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("BASE INTERCEPTOR POST HANDLE");

        if (modelAndView != null) {
            modelAndView.addObject("stylesheet", modelAndView.getViewName() + ".css");
        }

        super.postHandle(request, response, handler, modelAndView);
    }
}

但是由于瓷砖的存在,除了 / 之外的任何事情都不会触发拦截器。 .

最佳答案

我希望我正确理解你的问题:你有一些可以从 View 名称中派生的值(value) - 对吧?

我的解决方案(Spring 3.2、Tiles 3)是使用模式:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>

    <!-- base - every thing that is common -->
    <definition name="base" template="/WEB-INF/layouts/template.jspx">
        ...
    </definition>

    <!-- Tiles view definition for the complete backend --> 
    <definition name="prefix/**" extends="base">
        <put-attribute name="mainPart" value="/WEB-INF/views/{1}.jsp" />
        <put-attribute name="stylesheetUrl" value="/styles/{1}.css" />
    </definition>

</tiles-definitions>

这是您需要的唯一一个图 block xml。当您尝试渲染名称为 prefix/x/y 的 View 时,Tiles 将加载 /WEB-INF/layouts/template.jspx 模板并设置两个属性:

  • mainPart = /WEB-INF/views/x/y.jsp
  • stylesheetUrl = /styles/x/y.css

关于java - JSP 文件中的拦截器、图 block 、注释和自定义包含,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28202614/

相关文章:

java - EL 中的 PropertyNotFoundException

jsp - EL 表达式未在 JSP 中计算

java - 复杂搜索查询 JPA

java - 从 POJO 调用基于 Spring 的 Web 应用程序类

java - Eclipse 控制台中的位置超链接

java - Hibernate @Email 列表上的注释

java - Hibernate + Spring 异常 : Unknown Entity

Java从同一对象的不同HashMap中获取最终计算结果

java - 数组处理时出现越界异常

java - 在 Junit 4 中构建测试套件