1.思维导图
2.代码部分
自定义Tomcat服务器
public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8181); Socket socket = serverSocket.accept(); //处理请求行,获取访问资源的路径 InputStream inputStream = socket.getInputStream(); //转换流 InputStreamReader reader = new InputStreamReader(inputStream); //封装成了高效字符流 BufferedReader bufferedReader = new BufferedReader(reader); //"GET /day67_02/index.html HTTP/1.1" //请求方式、请求路径、协议;其中,只有请求路径有用! String line = bufferedReader.readLine(); String[] requestInfos = line.split(" "); String requestURL = requestInfos[1]; System.out.println(requestURL); int length = "/day67/".length(); //获取请求资源的相对路径 requestURL = requestURL.substring(length); //通过服务器将index.html响应给浏览器 , 通过socket.getOutputStream(); OutputStream outputStream = socket.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(outputStream); //操作响应行 (协议、响应状态码) bos.write("HTTP/1.1 200 OK\r\n".getBytes()); //操作响应头(Content-Type) bos.write("Content-Type:text/html\r\n".getBytes()); bos.write("\r\n".getBytes()); //操作响应正文 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(requestURL)); int len = -1; byte[] bys = new byte[8192]; while ((len = bis.read(bys)) != -1) { bos.write(bys,0,len); } bis.close(); bos.close(); } catch (Exception e) { e.printStackTrace(); } }
自定义Tomcat服务器优化
public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8282); while (true) { //阻塞 //没有请求时,阻塞这个代码,不会创建线程 Socket socket = serverSocket.accept(); new Thread(){ @Override public void run() { try { //处理请求行,获取访问资源的路径 InputStream inputStream = socket.getInputStream(); //转换流 InputStreamReader reader = new InputStreamReader(inputStream); //封装成了高效字符流 BufferedReader bufferedReader = new BufferedReader(reader); //"GET /day67_02/index.html HTTP/1.1" //请求方式、请求路径、协议;其中,只有请求路径有用! String line = bufferedReader.readLine(); String[] requestInfos = line.split(" "); String requestURL = requestInfos[1]; System.out.println(requestURL); int length = "/day67/".length(); //获取请求资源的相对路径 requestURL = requestURL.substring(length); //通过服务器将index.html响应给浏览器 , 通过socket.getOutputStream(); OutputStream outputStream = socket.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(outputStream); //操作响应行 (协议、响应状态码) bos.write("HTTP/1.1 200 OK\r\n".getBytes()); //操作响应头(Content-Type) bos.write("Content-Type:text/html\r\n".getBytes()); bos.write("\r\n".getBytes()); //操作响应正文 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(requestURL)); int len = -1; byte[] bys = new byte[8192]; while ((len = bis.read(bys)) != -1) { bos.write(bys,0,len); } bis.close(); bos.close(); } catch (Exception e) { e.printStackTrace(); } } }.start(); } } catch (Exception e) { e.printStackTrace(); } }
正则表达式基本使用
- 传统方式
Scanner scanner = new Scanner(System.in); while (true) { System.out.println("请输入您的qq号码:"); String qqStr = scanner.nextLine(); //判断qq号码的长度 if (qqStr.length() >= 5 && qqStr.length() <= 15) { if (!qqStr.startsWith("0")) { //获取字符串中每一个字符 boolean isNum = true;//记录是否是一个数字,只要字符串中有一个字符不是数字,那么就为false for (int i = 0; i < qqStr.length(); i++) { char chr = qqStr.charAt(i); //判断字符是否是数字 //12ac345 if (!Character.isDigit(chr)) { //该字符不是一个数字 isNum = false; break; } } //判断字符串是否都是数字 if (isNum) { System.out.println("您的qq号,很棒哟~~~"); } else { System.out.println("必须都是数字"); } } else { System.out.println("不能以0开头"); } } else { System.out.println("qq号码的长度不对!"); } }
- 采用正则表达式
Scanner scanner = new Scanner(System.in); while (true) { System.out.println("请输入您的qq号码:"); String qqStr = scanner.nextLine(); //qq号正则表达式 String reg = "[1-9]{1}[0-9]{4,14}"; System.out.println( qqStr.matches(reg) ? "qq号输入正确" : "qq号格式有误!" ); }
正则表达式字符类
- 常见字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
[0-9] 0到9的字符都包括
- 常见预定义字符类
. 任何字符
\d 数字:[0-9]
\D 非数字:[^0-9]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
// . 任何字符。 String reg1 = "."; System.out.println(">a".matches(reg1)); // \d 数字:[0-9] String reg2 = "\\d"; System.out.println("11".matches(reg2)); // \D 非数字:[^0-9] String reg3 = "[^0-9]"; System.out.println("a".matches(reg3)); String reg4 = "\\D"; System.out.println("1".matches(reg4)); // \w 单词字符:[a-zA-Z_0-9] String reg5 = "\\w"; System.out.println("_".matches(reg5)); String reg6 = "[a-zA-Z0-9_]"; System.out.println("_".matches(reg6)); // \W 非单词字符:[^\w] String reg7 = "[^a-zA-Z0-9_]"; System.out.println("a".matches(reg7)); String reg8 = "[^\\w]"; System.out.println("!".matches(reg8)); String reg9 = "[\\W]"; System.out.println("!".matches(reg9)); // \s 空白字符:[ \t\n\x0B\f\r] String reg10 = "\\s"; System.out.println(" ".matches(reg10)); // \S 非空白字符:[^\s] String reg11 = "\\S"; System.out.println("!".matches(reg11));
- 注意
String reg1 = "[abc]";//任意一个字符,要么是a、b、c String reg2 = "[a][b][c]";//等价于"abc" ,正则表达式中,如果没写[],会给每个字符加[] System.out.println("a".matches(reg1));//true System.out.println("a".matches(reg2)); System.out.println("---------------"); System.out.println("abc".matches(reg1));//false System.out.println("abc".matches(reg2));//true
正则表达式数量词
- 常见数量词
X?:X,要么只有一个,要么没有
X*:X,从0次到多次
X+:X,从1次到多次
X{n}:X,正好n次
X{n,}:X,从n次到多次
X{n,m}:X,从n次到m次
// X? :X,一次或一次也没有 String reg1 = "[a]?";//要么是“a”要么什么都没有 System.out.println("aaa".matches(reg1)); // X* :X,零次到多次 String reg2 = "[a]*"; System.out.println("b".matches(reg2)); // X+ :X,一次到 多次 String reg3 = "[a]+"; System.out.println("".matches(reg3)); // X{n} :X,恰好 n 次 String reg4 = "[ab]{3}";//内容由a或b组成,长度为3 System.out.println("aaa".matches(reg4)); // X{n,} :X,至少 n 次 //0次到多次 String reg5 = "[abc]{0,}";//内容由a组成,0次到多次! System.out.println("aaaa".matches(reg5)); //1次到多次 String reg6 = "[a]{1,}"; System.out.println("".matches(reg6)); // X{n,m} :X,至少 n 次,但是不超过 m 次 String reg7 = "[abc]{2,3}"; System.out.println("abc".matches(reg7));
正则表达式的分割功能
- 案例需求:"a,b,c,d"、 "a,,b,,c,,d"、 "a,b,,c,,,d"、 "a,,b,,,c,d,,,,,e" 将以上四个字符串按照逗号进行分割
// "a,b,c,d" String str1 = "a,b,c,d"; String reg1 = "[,]{1}"; String[] strs1 = str1.split(reg1); for (String str : strs1) { System.out.println(str); } System.out.println("-----------"); // "a,,b,,c,,d" String str2 = "a,,b,,c,,d"; // String reg2 = ",,"; String reg2 = "[,]{2}"; String[] strs2 = str2.split(reg2); for (String str : strs2) { System.out.println(str); } System.out.println("-----------"); // "a,b,,c,,,d" String str3 = "a,b,,c,,,d"; String reg3 = "[,]{1,3}"; String[] strs3 = str3.split(reg3); for (String str : strs3) { System.out.println(str); } System.out.println("-----------"); // "a,,,,,,,,,b,,,,,,,,,c,,,,,d,,,,,,,,e" String str4 = "a,,,,,,,,,b,,,,,,,,,c,d,,,,,,,,e"; String reg4 = "[,]+"; String[] strs4 = str4.split(reg4); for (String str : strs4) { System.out.println(str); }
Pattern类和Matcher类
- 模式和匹配器的典型调用顺序
//正则表达式 String reg = "[a]{3}"; //正则表达式 转换为 正则对象 Pattern pattern = Pattern.compile(reg); //匹配字符串,匹配对象 Matcher matcher = pattern.matcher("aaa"); //开始匹配 boolean flag = matcher.matches(); System.out.println(flag);
正则表达式的获取功能
- 案例需求:获取一个字符串中的手机号码
String str = "abcd18812345678.abcdef18856781234..abcdefg18888888888"; String reg = "[1]{1}[356789]{1}\\d{9}"; //获取正则对象 Pattern pattern = Pattern.compile(reg); //获取匹配对象 Matcher matcher = pattern.matcher(str); //开始查找手机号 //find:在str中找子字符串,子字符串要和正则匹配 List<String> phones = new ArrayList<>(); while (matcher.find()) { //找到了手机号,获取手机号 String phone = matcher.group(); phones.add(phone); } for (String phone : phones) { System.out.println(phone); }