学习内容》:
//========学习内容=========
请求与响应(2)
请求与响应(3)
《代码内容》:
主要思路——> 通过反射配置文件 获取到请求的控制层类,并执行控制层
//===================================================================================//
服务器代码—->做了一个ServerHandler线程来模拟多浏览器同时访问服务器
Server.Class
package server;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {public void startServer(){System.out.println("服务器启动中...");try {//服务器开放连接端口ServerSocket serverSocket = new ServerSocket(9999);while (true){Socket socket = serverSocket.accept();System.out.println("接收到一个新的请求");//可能有多个用户同时访问服务器,那么每个用户的socket请求过来都不一样//这里需要用到多线程并发的效果,设计一个线程来处理每个用户发过来的请求ServerHandler handler = new ServerHandler(socket);handler.start();}} catch (IOException e) {e.printStackTrace();}}}
ServerHandler.Class——>线程类,处理每个请求
package server;import controller.IndexController;import java.io.*;import java.lang.reflect.Method;import java.net.Socket;import java.util.HashMap;import java.util.Properties;public class ServerHandler extends Thread{private Socket socket = null;public ServerHandler(Socket socket){this.socket = socket;}//重写线程的run方法 也就是我们的Handler需要做的事情public void run(){/*** 分析:我们需要启动服务器后,通过socket获取流读取请求过来的资源名* 那么--->我们就设计一个方法 来读这个请求资源名* **/this.ReadRequestContentAndParams(socket);}//设计一个方法 来读取浏览器发送过来的请求private void ReadRequestContentAndParams(Socket socket) {try {//因为 浏览器 发送过来的是一行的信息--->资源名 用高级流来读取一行BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//读取到的资源名和参数String contentAndParams = reader.readLine();System.out.println(contentAndParams);//现在我拿到了资源名和参数,我需要把他们做一个解析。this.parseContentAndParams(contentAndParams);} catch (IOException e) {e.printStackTrace();}}//设计一个方法 用来解析 资源名 和 参数private void parseContentAndParams(String contentAndParams) {//index?uname=武伟&upassword=123123String content = null;HashMap paramsMap = null;if (contentAndParams.contains("?")){content = contentAndParams.substring(0, contentAndParams.indexOf("?"));String[] params = contentAndParams.substring(content.length() + 1).split("&");for (String keyAndValue : params){String[] KV = keyAndValue.split("=");paramsMap = new HashMap<String,String>();paramsMap.put(KV[0],KV[1]);}}else{content = contentAndParams;}//解析完后 把解析好的资源名 和 参数 包装成一个request对象HttpServletRequest request = new HttpServletRequest(content,paramsMap);HttpServletResponse response = new HttpServletResponse();//解析好了之后 我们可以通过拿到的 资源名 去找 Controllerthis.findController(request,response);}//通过资源名拿到配置文件中对应的控制层的类全名,进行反射类全名,执行控制层方法private void findController(HttpServletRequest request,HttpServletResponse response) {Properties properties = new Properties();try {//加载配置文件properties.load(new FileReader("src/web.properties"));//通过配置文件的key找到对应的控制层的名字String realControllerName = properties.getProperty(request.getContent());//我拿到 类全名之后 进行反射然后执行对应的方法Class clazz = Class.forName(realControllerName);Object obj = clazz.newInstance();Method controllerMethod = clazz.getMethod("test", HttpServletRequest.class, HttpServletResponse.class);controllerMethod.invoke(obj,request,response);} catch (Exception e) {e.printStackTrace();}}}
HttpServletRequest——->实体类对象, 用来包装 请求 资源名 和 参数
package server;import java.util.HashMap;public class HttpServletRequest {/*** 这个类实体 用来存储 浏览器 请求过来的资源名和参数* **/private String content;private HashMap<String,String> paramsMap;public HttpServletRequest() {}public HttpServletRequest(String content, HashMap<String, String> paramsMap) {this.content = content;this.paramsMap = paramsMap;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public HashMap<String, String> getParamsMap() {return paramsMap;}public void setParamsMap(HashMap<String, String> paramsMap) {this.paramsMap = paramsMap;}@Overridepublic String toString() {return "HttpServletRequest{" +"content='" + content + '\'' +", paramsMap=" + paramsMap +'}';}}
学习总结:
学懂的:
明白了最重要的地方
(1)HttpServletRequest和HttpServletResponse对象是在接收到请求之后,将资源名解析,包装成Request对象
而接收到请求后该如何响应回去,这里用Response对象来做参数最终Controller层执行后将Response已经填满响应信息
那么久直接可以响应回去啦
(2)在请求响应(2)这节课中 在优化上—-将配置文件中的信息做了缓存机制
将对象做了缓存机制 —->如果对象不存在,就new一个放入缓存中,下次用的时候先判断有没有 并且static修饰
这样这个对象是—->单例设计模式——>生命周期延迟加载方式
有问题**的地方:
今天的请求响应(2)没有封装,明天起来再写**
