如何在Spring MVC的同一控制器中从不同JSP页面访问表单中的值?

huangapple go评论78阅读模式
英文:

How do I access values from forms on different JSP pages in the same controller in Spring MVC?

问题

我正在尝试制作一个图书管理项目,在home.jsp页面上有三个按钮。每个按钮都会重定向到一个单独的页面,而且每个页面都有一个表单。我有一个Controller类,其中包含三个方法,用于处理来自这些页面中的每个表单提交。但是,当我尝试在任何表单的JSP页面中使用@ModelAttribute时,我无法获取添加到模型中的值。

以下是home.jsp的部分代码:

<body>
  <div class="container">
    <div>
      <h1>Spring Boot Web JSP Example</h1>
      <h2>Name: ${book.name}</h2>
      <h2>Author: ${book.author}</h2>
      <h2>ISBN: ${book.isbn}</h2>
    </div>
  </div>

  <form:form method="POST" action="/get" modelAttribute="newBook">
    <!-- 表单内容 -->
  </form:form>
  <a href="../add.jsp"><button type="submit" class="btn btn-primary">Add Book</button></a>
  <a href="../update.jsp"><button type="submit" class="btn btn-primary">Update Book</button></a>
</body>

这是控制器类的代码:

@Controller
public class MainController {
    // 控制器方法

    @PostMapping(value = "/get")
    public String change(@RequestParam("author") String author, Model model,
                         @ModelAttribute("newBook")Book book) {
        // 处理表单提交
    }

    @RequestMapping(value = "/add")
    public String addBook(@RequestParam("author") String author, @RequestParam("isbn") int isbn, Model model,
                          @ModelAttribute("addBook") Book book){
        // 处理添加表单提交
    }

    @RequestMapping( value = "/update")
    public String updateBook(@RequestParam("author") String author, @RequestParam("isbn") int isbn, Model model,
                             @ModelAttribute("updateBook") Book book){
        // 处理更新表单提交
    }
}

还有另外两个JSP页面:add.jsp 和 update.jsp(这里省略了内容,只展示了modelAttribute部分)。

问题可能是在这两个JSP页面中使用modelAttribute="addBook"modelAttribute="third" 时出现了错误。然而,这些值在home.jsp页面中是可用的。

请注意,上述代码中的 modelAttribute 值必须与控制器方法中 @ModelAttribute 注解的值相匹配。如果仍然遇到问题,可能需要检查导入的包是否正确以及IDE是否正确地识别了项目的结构和配置。

英文:

I am trying to make a Book Management project where I have three buttons on the home.jsp page. Each button redirects to a separate page and each of these pages has a form. I have one Controller class that has three methods to handle each form submissions from each of these pages but when I try to use @ModelAttribute in the JSP page for any form, I am unable to get the value that I add to the Model.

Here is the home.jsp:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;body&gt;

  &lt;div class=&quot;container&quot;&gt;

    &lt;div&gt;
      &lt;h1&gt;Spring Boot Web JSP Example&lt;/h1&gt;
      &lt;h2&gt;Name: ${book.name}&lt;/h2&gt;
      &lt;h2&gt;Author: ${book.author}&lt;/h2&gt;
      &lt;h2&gt;ISBN: ${book.isbn}&lt;/h2&gt;
    &lt;/div&gt;

  &lt;/div&gt;

  &lt;form:form method=&quot;POST&quot; action=&quot;/get&quot; modelAttribute=&quot;newBook&quot;&gt;
    &lt;div class=&quot;form-group&quot;&gt;
      &lt;label for=&quot;authorInput&quot;&gt;Author&lt;/label&gt;
      &lt;form:input path=&quot;author&quot; cssClass=&quot;form-control&quot; id=&quot;authorInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
      &lt;label for=&quot;dateInput&quot;&gt;Date&lt;/label&gt;
      &lt;form:input path=&quot;date&quot; cssClass=&quot;form-control&quot; id=&quot;dateInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Get Book&lt;/button&gt;
  &lt;/form:form&gt;
  &lt;a href=&quot;../add.jsp&quot;&gt;&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Add Book&lt;/button&gt;&lt;/a&gt;
  &lt;a href=&quot;../update.jsp&quot;&gt;&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Update Book&lt;/button&gt;&lt;/a&gt;
&lt;/body&gt;

<!-- end snippet -->

Here is the controller class:

@Controller
public class MainController {

@GetMapping(value = &quot;/&quot;)
public String welcome(Map&lt;String, Object&gt; model) {
    model.put(&quot;newBook&quot;, new Book());
    model.put(&quot;updateBook&quot;, new Book());
    model.put(&quot;addBook&quot;,new Book());
    return &quot;home&quot;;
}

@PostMapping(value = &quot;/get&quot;)
public String change(@RequestParam(&quot;author&quot;) String author, Model model,
                     @ModelAttribute(&quot;newBook&quot;)Book book) {
    System.out.println(author);
    Book b = BookDao.getBook(book.getAuthor(), book.getDate());
    if(b == null){
        return &quot;home&quot;;
    }
    model.addAttribute(&quot;book&quot;, b);
    model.addAttribute(&quot;newBook&quot;, new Book());
    return &quot;home&quot;;
}
@RequestMapping(value = &quot;/add&quot;)
public String addBook(@RequestParam(&quot;author&quot;) String author, @RequestParam(&quot;isbn&quot;) int isbn, Model model,
                      @ModelAttribute(&quot;addBook&quot;) Book book){
    System.out.println(&quot;Author: &quot;+author + &quot; ISBN: &quot;+isbn);
    model.addAttribute(&quot;addBook&quot;, new Book());
    Book b= new Book(book.getName(), author,isbn, book.getDate());
    model.addAttribute(&quot;add&quot;, book);
    boolean result = BookDao.addBook(b);
    if(result)
        return &quot;home&quot;;
    else
        return &quot;error&quot;;
}
@RequestMapping( value = &quot;/update&quot;)
public String updateBook(@RequestParam(&quot;author&quot;) String author, @RequestParam(&quot;isbn&quot;) int isbn, Model model,
                         @ModelAttribute(&quot;updateBook&quot;) Book book){
    System.out.println(&quot;Author: &quot;+author + &quot; ISBN: &quot;+isbn);
    Book b= new Book(book.getName(), author,isbn, book.getDate());
    model.addAttribute(&quot;updateBook&quot;, new Book());
    model.addAttribute(&quot;update&quot;,b);
    BookDao.updateBook(isbn, b);
    return &quot;home&quot;;
}

}

And here are the other two jsp pages:
Add.jsp:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;body&gt;

&lt;h1&gt;Add a Book&lt;/h1&gt;

&lt;form:form method=&quot;POST&quot; action=&quot;/add&quot; modelAttribute=&quot;addBook&quot;&gt;
        &lt;div class=&quot;form-group&quot;&gt;
            &lt;label for=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
            &lt;form:input path=&quot;name&quot; cssClass=&quot;form-control&quot; id=&quot;nameInput&quot;&gt;&lt;/form:input&gt;
        &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;authorInput&quot;&gt;Author&lt;/label&gt;
        &lt;form:input path=&quot;author&quot; cssClass=&quot;form-control&quot; id=&quot;authorInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;isbnInput&quot;&gt;ISBN&lt;/label&gt;
        &lt;form:input path=&quot;isbn&quot; cssClass=&quot;form-control&quot; id=&quot;isbnInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;dateInput&quot;&gt;Date&lt;/label&gt;
        &lt;form:input path=&quot;date&quot; cssClass=&quot;form-control&quot; id=&quot;dateInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;

    &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Add&lt;/button&gt;
&lt;/form:form&gt;


&lt;/body&gt;

<!-- end snippet -->

Update Book JSP Page:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;body&gt;
&lt;form:form method=&quot;POST&quot; action=&quot;/update&quot; modelAttribute=&quot;third&quot;&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;authorInput&quot;&gt;ISBN&lt;/label&gt;
        &lt;form:input path=&quot;isbn&quot; cssClass=&quot;form-control&quot; id=&quot;authorInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;nameInput&quot;&gt;Name&lt;/label&gt;
        &lt;form:input path=&quot;name&quot; cssClass=&quot;form-control&quot; id=&quot;nameInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;authorInput&quot;&gt;Author&lt;/label&gt;
        &lt;form:input path=&quot;author&quot; cssClass=&quot;form-control&quot; id=&quot;authorInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;div class=&quot;form-group&quot;&gt;
        &lt;label for=&quot;dateInput&quot;&gt;Date&lt;/label&gt;
        &lt;form:input path=&quot;date&quot; cssClass=&quot;form-control&quot; id=&quot;dateInput&quot;&gt;&lt;/form:input&gt;
    &lt;/div&gt;
    &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Update Book&lt;/button&gt;
&lt;/form:form&gt;
&lt;/body&gt;

<!-- end snippet -->

The problem is that the lines modelAttribute="addBook" and modelAttribute="third" in the add.jsp page and update.jsp page throw an error. The IDE says "Cannot resolve symbol 'addBook/third'". Those values are available in the home.jsp page though.

答案1

得分: 0

自从我找到了答案,我将它发布出来,以防其他人也遇到了同样的问题。
为了访问另一个JSP页面上的表单,在MVC设计中,我们不能直接重定向到页面。
为了实现这一点,我们需要为每个JSP表单创建一个@GetMapping注释方法,对应于@PostMapping注释,然后首先重定向到@GetMapping方法,而@GetMapping方法将重定向到JSP页面。应该按照以下方式完成:

控制器类:

@Controller
public class MainController {

    @GetMapping(value = "/")
    public String welcome(Map<String, Object> model) {
        model.put("newBook", new Book());
        return "home";
    }

    @PostMapping(value = "/get")
    public String change(@RequestParam("author") String author, Model model,
                         @ModelAttribute("newBook") Book book) {
        System.out.println(author);
        Book b = BookDao.getBook(book.getAuthor(), book.getDate());
        if(b == null){
            return "home";
        }
        model.addAttribute("book", b);
        model.addAttribute("newBook", new Book());
        return "home";
    }
    
    @GetMapping("/add")
    public String show(Model model) {
        model.addAttribute("addBook", new Book());
        return "add";
    }
    
    @PostMapping(value = "/add")
    public String addBook(@RequestParam("author") String author, @RequestParam("isbn") int isbn, Model model,
                          @ModelAttribute("addBook") Book book){
        System.out.println("Author: "+author + " ISBN: "+isbn);
        model.addAttribute("addBook", new Book());
        Book b= new Book(book.getName(), author,isbn, book.getDate());
        model.addAttribute("add", book);
        boolean result = BookDao.addBook(b);
        if(result)
            return "home";
        else
            return "error";
    }
    
    @GetMapping("/update")
    public String showUpdate(Model model) {
        model.addAttribute("updateBook", new Book());
        return "update";
    }
    
    @PostMapping(value = "/update")
    public String updateBook(@RequestParam("author") String author, @RequestParam("isbn") int isbn, Model model,
                             @ModelAttribute("updateBook") Book book){
        System.out.println("Author: "+author + " ISBN: "+isbn);
        Book b= new Book(book.getName(), author,isbn, book.getDate());
        model.addAttribute("updateBook", new Book());
        model.addAttribute("update",b);
        BookDao.updateBook(isbn, b);
        return "home";
    }
}

Home.jsp页面的代码如下:

<form:form method="POST" action="/get" modelAttribute="newBook">
    <div class="form-group">
        <label for="authorInput">Author</label>
        <form:input path="author" cssClass="form-control" id="authorInput"></form:input>
    </div>
    <div class="form-group">
        <label for="dateInput">Date</label>
        <form:input path="date" cssClass="form-control" id="dateInput"></form:input>
    </div>
    <button type="submit" class="btn btn-primary">Get Book</button>
</form:form>
<a  href ="/add"><button type="submit" class="btn btn-primary">Add Book</button></a>
<a  href ="/update"><button type="submit" class="btn btn-primary">Update Book</button></a>
</body>

因此,href属性映射到@GetMapping方法以获取ModelAttributes。其他JSP页面保持不变。

另外,我建议的另一种良好实践是使用Service层/包执行所有操作。因此,不要在控制器中执行CRUD操作,而是将这些任务委托给Service层,该层再与DAO层进行交互。

英文:

Since I found the answer, I will post it just in case somebody else gets stuck with it.
In order to access the forms on another JSP page, we can't just directly redirect to the page in an MVC design.
In order to do so, we need to create a @GetMapping annotation method for each of those JSP forms @PostMapping annotations and then redirect to the @GetMapping methods first and the @GetMapping will redirect to the JSP page. This is how it should be done:

Controller Class:

@Controller
public class MainController {

@GetMapping(value = &quot;/&quot;)
public String welcome(Map&lt;String, Object&gt; model) {
model.put(&quot;newBook&quot;, new Book());
return &quot;home&quot;;
}
@PostMapping(value = &quot;/get&quot;)
public String change(@RequestParam(&quot;author&quot;) String author, Model model,
@ModelAttribute(&quot;newBook&quot;)Book book) {
System.out.println(author);
Book b = BookDao.getBook(book.getAuthor(), book.getDate());
if(b == null){
return &quot;home&quot;;
}
model.addAttribute(&quot;book&quot;, b);
model.addAttribute(&quot;newBook&quot;, new Book());
return &quot;home&quot;;
}
@GetMapping(&quot;/add&quot;)
public String show(Model model) {
model.addAttribute(&quot;addBook&quot;, new Book());
return &quot;add&quot;;
}
@PostMapping(value = &quot;/add&quot;)
public String addBook(@RequestParam(&quot;author&quot;) String author, @RequestParam(&quot;isbn&quot;) int isbn, Model model,
@ModelAttribute(&quot;addBook&quot;) Book book){
System.out.println(&quot;Author: &quot;+author + &quot; ISBN: &quot;+isbn);
model.addAttribute(&quot;addBook&quot;, new Book());
Book b= new Book(book.getName(), author,isbn, book.getDate());
model.addAttribute(&quot;add&quot;, book);
boolean result = BookDao.addBook(b);
if(result)
return &quot;home&quot;;
else
return &quot;error&quot;;
}
@GetMapping(&quot;/update&quot;)
public String showUpdate(Model model) {
model.addAttribute(&quot;updateBook&quot;, new Book());
return &quot;update&quot;;
}
@PostMapping( value = &quot;/update&quot;)
public String updateBook(@RequestParam(&quot;author&quot;) String author, @RequestParam(&quot;isbn&quot;) int isbn, Model model,
@ModelAttribute(&quot;updateBook&quot;) Book book){
System.out.println(&quot;Author: &quot;+author + &quot; ISBN: &quot;+isbn);
Book b= new Book(book.getName(), author,isbn, book.getDate());
model.addAttribute(&quot;updateBook&quot;, new Book());
model.addAttribute(&quot;update&quot;,b);
BookDao.updateBook(isbn, b);
return &quot;home&quot;;
}

And the JSP page for Home.jsp page should be as follows:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;form:form method=&quot;POST&quot; action=&quot;/get&quot; modelAttribute=&quot;newBook&quot;&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;authorInput&quot;&gt;Author&lt;/label&gt;
&lt;form:input path=&quot;author&quot; cssClass=&quot;form-control&quot; id=&quot;authorInput&quot;&gt;&lt;/form:input&gt;
&lt;/div&gt;
&lt;div class=&quot;form-group&quot;&gt;
&lt;label for=&quot;dateInput&quot;&gt;Date&lt;/label&gt;
&lt;form:input path=&quot;date&quot; cssClass=&quot;form-control&quot; id=&quot;dateInput&quot;&gt;&lt;/form:input&gt;
&lt;/div&gt;
&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Get Book&lt;/button&gt;
&lt;/form:form&gt;
&lt;a  href =&quot;/add&quot;&gt;&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Add Book&lt;/button&gt;&lt;/a&gt;
&lt;a  href =&quot;/update&quot;&gt;&lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Update Book&lt;/button&gt;&lt;/a&gt;
&lt;/body&gt;

<!-- end snippet -->

So the href maps to the @GetMapping method to get the ModelAttributes. The other JSP pages are fine as it is.

Also, another good practice I might suggest is to Use a Service layer/package to perform all the operations. So instead of performing it in the Controller, we delegate tasks like the CRUD operations to the Service layer which in turn interacts with the DAO layer.

huangapple
  • 本文由 发表于 2020年9月12日 07:49:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63855561.html
匿名

发表评论

匿名网友

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

确定