【问题标题】:How to validate JSP with Servlet and keep input data?如何使用 Servlet 验证 JSP 并保留输入数据?
【发布时间】:2018-06-12 02:49:40
【问题描述】:

我需要一些帮助来将一个 JSP 和两个 Java Servlet 绑定在一起。我有以下内容:

在 JSP 上:

  • 前两个带有 onchange="submit()" 的单选按钮
  • 一个 div 容器,仅当其中一个单选按钮处于活动状态时才会出现(包含接下来的两个)
  • 一些下拉菜单,根据单选按钮的选择填充
  • 一些输入字段

两个 Servlet:

  • 用于填充下拉菜单
  • 第二个用于验证其他所有内容并在成功的情况下填充数据库/重定向到另一个页面,...

人口运行良好,数据库部分也运行良好。

不同的下拉菜单只允许一些组合(实际上有更多的值和更多的下拉菜单,如下面的 sn-p 所示)。我的问题是:只要验证失败,JSP 就会重新加载(这显然没问题),我的选择消失了,我开始在单选按钮选项之间进行选择。

将单选按钮的值从 Servlet 1 传递给 Servlet 2 似乎工作得很好。 (我已经尝试在 Servlet2 的重新加载中使用相同的方法(request.set ...),但它不起作用。)验证也很好。


问题:我怎样才能在验证后像以前一样预先选择单选按钮(和其他输入字段)?我只想显示一条错误消息并保留所有输入值。


如果这很重要,这里是代码的某些部分,名称已更改,希望是一致的。如果有人知道如何将其放入按需/剧透容器中,请随时编辑。

input.jsp

<body>
    <span class="messages">${messages.ERROR}</span>
    <form action="/project/chooseRadio" method="get">

        <h2>Radio</h2>
        <input type="radio" name="option" onchange="submit()"
            value="option1"
            ${param.option == 'option1' ? 'checked' : ''}> 
            <input type="radio"
            name="option" onchange="submit()" value="option2"
            ${param.option== 'option2' ? 'checked' : ''}>
    </form>


    <form action="/project/input" method="post">    
        <div
            style="display:${(option == 'option1'  || option == 'option2') ? 'block' : 'none'}">

            <select name="dd1">
                <c:forEach items="${dd1}" var="dd1">
                    <option><c:out value="${dd1}" /></option>
                </c:forEach>
            </select> 
            <select name="dd2">
                <c:forEach items="${dd2}" var="dd2">
                    <option><c:out value="${dd2}" /></option>
                </c:forEach>            


            <input type="text" name="inputfield1" required="true" /> <br> 
            <input type="text" name="inputfield2" required="true" /> <br>
            <input type="submit" name="submit"
                value="submit" />
          </span>
        </div>
    </form>   
</body>

选择Radio-Servlet

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // option1
    int[] dd1_1 = { 1, 2, 3, 4 };
    int[] dd2_1 = { 1, 2, 3, 4 };

    // option2
    int[] dd1_2 = { 9, 8, 7, 6 };
    int[] dd2_2 = { 9, 8, 7, 6 };

    if (request.getParameter("option") != null) {

        switch (request.getParameter("option")) {
        case "option 1":
            request.setAttribute("option", "option1");
            request.setAttribute("dd1", dd1_1);
            request.setAttribute("dd2", dd2_1);
            break;

        case "option2":
            request.setAttribute("gratingType", "option2");
            request.setAttribute("dd1", dd1_2);
            request.setAttribute("dd2", dd2_2);
            break;
        default:
            break;
        }
    }

    request.getRequestDispatcher("/WEB-INF/input.jsp").forward(request, response);
}

输入-Servlet

@WebServlet("/input")
public class InputServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.getRequestDispatcher("/WEB-INF/input.jsp").forward(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        DTO dto = new DTO();

        Map<String, String> messages = new HashMap<String, String>();

        switch (request.getParameter("option")) {
        case "option1":
            dto.setOption("option1");
            break;

        case "option2":
            dto.setOption("option2");
            break;
        default:
            break;
        }


dto.setInputfield1(Integer.parseInt(request.getParameter("inputfield1")));
// ... dto.set for other fields ... //
// save dto in database
// validation
    if(validCombination(...)){
                request.getRequestDispatcher("/WEB-INF/output.jsp").forward(request, response);
            }
            else {
                messages.put("ERROR", String.format("this is not a valid combination."));
                request.setAttribute("messages", messages);
                request.getRequestDispatcher("/WEB-INF/input.jsp").forward(request, response);
            }
        }

【问题讨论】:

  • 为什么你将两个单选按钮的名称都命名为 option1option2?根据您在第一个 servlet 中的代码,两者不应该具有相同的名称,即 option 吗?
  • 哦,是的,他们确实有 - 我更改了真实姓名并错过了这个。谢谢。 (:

标签: java validation jsp servlets


【解决方案1】:

你真的有三个选择

  1. 在提交表单之前在 javascript 中验证客户端,无需服务器端调用
  2. 在提交表单之前使用服务器端调用 (ajax) 在 javascript 中验证客户端
  3. 提交表单并刷新页面以进行验证

选项 1 和 2 将保留字段中的值。选项 3 将要求您填充值并显示错误消息。

【讨论】:

  • 谢谢。如果我选择选项 1 - 这是关于安全问题的良好做法吗?我听说完全避免 JavaScript 验证并更好地使用 servlet 进行验证,但 JS 似乎不那么复杂。
  • JavaScript 对用户来说是一种更好的体验,因为它速度很快并且不需要服务器端的点击。但是可以禁用javascript,并且可以在未经黑客验证的情况下发布表单。我会经常在 javascript 中验证客户端,并为丢失的字段显示一条很好的消息,但也会重复相同的验证服务器端,这次为丢失的字段抛出服务器端异常(因为它可能是黑客攻击场景)
  • 听起来很完美,谢谢。因此,如果验证仍然失败,我的 Servlet 可以重新加载页面,并且我不必关心糟糕的用户体验,因为在正常情况下 JS 验证了输入并可能阻止提交。 (:
  • 如果 javascript 验证失败,您将不会重新加载页面,您将停止表单提交并显示错误/警告消息,直到 javascript 验证通过。然后您将提交表单并在持久化数据之前进行服务器端验证(验证失败时抛出异常)
猜你喜欢
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 2013-01-04
相关资源
最近更新 更多