一尘不染

从Servlet使用sendRedirect时,jsp页面中的请求属性不可用

jsp

我是jsp和servlet的新手。我的情况如下

我有一个jsp页面,其中包含一个表单。有两个领域。jsp页面的代码片段如下。

MyFirstJSP.jsp文件

<body>
<h1> This is my first jsp and servlet project</h1>
<%
//System.out.println(request.getAttribute("fname"));

if(request.getAttribute("fname")!=null){
    System.out.println(request.getAttribute("fname"));
}else{
    System.out.println("No request ");
}
%>
<form action="MyFirstServlet" method="get">
First Name<input type="text" name="fname" value= ${fname}><br>
Last Name<input type="text" name="lname" value= ${lname}>
<input type="submit" value="Send">
</form>
</body>

当我提交此表单时,将调用MyFirstServlet,它检查用户输入的名字。如果名字等于“
abc”,那么servlet将属性设置为请求对象,并将其重定向到正在调用的jsp页面(即上一页)。它将从请求对象获取值并将其填写到表单的相应字段中。我也有Java
Expression语言,以获得相同的效果。

这是MyFirstServlet.java Servlet文件的代码片段

/**
 * Servlet implementation class MyFirstServlet
 */
public class MyFirstServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#HttpServlet()
 */
public MyFirstServlet() {
    super();
    // TODO Auto-generated constructor stub
}

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {       // TODO Auto-generated method stub
    String firstname=request.getParameter("fname");
    if(firstname.equalsIgnoreCase("abc")){
        System.out.println("Setting attributes");
        request.setAttribute("fname",firstname);
        request.setAttribute("lname",request.getParameter("lname"));
        response.sendRedirect("MyFirstJSP.jsp");
    }else{
        System.out.Println("No problem");
    }
}
/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    PrintWriter p=response.getWriter();
    p.println("Success!");
    doGet(request,response);
}
}

但是,当我执行代码时,servlet重定向到jsp页面,但没有用相应的值填充表单字段。为了找到原因,我添加了if-else-
block来了解原因,并且我知道请求对象属性在这里不可用。

如果在这种情况下使用请求分配器,则可以使用这些值,并且使用这些值填充表单,但是地址栏中的url不会改变,并且始终显示servlet的url。

所以我的查询是

** 1)为什么使用sendRedirect不能将请求对象用于jsp页面。

2)如果servlet将重定向发送到调用jsp的话,还有其他方法可以在jsp页面中显示由用户输入的值预填充我的表单,这样用户就不必重新输入数据了。**

请引导我的朋友解决这个问题,谢谢!


阅读 284

收藏
2020-06-08

共1个答案

一尘不染

您需要 转发 到服务器端的jsp页面,因为 重定向
是客户端操作(请检出位置标头1),请求属性会丢失。

更换

response.sendRedirect("MyFirstJSP.jsp");

request.getRequestDispatcher("MyFirstJSP.jsp").forward(request, response);

编辑:对不起,我跳过了这一部分

如果在这种情况下使用请求分配器,则可以使用这些值,并且使用这些值填充表单,但是地址栏中的url不会改变,并且始终显示servlet的url。

但是,重定向时您不能将请求属性传递给您的jsp(因为上面已经提到过,这是一个客户端操作)

我建议您执行以下操作:

  • 实现doGet仅用于呈现包含表单的页面
  • 实现doPost以处理提交的表单数据
  • 在HTML表单中使用POST而不是GET提交表单

在doGet和doPost中,都使用 forward 呈现* .jsp页面。

GET / MyFirstServlet->转发到MyFirstJSP.jsp

POST / MyFirstServlet->转发到MyFirstJSP.jsp

这是最常用和最清洁的方法。

编辑2:简单的例子

SimpleFormServlet.java

public class SimpleFormServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

private static final String VIEW_NAME = "/WEB-INF/jsp/simpleForm.jsp";
private static final String MODEL_NAME = "form";

public SimpleFormServlet() {
    super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setAttribute(MODEL_NAME, new SimpleForm());
    request.getRequestDispatcher(VIEW_NAME).forward(request, response);
}

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

    final SimpleForm form = map(request);

    if(form.getfName().equalsIgnoreCase("abc")){
        request.setAttribute(MODEL_NAME, form);
        // put additional attributes on the request
        // e.g. validation errors,...
        request.getRequestDispatcher(VIEW_NAME).forward(request, response);
    }else{
        System.out.println("No problem");
        response.sendRedirect("/SuccessServlet");
    }
}

private SimpleForm map(final HttpServletRequest request) {
    SimpleForm form = new SimpleForm();
    form.setfName(request.getParameter("fName"));
    form.setlName(request.getParameter("lName"));
    return form;
}

public static class SimpleForm implements Serializable {
    private static final long serialVersionUID = -2756917543012439177L;

    private String fName;
    private String lName;

    public String getfName() {
        return fName;
    }
    public void setfName(String fName) {
        this.fName = fName;
    }
    public String getlName() {
        return lName;
    }
    public void setlName(String lName) {
        this.lName = lName;
    }

}

}

/WEB-INF/jsp/simpleForm.jsp

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>

<form method="POST">
    First Name<input type="text" name="fName" value="${form.fName}"><br>
    Last Name<input type="text" name="lName" value="${form.lName}">
    <input type="submit" value="Send">
</form>

</body>
</html>
  1. GET / SimpleFormServlet
  2. doGet()准备表单模型(SimpleForm)并将其添加为名为“ form”的请求属性
  3. 转发到simpleForm.jsp
  4. 访问模型值并预填写以下表单:$ {form.fName}和$ {form.lName}
  5. 浏览器仍显示/ SimpleFormServlet(我们喜欢它;-))
  6. POST 形式相对到/ SimpleFormSerlvet(你没有明确设置表单元素的action属性)
  7. doPost()将请求参数映射到SimpleForm。
  8. 处理请求并执行您想做的任何事情(验证)
  9. 那么您可以转发到simpleForm.jsp(例如当验证失败时)或 重定向 到另一个Servlet(例如,/ SuccessServlet)
2020-06-08