模拟服务器Tomcat
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Create by xiye on 2019/12/9 11:22
*/
public class MyTomcat {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(1314);
while (true) {
Socket socket = serverSocket.accept();
new Thread(() -> {
try {
// 获取请求
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
byte[] bytes = new byte[1024];
String readLine = br.readLine();
//System.out.println(readLine);
// 获取请求体第一行的地址
String path = readLine.split(" ")[1].substring(1);
//System.out.println(path.lastIndexOf("?"));
path = path.split("\\?")[0]; // 字体文件含有?,去除掉
System.out.println(getHost(socket) + "请求:" + path);
File file = new File(path);
if (file.exists()) {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
OutputStream os = socket.getOutputStream();
// 写入HTTP协议响应头,固定写法
os.write("HTTP/1.1 200 OK\r\n".getBytes());
if (file.getName().endsWith(".css")) {
os.write("Content-Type:text/css\r\n".getBytes());
} else {
os.write("Content-Type:text/html\r\n".getBytes());
}
// 必须要写入空行,否则浏览器不解析
os.write("\r\n".getBytes());
// 文件内容
byte[] response = new byte[4 * 1024];
int len;
while ((len = bis.read(response))!= -1) {
os.write(response, 0, len);
}
os.close();
bis.close();
} else {
System.err.println("找不到" + file.getName());
}
br.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
private static String getHost(Socket socket) {
return socket.getInetAddress().getHostAddress() + ":" + socket.getPort();
}
}
反射
反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的方法,属性,构造方法等成员。
利用反射获取到属性、调用方法体的使用:
import com.xiye.bean.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Create by xiye on 2019/12/9 15:53
*/
public class Demo1_反射 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
// 方式一
Class stu1 = Student.class;
// 方式二
Class stu2 = new Student().getClass();
// 方式三
Class stu3 = Class.forName("com.xiye.bean.Student");
System.out.println("获取全路径名和类名:" + stu1.getName());
System.out.println("只获取类名:" + stu2.getSimpleName());
System.out.println("就是new一个对象,对应无参构造器:" + stu3.newInstance());
//methodConstructors(stu3);
methodMethod(stu3);
//methodField(stu3);
}
private static void methodField(Class stu3) throws InstantiationException, IllegalAccessException, NoSuchFieldException {
Object o1 = stu3.newInstance();
// 获取public修饰、指定名称的属性
System.out.println("\n=============获取public修饰、指定名称的属性===========");
Field sex = stu3.getField("sex");
sex.set(o1, "男"); // 类似o1.sex = "男";
System.out.println(sex.get(o1)); // 获取属性值
System.out.println(o1);
// 获取所有权限、指定名称的属性
System.out.println("\n=============获取所有权限、指定名称的属性===========");
Field name = stu3.getDeclaredField("name");
name.setAccessible(true);
name.set(o1, "李峰");
System.out.println(o1.toString());
// 获取public修饰的所有属性
System.out.println("\n=============获取public修饰的所有属性===========");
Field[] f1 = stu3.getFields();
for (Field f : f1) {
System.out.println(f.getType().getSimpleName() + " " + f.getName());
}
// 获取所有属性
System.out.println("\n=============获取所有属性===========");
Field[] f2 = stu3.getDeclaredFields();
for (Field f : f2) {
System.out.println(f.getType().getSimpleName() + " " + f.getName());
}
}
private static void methodMethod(Class stu3) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
// 获取public修饰的指定方法名和参数的方法
System.out.println("\n=============获取public修饰的指定方法名和参数的方法===========");
Method m1 = stu3.getMethod("getName");
System.out.println(m1.toString());
// 获取指定方法名和参数的方法
System.out.println("\n=============获取指定方法名和参数的方法===========");
Method m2= stu3.getDeclaredMethod("setName", String.class);
Object o1 = stu3.newInstance();
m2.invoke(o1, "李四");
System.out.println(m2.toString());
System.out.println(o1.toString());
// 获取到方法体
Method m0 = stu3.getDeclaredMethod("study");
m0.setAccessible(true); // 暴力访问私有方法
m0.invoke(null); // 设置为null访问静态的
// 如果调用普通方法,invoke指定方法所属的对象,若有参数,添加参数即可(getMethod获取方法时也要指定参数的类型)
Method m = stu3.getMethod("common", String.class);
m.invoke(o1, "我是参数"); // 类似o1.common("我是参数");
// 获取所有public修饰的方法(包含父类)
System.out.println("\n=============获取所有public修饰的方法(包含父类)===========");
Method[] m3= stu3.getMethods();
for (Method method : m3) {
System.out.println(method);
}
// 获取类中所有的方法(不包含包含父类)
System.out.println("\n=============获取类中所有的方法(不包含包含父类)===========");
Method[] m4= stu3.getDeclaredMethods();
for (Method method : m4) {
System.out.println(method);
}
}
private static void methodConstructors(Class stu3) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
// 获取有参构造器
System.out.println("\n=============获取有参构造器===========");
Constructor c1 = stu3.getDeclaredConstructor(String.class, Integer.class);
Object o1 = c1.newInstance("李四", 21); // 类似new Student("李四", 21);
System.out.println(o1.toString());
// 获取私有的构造器
System.out.println("\n=============获取私有的构造器===========");
Constructor c2 = stu3.getDeclaredConstructor(String.class);
c2.setAccessible(true); // 暴力反射,破坏了封装性
Object o2 = c2.newInstance("张三");
System.out.println(o2.toString());
// 获取所有构造器
System.out.println("\n=============获取所有构造器===========");
Constructor[] c3 = stu3.getDeclaredConstructors();
for (Constructor c : c3) {
System.out.println(c);
}
// 获取public修饰的指定构造器
System.out.println("\n=============获取public修饰的指定构造器===========");
Constructor c4 = stu3.getConstructor();
Constructor c5 = stu3.getConstructor(String.class, Integer.class);
System.out.println(c4.toString());
System.out.println(c5.toString());
// 获取public修饰的所有构造器
System.out.println("\n=============获取public修饰的所有构造器===========");
Constructor[] c6 = stu3.getConstructors();
for (Constructor c : c6) {
System.out.println(c);
}
}
}
package com.xiye.bean;
/**
* Create by xiye on 2019/12/9 15:54
*/
public class Student {
private String name;
private Integer age;
public String sex;
public Student() {}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
private static void study() {
System.out.println("私有静态方法:学习使我快乐");
}
public void common(String str) {
System.out.println("普通方法:" + str);
}
private Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
反射工厂模拟
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.Set;
/**
* Create by xiye on 2019/12/9 18:00
*/
public class Demo2_示例 {
public static void main(String[] args) throws Exception {
Object obj = getObject();
System.out.println(obj.toString());
}
private static Object getObject() throws Exception {
Properties properties = new Properties();
properties.load(new InputStreamReader(Demo2_示例.class.getResourceAsStream("/info.properties"), "GBK"));
Set<String> keys = properties.stringPropertyNames();
String pkg = properties.getProperty("class");
//
Class aClass = Class.forName(pkg);
Object obj = aClass.newInstance();
for (String k : keys) {
if (!"class".equals(k)) {
String value = properties.getProperty(k);
/*Field field = aClass.getDeclaredField(k);
field.setAccessible(true);
if (field.getType() == Integer.class) {
field.set(obj, Integer.parseInt(value));
} else {
field.set(obj, value);
}*/
setField(aClass, obj, k, value);
}
}
return obj;
}
/**
* 利用封装方法进行属性赋值
* @param aClass 反射类
* @param obj 类对象
* @param k 属性
* @param value 属性值
* @throws Exception
*/
private static void setField(Class aClass, Object obj, String k, String value) throws Exception {
// 处理封装方法的属性
for (Method method : aClass.getMethods()) {
if (method.getName().equals(getSetMethodName(k))) {
if (method.equals(aClass.getMethod(getSetMethodName(k), method.getParameterTypes()[0]))) {
if (method.getParameterTypes()[0] == Integer.class) {
method.invoke(obj, Integer.parseInt(value));
} else {
method.invoke(obj, value);
}
}
break;
}
}
// 处理没有封装方法并且是public的属性
for (Field field : aClass.getFields()) {
if (field.getName().equals(k)) {
if (field.equals(aClass.getField(k))) {
field.set(obj, value);
}
}
}
}
private static String getSetMethodName(String s) {
/*if (s.length() == 1) {
return s.toUpperCase();
}*/
return "set" + s.substring(0, 1).toUpperCase() + s.substring(1, s.length());
}
}