Servlet中的request对象

目录

简介

  HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户端的信息。

request的常用方法

  • 获取客户端信息
方法名描述
getRequestURL返回客户端发出请求时的完整URL
getRequestURI返回请求行中的资源名部分
getQueryString返回请求行中的参数部分
getRemoteAddr返回发出请求的客户机的IP地址
getRemoteHost返回发出请求的客户机的完整主机名(前提是有主机名,否则将返回IP地址)
getRemotePort返回客户机所使用的网络端口号
getLocalAddr返回Web服务器的IP地址
getLocalName返回Web服务器的主机名
getMethod得到客户机请求方式

  示例:

package com.wm103.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by DreamBoy on 2017/4/29.
 */

/**
 * request的常用方法
 */
@WebServlet(name = "RequestDemo1", urlPatterns = {"/RequestDemo1"})
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uri = request.getRequestURI();
        String url = request.getRequestURL().toString();
        String queryString = request.getQueryString();
        System.out.println("uri: " + uri);
        System.out.println("url: " + url);
        System.out.println("QueryString: " + queryString);

        System.out.println(request.getRemoteAddr());
        System.out.println(request.getRemoteHost()); // 返回客户端的主机名(要求客户端在DNS上注册过域名,配置了主机名,否则仍返回主机IP地址)
        System.out.println(request.getRemotePort());

        System.out.println("-----------------------");
        System.out.println(request.getMethod());
    }
}

  注:URI和URL——如:/news/1.html 是URI;http://www.sina.com/news/1.html 是URL。URL也属于URI。

  • 获取请求头信息
    • getHeader
    • getHeaders
    • getHeaderNames
  • 获取客户端提交的数据
    • getParameter
    • getParameterNames
    • getParameterValues
    • getParameterMap
    • getInputStream
      示例:
      User.java
package com.wm103.request;

/**
 * Created by DreamBoy on 2017/4/29.
 */
public class User {
    private String username[];
    private String password;

    public String[] getUsername() {
        return username;
    }

    public void setUsername(String[] username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

  RequestDemo2.java(注意该案例中使用到了BeanUtils,要求项目需要引入 beanutils的jar,这里为:commons-beanutils-1.8.0.jarcommons-logging-1.1.1.jar

package com.wm103.request;

import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;

/**
 * Created by DreamBoy on 2017/4/29.
 */

/**
 * 获取请求头和请求数据
 * 获取数据时一般来说都要先检查再使用
 */
@WebServlet(name = "RequestDemo2", urlPatterns = {"/RequestDemo2"})
public class RequestDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

    /**
     * 获取请求数据的方法
     * @param request
     */
    private void test2(HttpServletRequest request) {
        String username = request.getParameter("username");
        if(username != null && !username.trim().equals("")) {
            System.out.println(username);
        }

        System.out.println("-----------------------");

        Enumeration<String> en = request.getParameterNames();
        while (en.hasMoreElements()) {
            String name = en.nextElement();
            String value = request.getParameter(name);
            System.out.println(name + "=" + value);
        }

        System.out.println("-----------------------");

        String[] values = request.getParameterValues("username");
        for (int i = 0; values != null && i < values.length; i++) {
            System.out.println(values[i]);
        }

        System.out.println("-----------------------");

        // 重要!!!
        Map<String, String[]> map = request.getParameterMap();
        User user = new User();
        try {
            BeanUtils.populate(user, map); // 通过BeanUtils将map集合中的键值对设置到bean对象对应属性中去
            // BeanUtils.copyProperties(user, formbean); // 拷贝一个bean的属性值到另外一个bean
        } catch (Exception e) {
            e.printStackTrace();
        }
        String[] usernames = user.getUsername();
        String password = user.getPassword();
        System.out.println(usernames[0] + " " + usernames[1] + " " + password);

        System.out.println("-----------------------");

        // 有点毛病~~
        /*InputStream in = request.getInputStream();
        int len;
        byte[] buffer = new byte[1024];
        while ((len = in.read(buffer)) > 0) {
            System.out.println(new String(buffer, 0, len));
        }*/
    }

    /**
     * 获取请求头信息的方法
     * @param request
     */
    private void test1(HttpServletRequest request) {
        String headerValue = request.getHeader("Accept-Encoding");
        System.out.println(headerValue);

        System.out.println("-----------------------");

        Enumeration<String> en = request.getHeaders("Accept-Encoding");
        while (en.hasMoreElements()) {
            String value = en.nextElement();
            System.out.println(value);
        }

        System.out.println("-----------------------");

        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            String value = request.getHeader(name);
            System.out.println(name + ": " + value);
        }
    }
}

  表单提交接收案例:
  form1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Form</title>
    <style>
        .form-container {
            width: 400px;
            margin: 50px auto;
        }
    </style>
</head>
<body>
    <div class="form-container">
        <form action="/day06/RequestDemo3" method="post">
            <p>头 像:<input type="file" name="image"></p>
            <p>用户名:<input type="text" name="username"></p>
            <p>密 码:<input type="password" name="password"></p>
            <p>性 别:<input type="radio" name="gender" value="male"><input type="radio" name="gender" value="female"></p>
            <p>所在地:
                <select name="city">
                    <option value="beijing">北京</option>
                    <option value="shanghai">上海</option>
                    <option value="cs">长沙</option>
                </select>
            </p>
            <p>爱 好:
                <input type="checkbox" name="likes" value="sing">唱歌
                <input type="checkbox" name="likes" value="dance">跳舞
                <input type="checkbox" name="likes" value="basketball">篮球
                <input type="checkbox" name="likes" value="football">足球
            </p>
            <p>备 注:
                <textarea name="description" cols="30" rows="10"></textarea>
            </p>
            <input type="hidden" name="id" value="12345">
            <p><input type="submit" value="提交"></p>
        </form>
    </div>
</body>
</html>

  RequestDemo3.java

package com.wm103.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by DreamBoy on 2017/4/29.
 */
@WebServlet(name = "RequestDemo3", urlPatterns = {"/RequestDemo3"})
public class RequestDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8"); // 默认采用的是ISO-8859-1进行转码,但是提交过来的数据以UTF-8(根据页面的编码)进行编码,所以需要先设置转化数据的码表为UTF-8。

        String username = request.getParameter("username");
        System.out.println("username=" + username);
        String password = request.getParameter("password");
        System.out.println("password=" + password);
        String gender = request.getParameter("gender");
        System.out.println("gender=" + gender);
        String city = request.getParameter("city");
        System.out.println("city=" + city);
        String[] likes = request.getParameterValues("likes");
        for(int i = 0; likes != null && i < likes.length; i++) {
            System.out.println("likes=" + likes[i]);
        }
        String description = request.getParameter("description");
        System.out.println("description=" + description);
    }

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

    }
}

request接收中文数据乱码问题

  • post方式提交的数据(post方式提交的数据的编码方式根据页面显示编码方式进行编码),可以通过设置:
request.setCharacterEncoding("UTF-8"); // 默认采用的是ISO-8859-1进行转码,但是提交过来的数据以UTF-8(根据页面的编码)进行编码,所以需要先设置转化数据的码表为UTF-8。但是默认只对post提交有效。如果在server.xml中设置Connector标签的属性useBodyEncodingForURI为true,则对get请求方式也有效。

  示例:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 默认只对post提交有效。如果在server.xml中设置Connector标签的属性useBodyEncodingForURI为true,则对get请求方式也有效。
        request.setCharacterEncoding("UTF-8"); // 默认采用的是ISO-8859-1进行转码,但是提交过来的数据以UTF-8(根据页面的编码)进行编码,所以需要先设置转化数据的码表为UTF-8。但是只对post有效

        String username = request.getParameter("username");
        System.out.println("username=" + username);
    }
  • get方式提交的数据(包括form和链接跳转提交数据这两种方式)
      tomcat8.0默认URIEncoding为ISO-8859-1,从tomcat8.0开始,URIEncoding默认值不再是ISO-8859-1,而变成了UTF-8。所以对于设置了UTF-8编码的页面来说get请求提交的数据没有中文乱码的问题。但是对于tomcat8.0以前则需要解决,如:
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"), "UTF-8");
System.out.println("username=" + username);

  示例:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        // 值得注意的是,从tomcat8.0开始,URIEncoding默认值不再是ISO-8859-1,而变成了UTF-8。参考:http://www.cnblogs.com/hyl8218/p/5811769.html
        // 现在这里不用进行编码的转换,也不会乱码了!!当前环境为Tomcat 9.0.0.M4。参考:https://tomcat.apache.org/tomcat-9.0-doc/config/http.html
        // username = new String(username.getBytes("iso8859-1"), "UTF-8");
        System.out.println("username=" + username);
    }

request对象实现请求转发

  请求转发指一个Web资源收到客户端请求后,通知服务器去调用另外一个Web资源进行处理。通过使用请求转发可以使Web项目实现MVC设计模式。
1. request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
2. request对象同时也是一个域对象(此前提到的ServletContext同样也是一个域对象,其作用于整个Web应用,而request对象则作用于当前请求),开发人员通过request对象在实现转发时,把数据通过request对象带给其它Web资源处理。
3. 请求转发时,传递数据的方法(调用request对象中的方法):

  • setAttribute方法
  • getAttribute方法
  • removeAttribute方法
  • getAttributeNames方法
      
    示例:
package com.wm103.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by DreamBoy on 2017/4/29.
 */

/**
 * 请求转发,以及使用request域对象把数据带给转发资源
 * 请求转发的特点:
 * 1. 客户端只发送一次请求,而服务器端有多个资源调用
 * 2. 客户端浏览器地址栏没有变化
 */
@WebServlet(name = "RequestDemo5", urlPatterns = {"/RequestDemo5"})
public class RequestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String data = "This is RequestDemo5.";

        request.setAttribute("data", data);
        // 除了使用ServletContext进行转发外,也可以使用request对象实现转发
        request.getRequestDispatcher("/info.jsp").forward(request, response);
    }
}

  info.jsp (通过EL表达式从request中获取setAttribute的数据)

<%--
  Created by IntelliJ IDEA.
  User: DreamBoy
  Date: 2017/4/29
  Time: 17:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP</title>
</head>
<body>
    ${data} <!-- El表达式 -->

    <br/>
    <%
        String data = (String) request.getAttribute("data");
        out.write(data);
    %>
</body>
</html>

使用请求转发的注意事项

  • forward方法用于将请求转发到RequestDispatcher对象封装的资源。
  • 如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。
  • 如果在调用forward方法之前向Servlet引擎的缓冲区(response)中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已写入到HttpServletResponse对象中的响应头字段信息保持有效。
      示例:
package com.wm103.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by DreamBoy on 2018/3/5.
 */

/**
 * forward方法
 */
@WebServlet(name = "RequestDemo6", urlPatterns = {"/RequestDemo6"})
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

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

    // 如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常
    private void test1(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String data = "This is RequestDemo6";
        request.setAttribute("data", data);
        PrintWriter writer = response.getWriter();
        writer.write(data);
        writer.close(); // 将数据传送给客户端

        request.getRequestDispatcher("/info.jsp").forward(request, response);
    }

    // 如果在调用forward方法之前向Servlet引擎的缓冲区(response)中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空
    private void test2(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String data = "This is RequestDemo6";
        request.setAttribute("data", data);
        PrintWriter writer = response.getWriter();
        writer.write(data);

        request.getRequestDispatcher("/info.jsp").forward(request, response);
    }

    // 转发后JSP中进行内容的输出,后续再调用`request.getRequestDispatcher`进行转发,仍将抛出:java.lang.IllegalStateException: Cannot forward after response has been committed 异常
    private void test3(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String data = "This is RequestDemo6";
        request.setAttribute("data", data);

        if(true) {
            request.getRequestDispatcher("/info.jsp").forward(request, response);

            // return; // 加入 return 语句解决
        }

        // 执行下面语句后将抛出:java.lang.IllegalStateException: Cannot forward after response has been committed 异常
        request.getRequestDispatcher("/info.jsp").forward(request, response);
    }
}

RequestDispatcher的页面包含方法include

  • RequestDispatcher.include方法用于将RequestDispatcher对象封装的资源内容作为当前响应内容的一部分包含进来,从而实现可编程的服务器端包含功能。
  • 被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略。
      示例:
      public/head.jsp
<%--
  Created by IntelliJ IDEA.
  User: DreamBoy
  Date: 2017/4/29
  Time: 18:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>RequestDemo7</title>
</head>
<body>
    head<br/>

  public/foot.jsp

    foot<br/>
</body>
</html>

  使用include方法:

request.getRequestDispatcher("/public/head.jsp").include(request, response);
response.getWriter().write("Test Include<br/>");
request.getRequestDispatcher("/public/foot.jsp").include(request, response);

Web工程中各类URL地址的写法

  如果编写的URL是给服务器使用的,则“/”代表当前Web应用目录;如果编写的URL是给浏览器使用的,则“/”代表网站目录。
  示例:

// 1.
request.getRequestDispatcher("/index.jsp").forward(request, response);

// 2.
response.sendRedirect("/day06/index.jsp");

// 3.
this.getServletContext().getRealPath("/index.jsp");

// 4.
this.getServletContext().getResourceAsStream("/index.jsp");

// 5.
/*
<a href="/day06/index.jsp">点击此链接</a>

<form action="/day06/index.jsp">

</form>
 */

防盗链

  实际上即判断当前请求从“哪里”来。根据请求头中的referer进行判断。判断如果referer的值不为我们“http://服务器的主机名”,则为盗链

package com.wm103.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by DreamBoy on 2017/4/29.
 */

/**
 * 防盗链
 */
@WebServlet(name = "RequestDemo9", urlPatterns = {"/RequestDemo9"})
public class RequestDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String referer = request.getHeader("referer");
        if(referer == null || !referer.startsWith("http://localhost")) {
            response.sendRedirect("/day06/index.jsp");
            return;
        }

        response.getWriter().write("This is RequsetDemo9.");
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值