回到顶部
您的当前位置: 编程语言> JAVA> JAVA基础> WEB开发
Servlet技术-请求重定向与请求转发(四)
2014-04-22 16:41:49
标签: 原创 Servlet 开发 请求重定向 请求转发
请求重定向与请求转发的比较

    (1)RequestDispatcher.forward方法只能将请求转发给同一个Web应用中的组件;而HttpServletResponse.sendRedirect方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。如果传递给HttpServletResponse.sendRedirect方法的相对URL以”/”开头,它是相对整个Web站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以”/”开头,它是相对于当前Web应用程序的根目录.

    (2)调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;而调用RequestDispatcher.forward方法的请求转发过程结束后,浏览器地址栏保持初始URL地址不变.

    (3)HttpServletResponse.sendRedirect方法对浏览器的请求直接做出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求(一共发出两次请求得到两次响应);RequestDispatcher.forward方法在服务器内部将请求转发给另外的一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为.

    (4)RequestDispatcher.forward方法的调用者和被调用者之间共享相同的request对象和response对象,他们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法的调用者和被调用者使用各自的request对象和response对象,他们属于两个独立的访问请求和响应过程.如果一次请求的响应过程被设计成由Web应用程序内部的多个资源来协同完成,这就需要在同一个Web应用程序的内部资源之间进行跳转,并且在跳转之前往往要进行一些前期的预处理,然后在使用HttpServletRequest.setAttribute方法将预处理结果传递给下一个资源,这种情况下就必须使用RequestDispatcher.forward方法,不同Web应用程序之间的重定向特别是要重定向到另外一个Web站点上的资源的情况都应该使用HttpServletResponse.sendRedirect方法.

    (5)无论是RequestDispatcher.forward方法,还是HttpServletResponse.sendRedirect方法,在调用它们之前,都不能有内容已经被实际输出到客户端.如果缓冲区中有了一些内容,这些内容将被从缓冲区中清除.

用于获得请求行的相关方法信息

    getRequestURI方法:

    该方法返回请求行中的资源名部分,也就是位于URL的主机和端口之后,参数部分之前的那部分内容,例如,对于如下的URL:http://localhost:8080/servlet_day04/config?name=“lxm”&p2=“123”

    getRequestURI方法返回”/servlet_day04/config”.

    getQueryString方法:

    该方法返回请求行中的参数部分,也就是资源路径后面的问号(?)以 后的所有内容.返回结果没有被进行URL解码,而是保持其在HTTP消息的请求行中的原始面貌.

    getContextPath方法:

    该方法返回请求URL所属于的Web应用程序的路径,这个路径以”/”开头,表示相对于整个Web站点的根目录,路径结尾不含”/”,如果请求URL属于Web站点的根目录,那么返回结果为空字符串(“”).

    getPathInfo方法:

    该方法返回请求URL中额外路径信息.额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以”/”开头.如果请求URL中没有额外路径信息部分,getPathInfo返回null.额外路径可用于向Servlet传递信息,但它传递的信息通常是指Web服务器上的其它资源名,例如,配置文件,临时文件或其他servlet,jsp页面.在MVC设计模式中,客户端的所有请求都指向一个作为中央控制器的Servlet,其他各个JSP页面则作为请求URL中的额外路径部分,由这个Servlet根据额外路径信息去调用其他各个JSP页面.只要在web.xml文件中将某个Servlet映射成一个通配符形式的路径,例如”/controller/*”,然后就可以使用”/controller/one.jsp”,”/controller/two.jsp”等多个路径来访问这个Servlet,其中的”/one.jsp”和”/two.jsp”等即为额外路径信息,可以让这些额外路径信息正好是Web服务器上的其他资源名称.

    getPathTranslated方法:

    该方法返回URL中的额外路径信息所对应的资源的真实路径.

    getServletPath方法:

    该方法返回Servlet名称或Servlet所映射的路径

RequestLineServlet.java
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out=response.getWriter();
    out.println("getMethod:  "+request.getMethod()+"<br>");
    out.println("getRequestURI:  "+request.getRequestURI()+"<br>");
    out.println("getQueryString:  "+request.getQueryString()+"<br>");
    out.println("getProtocol:  "+request.getProtocol()+"<br>");
    out.println("getContextPath:  "+request.getContextPath()+"<br>");
    out.println("getPathInfo:  "+request.getPathInfo()+"<br>");
    out.println("getPathTranslated:     "+request.getPathTranslated()+"<br>");
    out.println("getServletPath:  "+request.getServletPath()+"<br>");
    out.println("getServletName:   "+request.getServerName()+"<br>");
    out.close();
}

    getRemoteAddr方法:

    该方法返回发出请求的客户端的IP地址.

    getRemoteHost方法:

    该方法返回发出请求的客户端的完整主机名,如果Servlet引擎不能解析出客户端的完整主机名那么该方法就返回客户机的IP地址.

    getRemotePort方法:

    给方法返回发出请求的客户机所使用的网络接口的端口号.

    getLocalAddr方法:

    该方法返回Web服务器上接收当前请求的网络接口的IP地址.

    getLocalName方法:

    该方法返回Web服务器上接收当前请求的网络接口的IP地址所对应的主机名.

    getLocalPort方法:

    该方法返回Web服务器上接收当前请求的网络接口的断口号.

    getServerName方法:

    该方法返回当前请求所指向的主机名,如果HTTP请求消息的Host头字段中包含有主机名部分,那么返回值即为该主机名部分.

    getServerPort方法:

    该方法返回当前请求所连接的服务器端口号.如果HTTP请求消息的Host头字段中包含有端口号部分,那么返回值即为该端口号部分.

    getScheme方法:

    该方法返回请求的协议名,例如http,ftp等.

    getRequestURL方法:

    该方法返回客户端发出的请求时完整URL.包括协议,服务器名,端口号,资源路径等信息,但不包括后面的查询参数部分.注意getRequestURL方法返回的结果是StringBuffer类型.

    getCharacterEncoding方法:

    该方法返回请求信息的实体部分的字符集编码.

    setCharacterEncoding方法:

    该方法用于覆盖请求消息中的实体内容的字符集编码名称的设置.

    getParameter方法:

    该方法返回某个指定名称的参数的值.

    getParameterValues方法:

    该方法常用于处理FORM表单中的多选项,因为它包含了多个同名的字段元素.

    getParameterNames方法:

    该方法用于返回一个包含请求消息中的所有参数名的Enumeration对象.

    getParameterMap方法:

    该方法用于将请求消息中的所有参数名和值装入一个Map对象中返回.

Form.html
<form method="post" action="parameter">
    <input type="hidden" name="type" value="register">
    userName:<input type="text" name="userName">
    password:<input type="password" name="password">
    gender:male<input name="gender" type="radio" value="m" checked>
    female<input name="gender" type="radio"value="f">
    hobbies:eating<input type="checkbox"  name="hobbies" value="e">
    sleeping<input type="checkbox"  name="hobbies" value="s">
    playing<input type="checkbox"  name="hobbies" value="y">
    province:<select name="province">
        <option value="110000">beijing</option>
        <option value="120000">tianjin</option>
    </select>
    introduction:<textarea name="introduction"></textarea>
    <input type="submit" value="submit">
    <input type="button" value="button">
    <input type="reset">
</form>
RequestParameterServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head><title>param</title></head>");
    out.println("<body>");
    out.println("<h3 align=\"center\">all parameters</h3>");
    out.println("<hr>");
    out.println(request.getParameter("userName"));
    out.println(join(";", request.getParameterValues("hobbies")));
    out.println("<hr>");
    Enumeration paramNames = request.getParameterNames();
    while (paramNames.hasMoreElements()){
        String name = (String) paramNames.nextElement();
        String[] values = request.getParameterValues(name);
        out.println(name + "=" + join(",", values));
        out.println("<br>");
    }
    out.close();
}

private String join(String str, String[] values) {
    if(values == null) {
        return null;
    }
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < values.length; i++) {
        if (i > 0) {
            buffer.append(str);
        }
        buffer.append(values[i]);
    }
    return buffer.toString();
}
RequestParameterMapServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException{
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html>");
    out.println("<head><title>param</title></head>");
    out.println("<body>");
    out.println("<h3 align=\"center\">all parameters</h3>");
    out.println("<hr>");
    Map parameters = request.getParameterMap();
    Set paramNames = parameters.keySet();
    Iterator iter = paramNames.iterator();
    while (iter.hasNext()){
        String name = (String) iter.next();
        String[] values = parameters.get(name);
        out.println(name + "=" + join(",", values));
        out.println("<br>");
    }
    out.close();
}

private String join(String str, String[] values){
    if(values == null){
        return null;
    }
        
    StringBuffer buffer = new StringBuffer();
    for (int i = 0; i < values.length; i++){
        if (i > 0){
            buffer.append(str);
        }
        buffer.append(values[i]);
    }
    return buffer.toString();
}
利用请求域属性传递信息

    setAttribute方法:

    该方法用于将一个对象与一个名称关联后存储进对象中,其完整语法定义如下:

public void setAttribute(java.lang.String name,java.lang.Object o);

    getAttribute方法:

    该方法用于从ServletRequest对象中返回指定名称的属性对象,其完整的语法定义如下:

public java.lang.String getAttribute(java.lang.String name);

    removeAttribute方法:

    该方法用于从ServletRequest对象中删除指定名称的属性,其完整的语法定义如下:

public void removeAttribute(java.lang.String name);

    getAttributeNames方法:

    该方法用于返回一个包含ServletRequest对象中所有属性名的Enumeration对象,可以对ServletRequest对象中的所有属性进行遍历处理.其完整语法定义如下:

public java.util.Eunmeration getAttributeNames();