如何从Spring Boot中提供 *.jsp 页面

huangapple 未分类评论45阅读模式
英文:

How to serve *.jsp from Springboot

问题

我正试图将一个遗留的 JSP 应用程序转换为托管在 Spring Boot 2.3.1 应用程序中。
我希望在引用 .jsp 扩展名的情况下提供 .jsp 文件。
我知道它们应该通过 DispactherServlet 进行处理以正确映射视图,但这并没有起作用。

我已经在 application.properties 中进行了以下设置:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

我还设置了一个控制器类,其中包含以下映射:

@GetMapping({"/", "/login"})
public String login(Model model) {
    return "login";
}

这使我能够成功解析对“/”或“/login”的引用,正如日志所示:

o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
...
org.apache.jasper.servlet.JspServlet     : Forwarding to [/WEB-INF/jsp/login.jsp]
...

但是,如果我尝试解析以 .jsp 结尾的任何内容,DispatcherServlet 将不会被调用。JspServlet 将直接被调用,而不会解析路径到 /WEB-INF/jsp 目录:

org.apache.jasper.servlet.JspServlet     : JspEngine --> /login.jsp
...
o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}
...
org.apache.jasper.servlet.JspServlet     : Forwarding to [/WEB-INF/jsp/error.jsp]
...

是否有一种方法可以配置 Spring Boot,以便我也可以解析 .jsp 文件?

这是 web.xml 文件。我已经尝试过带有 servlet 定义和不带有 servlet 定义的情况:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <display-name>MyApp</display-name>

    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
英文:

I am trying to convert a legacy JSP app to be hosted within a Springboot 2.3.1 app.
I would like to have the .jsp files served up when referenced with a .jsp extension.
I understand that they should go via the DispactherServlet to get the view mapped correctly, but this is not working.

I have setup the following in application.properties:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

I have also set up a controller class with the following mapping:

    @GetMapping({&quot;/&quot;, &quot;/login&quot;})
    public String login(Model model) {
      return &quot;login&quot;;
    }

This allows me to resolve references to either "/" or "/login" successfully as the logs show:

o.s.web.servlet.DispatcherServlet        : Initializing Servlet &#39;dispatcherServlet&#39;
o.s.web.servlet.DispatcherServlet        : Detected StandardServletMultipartResolver
o.s.web.servlet.DispatcherServlet        : enableLoggingRequestDetails=&#39;false&#39;: request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
o.s.web.servlet.DispatcherServlet        : Completed initialization in 18 ms
o.s.web.servlet.DispatcherServlet        : GET &quot;/&quot;, parameters={}
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to itree.m5cb.MainController#login(Model)
o.s.w.s.v.ContentNegotiatingViewResolver : Selected &#39;text/html&#39; given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
o.s.web.servlet.view.JstlView            : View name &#39;login&#39;, model {}
o.s.web.servlet.view.JstlView            : Forwarding to [/WEB-INF/jsp/login.jsp]
org.apache.jasper.servlet.JspServlet     : JspEngine --&gt; /WEB-INF/jsp/login.jsp
org.apache.jasper.servlet.JspServlet     :            ServletPath: /WEB-INF/jsp/login.jsp
org.apache.jasper.servlet.JspServlet     :               PathInfo: null
org.apache.jasper.servlet.JspServlet     :               RealPath: null
org.apache.jasper.servlet.JspServlet     :             RequestURI: /WEB-INF/jsp/login.jsp
org.apache.jasper.servlet.JspServlet     :            QueryString: null
o.s.web.servlet.DispatcherServlet        : Completed 200 OK

But if I try to resolve anything ending in .jsp, the DispatcherServlet is not called. The JspServlet is called directly without resolving the path to the /WEB-INF/jsp directory:

org.apache.jasper.servlet.JspServlet     : JspEngine --&gt; /login.jsp
org.apache.jasper.servlet.JspServlet     :            ServletPath: /login.jsp
org.apache.jasper.servlet.JspServlet     :               PathInfo: null
org.apache.jasper.servlet.JspServlet     :               RealPath: null
org.apache.jasper.servlet.JspServlet     :             RequestURI: /login.jsp
org.apache.jasper.servlet.JspServlet     :            QueryString: null
o.s.web.servlet.DispatcherServlet        : &quot;ERROR&quot; dispatch for GET &quot;/error&quot;, parameters={}
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
o.s.w.s.v.ContentNegotiatingViewResolver : Selected &#39;text/html&#39; given [text/html, text/html;q=0.8]
o.s.web.servlet.view.JstlView            : View name &#39;error&#39;, model {timestamp=Thu Jul 23 16:00:23 AEST 2020, status=404, error=Not Found, message=, path=/login.jsp}
o.s.web.servlet.view.JstlView            : Forwarding to [/WEB-INF/jsp/error.jsp]
org.apache.jasper.servlet.JspServlet     : JspEngine --&gt; /WEB-INF/jsp/error.jsp
org.apache.jasper.servlet.JspServlet     :            ServletPath: /WEB-INF/jsp/error.jsp
org.apache.jasper.servlet.JspServlet     :               PathInfo: null
org.apache.jasper.servlet.JspServlet     :               RealPath: null
org.apache.jasper.servlet.JspServlet     :             RequestURI: /WEB-INF/jsp/error.jsp
org.apache.jasper.servlet.JspServlet     :            QueryString: null
o.s.web.servlet.DispatcherServlet        : Exiting from &quot;ERROR&quot; dispatch, status 404

Is there a way to configure Springboot so I can also resolve .jsp files?

Here is the web.xml. I have tried with and without the servlet definition:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
         xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
         version=&quot;2.5&quot;&gt;
    &lt;display-name&gt;MyApp&lt;/display-name&gt;

    &lt;session-config&gt;
        &lt;session-timeout&gt;60&lt;/session-timeout&gt;
    &lt;/session-config&gt;

    &lt;welcome-file-list&gt;
        &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
        &lt;welcome-file&gt;login.jsp&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;

    &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
    &lt;/listener&gt;

    &lt;servlet&gt;
        &lt;servlet-name&gt;app&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
            &lt;param-value&gt;&lt;/param-value&gt;
        &lt;/init-param&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;

    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;app&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
&lt;/web-app&gt;

答案1

得分: 0

我认为问题在于当您提供类似 something:portno/login.jsp 的网址时,Spring Boot 无法将该网址与您的调度控制器方法匹配,而是将其视为直接提供 jsp 文件的请求,并因此尝试直接从静态文件目录中解析视图 而不添加前缀和后缀,因此,如果您的静态文件夹中有一个 login.jsp,这应该可以工作,但由于您想要返回一个动态 jsp,我认为您需要决定是否在网址中保留扩展名。通常情况下,容器会获取请求,将其视为需要由调度程序解析的网址,然后将其转发,然后调度程序 Servlet 将通过视图解析器解析视图,该解析器会添加前缀和后缀以解析视图。对于您来说,这种情况并没有发生,我认为这是因为容器将该网址视为不与任何端点匹配的网址,并且作为获取视图的请求。

尝试:

@GetMapping({"/", "/login","/login.jsp"})
public String login(Model model) {
  return "login";
}
英文:

I think the issue is that when you provide the url like something:portno/login.jsp then springboot does not match the url with your dispatcher controller method instead sees it as a request to serve the jsp file directly and hence try to resolve the view directly from your static file directory without the prefix and suffix added , so if you have a login.jsp in your static folder this should work but since you want a dynamic jsp to be returned I think you need to decide on whether to keep the extension in your url or not. Usually what happends is that the container gets the request sees it as a url that needs to be resolved by the dispatcher forwards it and then the dispatcher servlet will resolve the view through a view resolver that adds the prefix and the suffix to resolve the view. For you this is not happening and I think it's because the container sees the url as not matching any endpoint and as a request to fetch the view.

Try :

@GetMapping({&quot;/&quot;, &quot;/login&quot;,&quot;/login.jsp&quot;})
public String login(Model model) {
  return &quot;login&quot;;
}

huangapple
  • 本文由 发表于 2020年7月23日 14:23:21
  • 转载请务必保留本文链接:https://java.coder-hub.com/63048102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定