【问题标题】:Populate form using values getting from Spring Controller使用从 Spring Controller 获取的值填充表单
【发布时间】:2017-01-18 06:49:50
【问题描述】:

我只是在 Spring MVC 中创建一个 CRUD 应用程序。我想编辑学生详细信息。我创建了一种用于添加学生的表格。如何使用相同的表单来填充学生详细信息以进行编辑?

控制器

@RequestMapping(value="/add", method = RequestMethod.GET)
public String addStudent(@RequestParam("studentName") String name,@RequestParam("studentId") String studId){
    System.out.println("Student Id : "+ studId);
    System.out.println("Student "+name+" added");
    list.add(name);
    return "redirect:get";
}

@RequestMapping(value="/edit/${index}", method = RequestMethod.GET)
public String editStudent(@PathVariable("index") int index, Model model){
    System.out.println("Edit Student with Index " + index);
    model.addAttribute("studentId",index);
    model.addAttribute("studentName",list.get(index));
    return "student";
}

表格

<c:url value="/students/add" var="addStudentAction"></c:url>
<form action="${addStudentAction}" method="get">
    <input type="hidden" name="studentId">
    <input type="text" name="studentName"></input>
    <input type="submit" name="submit" value="Add Student" />
</form>

我想在editStudent方法的模型中设置的表单字段中设置studentId和studentName。

【问题讨论】:

标签: java spring spring-mvc


【解决方案1】:

您要问的是一个非常基本的问题,理想情况下应该从教程和文档中学习。

以下是步骤的简短列表:

  • 使用Spring tags for rendering form&lt;form:form&gt;&lt;form:input&gt;等)
  • 创建一个表示表单值的对象并将其从控制器导出到视图
  • 将此对象作为处理表单提交的控制器方法中的参数

【讨论】:

  • 使用弹簧形式必须在modelAttribute中指定模型。我不想创建我的自定义模型类。
  • 在这种情况下,您必须手动填写value 属性:&lt;input type="text" name="studentName" value="&lt;c:out value='${studentName}' /&gt;" /&gt;
【解决方案2】:

我认为您需要两个页面和一个控制器。
1. 列出所有学生:index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h3>Student List</h3>
    <div>
        <p>
        <ul>
            <c:forEach items="${requestScope.students}" var="student">
                <li>
                    <c:out value="${student.id}"></c:out> |
                    <c:out value="${student.name}"></c:out> |
                    <a href="${pageContext.request.contextPath}/student/<c:out value='${student.id}'/>">edit</a>
                </li>
            </c:forEach>
        </ul>
        </p>
        <p><a href="${pageContext.request.contextPath}/student/new">Create Student</a></p>
    </div>
    </body>
    </html>
  1. 用于显示或编辑或创建学生:edit.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <c:if test="${student.id == null}">
        <h3>Student Create</h3>
    </c:if>
    <c:if test="${student.id != null}">
        <h3>Student Edit</h3>
    </c:if>
    <div>
        <form action="${pageContext.request.contextPath}/student/" method="post">
            <input type="hidden" name="id" value="<c:out value='${student.id}'/>"/>
            <p>Student Name: <input type="text" name="name" value="<c:out value='${student.name}'/>"></p>
            <p><input type="submit" value="submit"/></p>
        </form>
    </div>
    </body>
    </html>
    
  2. 学生管理员

    package cn.kolbe.student;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.servlet.ModelAndView;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    @Controller
    @RequestMapping("/student")
    public class StudentController {
        @GetMapping("")
        public ModelAndView index() {
            List<Student> students = new ArrayList<Student>();
            studentCache.keySet().forEach(id -> {
                students.add(studentCache.get(id));
            });
            return new ModelAndView("student/index", "students", students);
        }
        @GetMapping("/{id}")
        public ModelAndView show(@PathVariable("id")String id) {
            if (id.equals("new")) {
                return new ModelAndView("student/edit");
            } else {
                Student student = studentCache.get(Long.valueOf(id));
                return new ModelAndView("student/edit", "student", student);
            }
        }
        @PostMapping("")
        public String createOrEdit(String name, Long id) {
            Student student;
            if (id == null) {
                id = cacheId++;
                student = new Student(id, name);
                studentCache.put(id, student);
            } else {
                student = studentCache.get(id);
                student.setName(name);
            }
            return "redirect:/student";
        }
        private static ConcurrentHashMap<Long, Student> studentCache = new ConcurrentHashMap<>();
        private static Long cacheId = 1L;
    }
    

【讨论】:

  • 我认为使用 scriptlets 是一种不好的风格,我宁愿使用&lt;c:forEach&gt;
  • 另一个可能与并发相关的问题:因为控制器是一个 bean,并且默认情况下它具有singleton 范围,那么可能有 2 个或更多线程将在控制器上执行方法。考虑使用ConcurrentHashMap 而不是HashMap
  • 另一个可能的问题:在 HTML 代码中使用${student.id} 容易受到 XSS 攻击。考虑使用&lt;c:out&gt;,它会在打印前转义数据。
  • 嗨 Slava Semushin,我同意你的看法。并且已经编辑了代码。谢谢!
  • 还有一个问题是将Long 替换为AtomicLong (stackoverflow.com/questions/35546956/…)。
【解决方案3】:

不要使用 html &lt;form&gt; 标签。

使用 Spring 标记呈现 &lt;form:form&gt; ,&lt;form:input&gt; 的表单

【讨论】:

  • 欢迎来到 Stack Overflow!下次,请不要在答案中使用不必要的格式,例如过度使用大写字母和/或粗体字母。仅突出显示您最重要的一句话或要点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-26
  • 1970-01-01
  • 2013-01-10
  • 2022-01-19
  • 2019-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多