【问题标题】:spring boot 1.4 jsp page not evaluated Forward InternalViewResolverspring boot 1.4 jsp 页面未评估 Forward InternalViewResolver
【发布时间】:2018-02-06 22:52:26
【问题描述】:

经过 2 天的调查,并查看了很多关于我的问题的答案,我无法解决它。 我不是spring框架的专家。

入口点: 一年前我已经生成了一个 jhipster 项目。我想在我的项目中嵌入 jsp 页面。

我在一个 maven 项目中使用 spring boot 1.4 我包含以下依赖项:

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>

我在实现 ServletContextInitializer.onStartup 的 WebConfigurer 类中创建了一个新的 servlet,并在 WEB-INF 资源文件夹中创建了一个名为 servletJsp-servlet.xml 的文件。 xml 实例化 InternalViewResolver 前缀 /mesPages/ 和后缀=.jsp

我还创建了一个控制器:

@Controller
public class TestJspController {
    @RequestMapping(value = "/jsp/bbb")
    public ModelAndView serveLog4jAdmin() {
        return new ModelAndView("log4jAdmin");
    }
}

我坚持在这里:(见下面的日志)

日志说:

  • 控制器很好用
  • 它很好地返回了 ModelAndView
  • 从 InternalResourceView 'log4jAdmin' 启动转发到资源 [/mesPagesJsps/log4jAdmin.jsp]

但在那之后,不是获取它并渲染它,而是没有堆栈跟踪并尝试使用另一个 servlet 解析 jsp 页面:dispatcherServlet(我相信这是默认的 spring 自动配置和创建的)spring servlet。 dispatcherServlet 成功获取它,因为我已将我的文件夹 mesPages(其中包含我的 jsps)放在资源和 webapp 的项目(META-INF、WEB-INF、根文件夹)中的每个位置

最后,jsp页面没有被评估,broswer给我下载它作为“application/octet-stream”。 以前在将 jsp 放在所有这些文件夹上之前,我曾经有相同的控制器行为,但以 404 错误(空白页)结束。

我真的不明白为什么应用会这样。 我有另一个运行良好的弹簧(非启动)网络应用程序。 我试图调试,但对我来说很复杂......调试时我只是检测到 requestDispatcher 无法调度 Forward,因为在某些“下一个”变量中没有 FORWARD 类型的处理程序。 我认为这是原因......

如果有人有答案,我会很高兴
我可以提供任何其他需要的信息。

日志相关部分:

[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'servletJSP' processing GET request for [/jsps/jsp/bbb]
[  XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /jsp/bbb
[  XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView fr.softeam.testify.web.rest.jsp.TestJspController.serveLog4jAdmin()]
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/jsps/jsp/bbb] is: -1
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Rendering view [org.springframework.web.servlet.view.JstlView: name 'log4jAdmin'; URL [/mesPagesJsps/log4jAdmin.jsp]] in DispatcherServlet with name 'servletJSP'
[  XNIO-3 task-2] o.s.web.servlet.view.JstlView            : Forwarding to resource [/mesPagesJsps/log4jAdmin.jsp] in InternalResourceView 'log4jAdmin'
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/mesPagesJsps/log4jAdmin.jsp]
[  XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /mesPagesJsps/log4jAdmin.jsp
[  XNIO-3 task-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/mesPagesJsps/log4jAdmin.jsp]
[  XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/mesPagesJsps/log4jAdmin.jsp] are [/**]
[  XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/mesPagesJsps/log4jAdmin.jsp] are {}
[  XNIO-3 task-2] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/mesPagesJsps/log4jAdmin.jsp] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@1774cad]]] and 1 interceptor
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/mesPagesJsps/log4jAdmin.jsp] is: -1
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Successfully completed request
[  XNIO-3 task-2] o.s.web.servlet.DispatcherServlet        : Successfully completed request

【问题讨论】:

  • 你为什么要创建一个新的DispatcherServlet? Spring Boot 已经预配置了一个。

标签: spring jsp spring-boot


【解决方案1】:

因为我想为所有 jsp 开辟一条新路径(我知道我们也可以在控制器中做到这一点),并且我担心保留相同的 servlet 来同时为 angular 前端和 jsp 提供服务。 因为 jhipster 生成了很多参数化的类(HttpSecurity,),所以我认为创建一个新的 servlet(没有任何自定义参数)可能更简单并且避免问题。

DispatcherServlet.render()
--> resolveViewName() qui retourne une JstlView
--> JstlView.render()
--> renderMergedOutputModel()
dispatcherPath = prepareForRendering(request, response);   //  dispatcherPath = /mesPagesJsps/log4jAdmin.jsp
RequestDispatcher rd = getRequestDispatcher() // rd.path=/mesPagesJsps/log4jAdmin.jsp   and   rd.servletChain=another DispatcherServlet !!! why ??? named dispatcherServlet, which is not my jsp servlet
--> rd.forward()
--> forwardImpl()
--> response.resetBuffer()
newServletPath = newRequestUri = /mesPagesJsps/log4jAdmin.jsp
pathMatch.servletChain still contains wrond servlet : dispatcherServlet instead of jspServlet
--> servletContext.getDeployment().getServletDispatcher().dispatchToPath(requestImpl.getExchange(), pathMatch, DispatcherType.FORWARD);
--> servletInitialDispatcher.dispatchToPath()
servletRequestContext.servletChain correspond to my servletJSP
--> dispatchRequest( pathInfo = /mesPagesJsps/log4jAdmin.jsp, dispatcherType=FORWARD, servletChain is not my jsp servletJSP but dispatcherServlet )
Exchange is : HttpServerExchange{ GET /mesPagesJsps/log4jAdmin.jsp request {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], Accept-Language=[fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3], Cache-Control=[max-age=0], Accept-Encoding=[gzip, deflate], User-Agent=[Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0], Connection=[keep-alive], Cookie=[CSRF-TOKEN=f6843de6-766d-4259-8a84-242c020420bc; JSESSIONID=VrVa7HNkUmzv_JM_cAhwyrfGWGCcrjZSltoQh2EJ], Upgrade-Insecure-Requests=[1], Host=[localhost:8080]} response {X-Application-Context=[testify_jhi:swagger,dev:8080], Content-Language=[fr-]}}
--> servletInitialHandler.dispatchRequest()
setCurrentServlet( WITH SERVLET dispatcherServlet and NOT servletJSP )
--> next.handleRequest(exchange) : next is here a SessionRestoringHandler
--> next.handleRequest(exchange) : next is here PredicateHandler. This called because a sessionId has been found ...
--> predicate.resolve() with a predicate of type REQUEST (I think this bad) --> which return falseHandler
--> next.handleRequest() --> with again a predicate of type REQUEST --> which return falseHandler
--> next.handleRequest() --> with a ServletDispatchingHandler whose ServletChain is the wrong servlet : dispatcherServlet instead of servletJSP
the dispatcher type is still FORWARD here but its to late because I thing the wrong servlet process the request

【讨论】:

    【解决方案2】:

    因为我想为所有 jsp 开辟一条新路径(我知道我们也可以在控制器中做到这一点),并且我担心保留相同的 servlet 来同时为 angular 前端和 jsp 提供服务。 因为 jhipster 生成了很多参数化的类(HttpSecurity,),所以我认为创建一个新的 servlet(没有任何自定义参数)可能更简单并且避免问题。

    比如有HttpSecurity,还有这个:

    public void customize(ConfigurableEmbeddedServletContainer container) {
        MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
        // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
        mappings.add("html", "text/html;charset=utf-8");
        // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
        mappings.add("json", "text/html;charset=utf-8");
        //mappings.add("jsp", "text/html;charset=utf-8"); // si je fais ça, en combinaisais avec le addResourcesHandler(), alors la page jsp est affichée dans le navigateur
        container.setMimeMappings(mappings);
        // When running in an IDE or with ./mvnw spring-boot:run, set location of the static web assets.
        setLocationForStaticAssets(container);
    }
    

    【讨论】:

      【解决方案3】:

      我终于找到并解决了这个问题(解决方案如下),它似乎与一些undertow元素有链接,默认情况下没有配置初始化japser。 JasperInitializer 从未初始化。 如果有人想解释我,欢迎他:)

      您必须在配置类中添加此代码。

      @Bean
      public TomcatContextCustomizer tomcatContextCustomizer() {
          return new TomcatContextCustomizer() {
              @Override
              public void customize(Context context) {
                  context.addServletContainerInitializer(new JasperInitializer(), null);
              }
          };
      }
      
      @Bean
      public TomcatEmbeddedServletContainerFactory tomcatContainerFactory() {
           TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
           factory.setTomcatContextCustomizers(Arrays.asList(new TomcatContextCustomizer[] { tomcatContextCustomizer() }));
           return factory;
      }
      

      另一个问题:我的 Spring Boot 应用程序中没有 xml 文件,除了一个: 是否可以通过 java/annotation 定义替换我用 WEB-INF/servletJSP-servlet.xml 构建的 servlet Web 应用程序上下文定义?

      【讨论】:

        猜你喜欢
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 2020-03-08
        • 2017-10-06
        • 2021-08-31
        • 1970-01-01
        • 1970-01-01
        • 2016-09-18
        相关资源
        最近更新 更多