【问题标题】:Using Spring MVC 3.1+ WebApplicationInitializer to programmatically configure session-config and error-page使用 Spring MVC 3.1+ WebApplicationInitializer 以编程方式配置 session-config 和 error-page
【发布时间】:2012-06-04 13:16:12
【问题描述】:

WebApplicationInitializer 提供了一种方法来以编程方式表示标准 web.xml 文件的大部分 - servlet、过滤器、侦听器。

但是我还没有找到一种使用 WebApplicationInitializer 来表示这些元素(会话超时、错误页面)的好方法,是否仍然需要为这些元素维护 web.xml?

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/uncaughtException</location>
</error-page>

<error-page>
    <error-code>404</error-code>
    <location>/resourceNotFound</location>
</error-page>

【问题讨论】:

    标签: java spring-mvc servlet-3.0


    【解决方案1】:

    我对这个主题做了一些研究,发现对于一些配置,比如 sessionTimeOut 和错误页面,你仍然需要 web.xml。

    看看这个Link

    希望这对您有所帮助。 干杯。

    【讨论】:

    • 感谢@Japs,是的,听起来这些需要通过 web.xml 文件完成
    • 情况变了还是我们还需要web.xml?
    • 我不确定。最近没有尝试过最新的春季版本。
    • 您可以使用@ExceptionHandler 注释方法或@ControllerAdvice 类进行error-page 配置。对于 session-config 添加会话监听器并使用 setMaxInactiveInterval() 指定超时。
    • @ExceptionHandler 仅适用于您在控制器中抛出的错误。它不适用于 SpringSecurity 401/403 或普通 404s。
    【解决方案2】:

    使用 spring-boot 非常简单。

    我相信通过扩展SpringServletContainerInitializer 也可以在没有弹簧靴的情况下完成。它似乎是专门为此设计的。

    Servlet 3.0 ServletContainerInitializer 旨在支持基于代码的 使用 Spring 配置 servlet 容器 WebApplicationInitializer SPI 与(或可能在 结合)传统的基于 web.xml 的方法。

    示例代码(使用 SpringBootServletInitializer)

    public class MyServletInitializer extends SpringBootServletInitializer {
    
        @Bean
        public EmbeddedServletContainerFactory servletContainer() {
            TomcatEmbeddedServletContainerFactory containerFactory = new TomcatEmbeddedServletContainerFactory(8080);
    
            // configure error pages
            containerFactory.getErrorPages().add(new ErrorPage(HttpStatus.UNAUTHORIZED, "/errors/401"));
    
            // configure session timeout
            containerFactory.setSessionTimeout(20);
    
            return containerFactory;
        }
    }
    

    【讨论】:

    • 我认为 servletContainer() 方法中缺少@Bean 注解。
    • 这仅适用于嵌入式 tomcat。在application.properties 中设置server.session-timeout=20 更容易
    • 值得注意的是,SpringServletContainerInitializer 的 JavaDoc 明确指出“此类既不是为扩展而设计的,也不是为了扩展而设计的。它应该被视为内部类型”。所以我认为说“它似乎是专门为它设计的”是不正确的。您从 JavaDoc 中得到的引用是正确的 - 该类确实支持基于代码的配置,但它通过委托给 WebApplicationInitializer 来实现这一点,而不是通过提供扩展点本身。
    【解决方案3】:

    其实WebApplicationInitializer 并没有直接提供。但是有一种方法可以通过 java 配置来设置 sessointimeout。

    你必须先创建一个HttpSessionListner:

    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    public class SessionListener implements HttpSessionListener {
    
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            //here session will be invalidated by container within 30 mins 
            //if there isn't any activity by user
            se.getSession().setMaxInactiveInterval(1800);
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println("Session destroyed");
        }
    }
    

    在此之后,只需在您的 servlet 上下文中注册此侦听器,该上下文将在方法 onStartup 下的 WebApplicationInitializer 中可用

    servletContext.addListener(SessionListener.class);
    

    【讨论】:

      【解决方案4】:

      扩展 BwithLove 注释,您可以使用异常和控制器方法定义 404 错误页面,即@ExceptionHandler:

      1. 在 DispatcherServlet 中启用抛出 NoHandlerFoundException。
      2. 在控制器中使用 @ControllerAdvice 和 @ExceptionHandler。

      WebAppInitializer 类:

      public class WebAppInitializer implements WebApplicationInitializer {
      @Override
      public void onStartup(ServletContext container) {
          DispatcherServlet dispatcherServlet = new DispatcherServlet(getContext());
          dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
          ServletRegistration.Dynamic registration = container.addServlet("dispatcher", dispatcherServlet);
          registration.setLoadOnStartup(1);
          registration.addMapping("/");
      }
      
      private AnnotationConfigWebApplicationContext getContext() {
          AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
          context.setConfigLocation("com.my.config");
          context.scan("com.my.controllers");
          return context;
      }
      }
      

      控制器类:

      @Controller
      @ControllerAdvice
      public class MainController {
      
          @RequestMapping(value = "/")
          public String whenStart() {
              return "index";
          }
      
      
          @ExceptionHandler(NoHandlerFoundException.class)
          @ResponseStatus(value = HttpStatus.NOT_FOUND)
          public String requestHandlingNoHandlerFound(HttpServletRequest req, NoHandlerFoundException ex) {
              return "error404";
          }
      }
      

      “error404”是一个JSP文件。

      【讨论】:

        【解决方案5】:

        在 web.xml 中

        <session-config>
            <session-timeout>3</session-timeout>
        </session-config>-->
        <listener>
            <listenerclass>
        
          </listener-class>
        </listener>
        

        监听类

        public class ProductBidRollBackListener implements HttpSessionListener {
        
         @Override
         public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            //To change body of implemented methods use File | Settings | File Templates.
        
         }
        
         @Override
         public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            HttpSession session=httpSessionEvent.getSession();
            WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
            ProductService productService=(ProductService) context.getBean("productServiceImpl");
            Cart cart=(Cart)session.getAttribute("cart");
            if (cart!=null && cart.getCartItems()!=null && cart.getCartItems().size()>0){
                for (int i=0; i<cart.getCartItems().size();i++){
                    CartItem cartItem=cart.getCartItems().get(i);
                    if (cartItem.getProduct()!=null){
                        Product product = productService.getProductById(cartItem.getProduct().getId(),"");
                        int stock=product.getStock();
                        product.setStock(stock+cartItem.getQuantity());
                        product = productService.updateProduct(product);
                    }
                }
            }
         }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-02
          • 1970-01-01
          • 2013-12-15
          • 1970-01-01
          • 2012-04-18
          • 2017-08-20
          • 1970-01-01
          • 2017-05-31
          相关资源
          最近更新 更多