【问题标题】:Spring Boot - Correct way to map both JSP and REST URI to be handled in controller?Spring Boot - 映射 JSP 和 REST URI 以在控制器中处理的正确方法?
【发布时间】:2018-03-13 07:29:19
【问题描述】:

我在使用 Spring boot 1.5.2 时遇到问题,我还添加了 JSP 的所有依赖项,以便它可以从 Web 应用程序 (war) 文件返回。

application.properties

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

带有 JSP 依赖项的 pom.xml

<!-- JSTL for JSP -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
    </dependency>

    <!-- Need this to compile JSP -->
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>

    <!-- Need this to compile JSP,
    tomcat-embed-jasper version is not working, no idea why -->
    <dependency>
        <groupId>org.eclipse.jdt.core.compiler</groupId>
        <artifactId>ecj</artifactId>
        <version>4.6.1</version>
        <scope>provided</scope>
    </dependency>       

我有一个像这样的简单控制器

@Controller
public class ClassController {
    @RequestMapping("/**")
    public String handle(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       // This one can handle any rest URIs, e.g: localhost:8080/application/abc, localhost:8080/application/abc/12/asdasd/3123,...
    }
}

但是,我无法从 localhost:8080/application/index.jsp 返回 index.jsp,因为它不会调用方法句柄,而是返回

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Mon Oct 02 10:20:39 CEST 2017
There was an unexpected error (type=Not Found, status=404).

什么是正确的配置,所以我可以使用 .jsp(例如:http://localhost:8080/application/index.jsp)将请求定向到 jsp 文件(WEB-INF/jsp/index.jsp),并将 REST uri(http://localhost:8080/application/132/21321312/324)定向到句柄方法?

【问题讨论】:

  • 控制器方法中返回什么?要查看页面,您应该只返回字符串“index”。还要粘贴您的 servlet 配置,因为不清楚您为 DispatcherServlet 定义了什么映射(上下文路径/servlet 路径)
  • 我只是在 handle() 方法中返回 "" 。我没有 servlet 配置?因为我正在使用 Spring Boot。
  • 尝试返回“application/index”并在浏览器中使用http://localhost:8080/application/index.jsp
  • 我在handle()方法中添加了return并尝试了uri到jsp文件,但仍然返回404 not found。
  • 好的,我几个小时后回来,我现在在上班

标签: java spring jsp spring-mvc spring-boot


【解决方案1】:

我通过使用 servlet 过滤器将包含 .jsp 的请求转发到 /WEB-INF/jsp 中的相应文件来解决了这个问题。其他请求将转到控制器内部的 handle() 方法。

 @WebFilter(urlPatterns = "/*")
public class SecoreFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (!request.getRequestURI().endsWith(".jsp")) {
            chain.doFilter(req, res);
        } else {
            String jspFile = new File(request.getRequestURI()).getName();
            // e.g: /application/3223/234234/2342323/browse.jsp
            String uri = request.getRequestURI();
            // extract the jsp file from uri
            uri = uri.substring(0, uri.length() - jspFile.length());
            RequestDispatcher dispatcher = req.getServletContext()
                    .getRequestDispatcher("/WEB-INF/jsp/" + jspFile);
            req.setAttribute("uri", uri);
            dispatcher.forward(req, response);
            // chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }

}

【讨论】:

    【解决方案2】:

    我根据您的描述重新构建了您的项目,发现了两个问题。

    • tomcat-embed-jasper需要是编译时依赖,不需要Eclipse编译器
    • 在控制器 (ClassController) 中,您必须返回视图的名称,在您的情况下为 index。

    您可以在这里找到一个工作示例:https://github.com/springuni/springuni-stackoverflow/tree/master/question-46521912

    它的作用是将任何给定的请求 (/application/132/21321312/324) 重定向到 index.jsp。在 JSP 中,请求的路径被写入输出,以证明重定向实际上来自控制器。

    让我知道它是否对你有用!

    干杯, 拉斯洛

    【讨论】:

    • 感谢 László 的帮助,但它似乎比您构建的更复杂。我想要的是:我可以连接到 URI(1 使用 JSP:localhost:8080/application/index.jsp)和 1 使用随机 REST URI(与 index.jsp 没有任何关系,例如:localhost: 8080/应用程序/12/3123)。尝试像 index.jsp 一样思考,它将在 html 页面中返回 Hello László,而对于 REST URI handle(),它将只是字符串中 1 + 2 = 3 的结果。
    • 好的,现在我更了解您想要实现的目标了。如果要直接访问 JSP,则必须将其放在 src/main/webapp/WEB-INF 之外。我添加了index2.jsp 作为示例。虽然这种方法会破坏 MVC 范式,所以我不推荐。另一种方法是定义单独的控制器方法来处理 JSP 和处理其他请求。在修改后的示例中,我添加了方法 index() 来执行前者,并为您上面的示例添加了更改方法 handle() 来执行后者。
    • 不好意思问这个问题,"@RequestMapping("/application/index.jsp")" 你测试了吗?因为我之前的情况下无法去处理这个请求的方法,所以我需要问一下。 “@RequestMapping("/application/{arg1}/{arg2}")” 也不是我想要的,1 + 2 = 3 只是示例,这里我想要一个随机 URI(例如:/application/213213/ 213asdasd/2132132132/1321321) 来处理。
    • 我应该知道,它不会那样工作,对此感到抱歉。我做了一些重构。路径 /application/index.jsp 直接由 Tomcat 提供服务,地址为 src/main/webapp/application/index.jsp,正如我之前提到的,此解决方案打破了 MVC 模式。路径/application/index.do 由控制器方法index() 提供服务,然后将请求重新路由到JSP src/main/webapp/WEB-INF/jsp/index.jsp。这是标准的 Spring MVC 方式。路径 /application/** 现在由控制器方法 handle() 提供服务,您可以使用任何您想要的 url 后缀。
    • 虽然,我无法测试您的项目,但感谢您的努力。
    猜你喜欢
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多