⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 request.java

📁 《java网络编程精解》的源代码
💻 JAVA
字号:
import java.net.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.regex.*;
/* 代表客户的HTTP请求 */
public class Request {
  static class Action {  //枚举类,表示HTTP请求方式
    private String name;
    private Action(String name) { this.name = name; }
    public String toString() { return name; }

    static Action GET = new Action("GET");
    static Action PUT = new Action("PUT");
    static Action POST = new Action("POST");
    static Action HEAD = new Action("HEAD");

    public static Action parse(String s) {
        if (s.equals("GET"))
            return GET;
        if (s.equals("PUT"))
            return PUT;
        if (s.equals("POST"))
            return POST;
        if (s.equals("HEAD"))
            return HEAD;
        throw new IllegalArgumentException(s);
    }
  }

  private Action action;
  private String version;
  private URI uri;

  public Action action() { return action; }
  public String version() { return version; }
  public URI uri() { return uri; }

  private Request(Action a, String v, URI u) {
    action = a;
    version = v;
    uri = u;
  }

  public String toString() {
    return (action + " " + version + " " + uri);
  }

  private static Charset requestCharset = Charset.forName("GBK");

  /* 判断ByteBuffer是否包含了HTTP请求的所有数据。
   * HTTP请求以“\r\n\r\n”结尾。
   */
  public static boolean isComplete(ByteBuffer bb) {
    ByteBuffer temp=bb.asReadOnlyBuffer();
    temp.flip();
    String data=requestCharset.decode(temp).toString();
    if(data.indexOf("\r\n\r\n")!=-1){
      return true;
    }
    return false;
  }

  /*
   * 删除请求正文,本例子仅支持GET和HEAD请求方式,忽略HTTP请求中的正文部分
   */
  private static ByteBuffer deleteContent(ByteBuffer bb) {
    ByteBuffer temp=bb.asReadOnlyBuffer();
    String data=requestCharset.decode(temp).toString();
    if(data.indexOf("\r\n\r\n")!=-1){
        data=data.substring(0,data.indexOf("\r\n\r\n")+4);
        return requestCharset.encode(data);
    }
    return bb;
  }

  /*
   * 设定用于解析HTTP请求的字符串匹配模式。对于以下形式的HTTP请求:
   *
   *     GET /dir/file HTTP/1.1
   *     Host: hostname
   *
   * 将被解析成:
   *
   *     group[1] = "GET"
   *     group[2] = "/dir/file"
   *     group[3] = "1.1"
   *     group[4] = "hostname"
   */
  private static Pattern requestPattern
      = Pattern.compile("\\A([A-Z]+) +([^ ]+) +HTTP/([0-9\\.]+)$"
                        + ".*^Host: ([^ ]+)$.*\r\n\r\n\\z",
                        Pattern.MULTILINE | Pattern.DOTALL);

  /* 解析HTTP请求,创建相应的Request对象 */
  public static Request parse(ByteBuffer bb) throws MalformedRequestException {
    bb=deleteContent(bb); //删除请求正文
    CharBuffer cb = requestCharset.decode(bb); //解码
    Matcher m = requestPattern.matcher(cb);  //进行字符串匹配
    //如果HTTP请求与指定的字符串模式不匹配,说明请求数据不正确
    if (!m.matches())
        throw new MalformedRequestException();
    Action a;
    try {  //获得请求方式
        a = Action.parse(m.group(1));
     } catch (IllegalArgumentException x) {
        throw new MalformedRequestException();
    }
    URI u;
    try { //获得URI
        u = new URI("http://"
                    + m.group(4)
                    + m.group(2));
    } catch (URISyntaxException x) {
        throw new MalformedRequestException();
    }
    //创建一个Request对象,并将其返回
    return new Request(a, m.group(3), u);
  }
}


/****************************************************
 * 作者:孙卫琴                                     *
 * 来源:<<Java网络编程精解>>                       *
 * 技术支持网址:www.javathinker.org                *
 ***************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -