【问题标题】:How to get e.g. registration.jsp view appear correctly in browser?如何获得registration.jsp 视图在浏览器中正确显示?
【发布时间】:2019-05-04 13:31:19
【问题描述】:

我正在关注本教程以获取 Spring Boot Web 应用程序中的登录和注册功能:https://hellokoding.com/registration-and-login-example-with-spring-security-spring-boot-spring-data-jpa-hsql-jsp/

我无法正确显示视图 - 而不是例如在registration.jsp 视图页面中,我在屏幕上看到以下字符串,它由我的GET 注册控制器方法返回:https://ibb.co/XXXtdSZ

我是 Java、Spring Boot 的新手,甚至是 JSP 的新手。 我正在使用 IntelliJ 社区版 2017.3.5,并且收到不支持 .jsp 文件的通知。在此之后,https://stackoverflow.com/a/36572413/11451547,我转到了已识别文件类型下的设置 - 文件类型 - HTML,并添加了一个新的注册模式 .*jsp,覆盖了 JSP 文件的现有注册模式(仅限语法突出显示)。 .jsp 不受支持的消息消失了,但我仍然看不到正确的视图页面。

在我的registration.jsp 中,我看到很多“命名空间,例如'form' is not bound”通知。在我的 login.jsp 中,它具有相同的显示问题(在屏幕上我看到字符串 'login' 而不是登录视图),我有一个通知 - 'Namespace 'c' is not bound'。

您能否提供一些关于如何正确显示视图的想法?

谢谢!

这是我的控制器的相应部分(也许我将@ModelAttribute 添加到 GET 注册两次是错误的,这是我对教程代码所做的修改的一部分,但例如我的 GET 登录控制器方法与教程):

@GetMapping("/registration")
    public String registration(Model model) {
        model.addAttribute("userForm", new User());

        return "registration";
    }

@PostMapping("/registration")
    public String registration(@ModelAttribute("userForm") User userForm, @ModelAttribute("roleId") Long roleId, BindingResult bindingResult) { //diff w tutorial
        userValidator.validate(userForm, bindingResult);
//        userValidator.validate(roleId, bindingResult);

        if (bindingResult.hasErrors()) {
            return "registration";
        }
        userService.saveUser(userForm, roleId);

        securityService.autoLogin(userForm.getUserName(), userForm.getPasswordConfirm());

        return "redirect:/welcome";
    }

    @GetMapping("/login")
    public String login(Model model, String error, String logout) {
        if (error != null)
            model.addAttribute("error", "Your username and/or password is invalid.");

        if (logout != null)
            model.addAttribute("message", "You have been logged out successfully.");

        return "login";
    }

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

我的registration.jsp:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<c:set var="contextPath" value="${pageContext.request.contextPath}">

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="utf-8">
      <title>Create an account</title>

      <link href="${contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
      <link href="${contextPath}/resources/css/common.css" rel="stylesheet">
  </head>

  <body>
    <div class="container">
        <form:form method="POST" modelAttribute="userForm" modelAttribute="roleId" class="form-signin">
            <h2 class="form-signin-heading">Create Your Account</h2>
            <spring:bind path="userName">
                <div class="form-group ${status.error ? 'has-error' : ''}">
                    <form:input type="text" path="userName" class="form-control" placeholder="Enter your username"
                                autofocus="true"></form:input>
                    <form:errors path="userName"></form:errors>
                </div>
            </spring:bind>

            <spring:bind path="password">
                <div class="form-group ${status.error ? 'has-error' : ''}">
                    <form:input type="password" path="password" class="form-control" placeholder="Enter your password"></form:input>
                    <form:errors path="password"></form:errors>
                </div>
            </spring:bind>

            <spring:bind path="passwordConfirm">
                <div class="form-group ${status.error ? 'has-error' : ''}">
                    <form:input type="password" path="passwordConfirm" class="form-control"
                                placeholder="Confirm your password"></form:input>
                    <form:errors path="passwordConfirm"></form:errors>
                </div>
            </spring:bind>

            <button class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
        </form:form>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="${contextPath}/resources/js/bootstrap.min.js"></script>
  </body>
</html>

我的 login.jsp:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<c:set var="contextPath" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="utf-8">
      <title>Log in with your account details</title>

      <link href="${contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
      <link href="${contextPath}/resources/css/common.css" rel="stylesheet">
  </head>

  <body>
    <div class="container">
      <form method="POST" action="${contextPath}/login" class="form-signin">
        <h2 class="form-heading">Log In</h2>
        <div class="form-group ${error != null ? 'has-error' : ''}">
            <span>${message}</span>
            <input name="userName" type="text" class="form-control" placeholder="Enter your username"
                   autofocus="true"/>
            <input name="password" type="password" class="form-control" placeholder="Enter your password"/>
            <span>${error}</span>
            <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

            <button class="btn btn-lg btn-primary btn-block" type="submit">Log In</button>
            <h4 class="text-center"><a href="${contextPath}/registration">Create an Account</a></h4>
        </div>
      </form>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="${contextPath}/resources/js/bootstrap.min.js"></script>
  </body>
</html>

我的welcome.jsp:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:set var="contextPath" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Welcome</title>

    <link href="${contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
  <div class="container">
    <c:if test="${pageContext.request.userPrincipal.name != null}">
        <form id="logoutForm" method="POST" action="${contextPath}/logout">
            <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
        </form>

        <h2>Welcome ${pageContext.request.userPrincipal.name} | <a onclick="document.forms['logoutForm'].submit()">Logout</a></h2>
    </c:if>
  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="${contextPath}/resources/js/bootstrap.min.js"></script>
</body>
</html>

我的 application.yml 文件的相应部分:

spring:
  main:
    banner-mode: 'off'
  datasource:
    url: jdbc:mysql://localhost:3306/inspire_me_db?useSSL=false
    username: springuser
    password: ThePassword
  jpa:
    hibernate:
      ddl-auto: update
  flyway:
    baselineOnMigrate: true
  mvc:
    view:
      prefix: /
      suffix: .jsp
  messages:
    basename: validation

我的 pom.xml 的相应部分:

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
</dependency>

我的包结构:

https://ibb.co/Qr2dmNr

【问题讨论】:

  • 我使用 Spring MVC 但不是 Spring Boot。但它看起来肯定没有使用您的 JSP 视图解析器。因此,不会将返回的“注册”字符串转换为服务/registration.jsp
  • 非常感谢您的回复。我阅读了很多有关视图解析器的信息,但仍在尝试解决此问题。

标签: spring-boot spring-mvc jsp intellij-idea view


【解决方案1】:

您可以尝试如下注册您的 jsp 视图解析器吗:

@Configuration
@EnableWebMvc
@ComponentScan
public class MvcConfiguration implements WebMvcConfigurer
{
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/view/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        registry.viewResolver(resolver);
    }
}

或者您也可以通过在application.properties 或 yml 中提供以下内容,将 jsp 指定为 Spring-boot 中的视图解析器:

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

验证提供的前缀是否指向正确的 jsp 文件所在的目录。通常 jsp 文件放在 src/main/WEB_INF/view 下。

此外,由于您使用的是 spring-boot ,如果您没有适当的依赖项来编译 jsp ,请将以下内容添加到 pom 中:

<!-- JSTL -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
<!-- To compile JSP files -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

【讨论】:

  • 谢谢。我试过这个和它的变体。现在我正在使用 MvcConfiguration (我的类实现了 WebMvcConfigurer,因为 WebMvcConfigurerAdapter 已被弃用)。我将前缀映射更改为resolver.setPrefix("webapp/resources/WEB-INF/view/") 以反映此结构:ibb.co/9qB9bh6。我得到的错误:'出现意外错误(类型 = 内部服务器错误,状态 = 500)'uriTemplate' 不能为空'。它似乎与 REST 方法有关。我在同一个控制器中有 REST 方法,但用 @ResponseBody 注释它们并将控制器类注释更改为 @Controller。
  • 谢谢,我已经更新了答案(现在正在实现 WebMvcCinfiger)。只需尝试给出 resolver.setPrefix("/WEB-INF/view/") ,并将 WEB-INF 保留在 webapp 下而不是下资源。即'src/main/webapp/WEB-INF'
  • 不起作用 :( 我希望在这个周末解决它,并告诉你如何解决。
  • 尝试启用 spring-boot 跟踪日志以了解实际问题所在。也许jsp文件没有正确编译。
  • 视图名称之前的路径的 RequestMapping(我从以前创建的 REST 端点获得)未正确映射。我们更密切地遵循初始教程(特别是在包结构方面)并将视图移动到它们自己的控制器(将 REST 端点留在初始控制器中)。这解决了这个问题。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
相关资源
最近更新 更多