博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java24 手写服务器最终版本
阅读量:4307 次
发布时间:2019-06-06

本文共 13471 字,大约阅读时间需要 44 分钟。

手写服务器最终版本;
login
com.bjsxt.servlet.LoginWeb
login
/g
/y
public class CloseUtil { /** * 关闭IO流 */ /* public static void closeIO(Closeable... io){ for(Closeable temp:io){ try { if (null != temp) { temp.close(); } } catch (Exception e) { } } }*/ /** * 使用泛型方法实现关闭IO流 * @param io */ public static
void closeIO(T... io){ for(Closeable temp:io){ try { if (null != temp) { temp.close(); } } catch (Exception e) { } } } public static void closeSocket(ServerSocket socket){ try { if (null != socket) { socket.close(); } } catch (Exception e) { } } public static void closeSocket(Socket socket){ try { if (null != socket) { socket.close(); } } catch (Exception e) { }} public static void closeSocket(DatagramSocket socket){ try { if (null != socket) { socket.close(); } } catch (Exception e) { } }}/** * 抽象为一个父类 * @author Administrator * */public abstract class Servlet { public void service(Request req,Response rep) throws Exception{ this.doGet(req,rep); this.doPost(req,rep); } protected abstract void doGet(Request req,Response rep) throws Exception; protected abstract void doPost(Request req,Response rep) throws Exception;}public class LoginWeb extends Servlet { @Override public void doGet(Request req, Response rep) throws Exception { rep.println("success....."); } @Override public void doPost(Request req, Response rep) throws Exception { // TODO Auto-generated method stub }}/** * 创建服务器,并启动 * * 1、请求 * 2、响应 * @author Administrator * */public class Server { private ServerSocket server; public static final String CRLF="\r\n"; public static final String BLANK=" "; private boolean isShutDown= false; /** * @param args */ public static void main(String[] args) { Server server = new Server(); server.start(); } /** * 启动方法 */ public void start(){ start(8888); } /** * 指定端口的启动方法 */ public void start(int port){ try { server = new ServerSocket(port); this.receive(); } catch (IOException e) { //e.printStackTrace(); stop(); } } /** * 接收客户端 */ private void receive(){ try { while(!isShutDown){ new Thread(new Dispatcher(server.accept())).start(); } } catch (IOException e) { //e.printStackTrace(); stop(); } } /** * 停止服务器 */ public void stop(){ isShutDown=true; CloseUtil.closeSocket(server); } }public class ServletContext { //为每一个servlet取个别名 // login -->com.bjsxt.server.demo03.LoginServlet private Map
servlet ; //url -->login // /log -->login // /login -->login private Map
mapping; ServletContext(){ servlet =new HashMap
(); mapping =new HashMap
(); } public Map
getServlet() { return servlet; } public void setServlet(Map
servlet) { this.servlet = servlet; } public Map
getMapping() { return mapping; } public void setMapping(Map
mapping) { this.mapping = mapping; }}public class WebApp { private static ServletContext contxt; static{ try { //获取解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //获取解析器 SAXParser sax = factory.newSAXParser(); //指定xml+处理器 WebHandler web = new WebHandler(); sax.parse(Thread.currentThread().getContextClassLoader() .getResourceAsStream("WEB_INFO/web.xml"), web); //将list 转成Map contxt =new ServletContext(); Map
servlet =contxt.getServlet(); //servlet-name servlet-class for(Entity entity:web.getEntityList()){ servlet.put(entity.getName(), entity.getClz()); } //url-pattern servlet-name Map
mapping =contxt.getMapping(); for(Mapping mapp:web.getMappingList()){ List
urls =mapp.getUrlPattern(); for(String url:urls ){ mapping.put(url, mapp.getName()); } } } catch (Exception e) { } } public static Servlet getServlet(String url) throws InstantiationException, IllegalAccessException, ClassNotFoundException{ if((null==url)||(url=url.trim()).equals("")){ return null; } //根据字符串(完整路径)创建对象 //return contxt.getServlet().get(contxt.getMapping().get(url)); String name=contxt.getServlet().get(contxt.getMapping().get(url)); return (Servlet)Class.forName(name).newInstance();//确保空构造存在 }}public class WebHandler extends DefaultHandler{ private List
entityList; private List
mappingList; private Entity entity; private Mapping mapping; private String beginTag ; private boolean isMap; @Override public void startDocument() throws SAXException { //文档解析开始 entityList =new ArrayList
() ; mappingList =new ArrayList
() ; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { //开始元素 if(null!=qName){ beginTag=qName; if(qName.equals("servlet")){ isMap=false; entity=new Entity(); }else if(qName.equals("servlet-mapping")){ isMap=true; mapping=new Mapping(); } } } @Override public void characters(char[] ch, int start, int length) throws SAXException { //处理内容 if(null!=beginTag){ String str =new String(ch,start,length); if(isMap ){ if(beginTag.equals("servlet-name")){ mapping.setName(str); }else if(beginTag.equals("url-pattern")){ mapping.getUrlPattern().add(str); } }else{ if(beginTag.equals("servlet-name")){ entity.setName(str); }else if(beginTag.equals("servlet-class")){ entity.setClz(str); } } } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { //结束元素 if(null!=qName){ if(qName.equals("servlet")){ entityList.add(entity); }else if(qName.equals("servlet-mapping")){ mappingList.add(mapping); } } beginTag=null; } @Override public void endDocument() throws SAXException { //文档解析结束 } /*public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { //获取解析工厂 SAXParserFactory factory =SAXParserFactory.newInstance(); //获取解析器 SAXParser sax =factory.newSAXParser(); //指定xml+处理器 WebHandler web = new WebHandler(); sax.parse(Thread.currentThread().getContextClassLoader() .getResourceAsStream("com/bjsxt/server/demo4/web.xml") ,web); System.out.println(web.getEntityList()); }*/ public List
getEntityList() { return entityList; } public void setEntityList(List
entityList) { this.entityList = entityList; } public List
getMappingList() { return mappingList; } public void setMappingList(List
mappingList) { this.mappingList = mappingList; } }/** * 封装响应信息 * @author Administrator * */public class Response { //两个常量 public static final String CRLF="\r\n"; public static final String BLANK=" "; //流 private BufferedWriter bw ; //正文 private StringBuilder content; //存储头信息 private StringBuilder headInfo; //存储正文长度 private int len =0; public Response(){ headInfo =new StringBuilder(); content =new StringBuilder(); len =0; } public Response(Socket client){ this(); try { bw= new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); } catch (IOException e) { headInfo=null; } } public Response(OutputStream os){ this(); bw= new BufferedWriter(new OutputStreamWriter(os)); } /** * 构建正文 */ public Response print(String info){ content.append(info); len+=info.getBytes().length; return this; } /** * 构建正文+回车 */ public Response println(String info){ content.append(info).append(CRLF); len+=(info+CRLF).getBytes().length; return this; } /** * 构建响应头 */ private void createHeadInfo(int code){ //1) HTTP协议版本、状态代码、描述 headInfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK); switch(code){ case 200: headInfo.append("OK"); break; case 404: headInfo.append("NOT FOUND"); break; case 505: headInfo.append("SEVER ERROR"); break; } headInfo.append(CRLF); //2) 响应头(Response Head) headInfo.append("Server:bjsxt Server/0.0.1").append(CRLF); headInfo.append("Date:").append(new Date()).append(CRLF); headInfo.append("Content-type:text/html;charset=GBK").append(CRLF); //正文长度 :字节长度 headInfo.append("Content-Length:").append(len).append(CRLF); headInfo.append(CRLF); //分隔符 } //推送到客户端 void pushToClient(int code) throws IOException{ if(null==headInfo){ code =500; } createHeadInfo(code); //头信息+分割符 bw.append(headInfo.toString()); //正文 bw.append(content.toString()); bw.flush(); } public void close(){ CloseUtil.closeIO(bw); } }/** * 封装request * @author Administrator * */public class Request { //请求方式 private String method; //请求资源 private String url; //请求参数 private Map
> parameterMapValues; //内部 public static final String CRLF="\r\n"; private InputStream is; private String requestInfo; public Request(){ method =""; url =""; parameterMapValues=new HashMap
>(); requestInfo=""; } public Request(InputStream is){ this(); this.is=is; try { byte[] data = new byte[20480]; int len = is.read(data); requestInfo = new String(data, 0, len); } catch (Exception e) { return ; } //分析请求信息 parseRequestInfo(); } /** * 分析请求信息 */ private void parseRequestInfo(){ if(null==requestInfo ||(requestInfo=requestInfo.trim()).equals("")){ return ; } /** * ===================================== * 从信息的首行分解出 :请求方式 请求路径 请求参数(get可能存在) * 如:GET /index.html?name=123&pwd=5456 HTTP/1.1 * * 如果为post方式,请求参数可能在 最后正文中 * * 思路: * 1)请求方式 :找出第一个/ 截取即可 * 2)请求资源:找出第一个/ HTTP/ * ===================================== */ String paramString =""; //接收请求参数 //1、获取请求方式 String firstLine =requestInfo.substring(0,requestInfo.indexOf(CRLF)); int idx =requestInfo.indexOf("/"); // /的位置 this.method=firstLine.substring(0, idx).trim(); String urlStr =firstLine.substring(idx,firstLine.indexOf("HTTP/")).trim(); if(this.method.equalsIgnoreCase("post")){ this.url=urlStr; paramString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim(); }else if(this.method.equalsIgnoreCase("get")){ if(urlStr.contains("?")){ //是否存在参数 String[] urlArray=urlStr.split("\\?"); this.url=urlArray[0]; paramString=urlArray[1];//接收请求参数 }else{ this.url=urlStr; } } //不存在请求参数 if(paramString.equals("")){ return ; } //2、将请求参数封装到Map中 parseParams(paramString); } private void parseParams(String paramString){ //分割 将字符串转成数组 StringTokenizer token=new StringTokenizer(paramString,"&"); while(token.hasMoreTokens()){ String keyValue =token.nextToken(); String[] keyValues=keyValue.split("="); if(keyValues.length==1){ keyValues =Arrays.copyOf(keyValues, 2); keyValues[1] =null; } String key = keyValues[0].trim(); String value = null==keyValues[1]?null:decode(keyValues[1].trim(),"gbk"); //转换成Map 分拣 if(!parameterMapValues.containsKey(key)){ parameterMapValues.put(key,new ArrayList
()); } List
values =parameterMapValues.get(key); values.add(value); } } /** * 解决中文 * @param value * @param code * @return */ private String decode(String value,String code){ try { return java.net.URLDecoder.decode(value, code); } catch (UnsupportedEncodingException e) { //e.printStackTrace(); } return null; } /** * 根据页面的name 获取对应的多个值 * @param args */ public String[] getParameterValues(String name){ List
values=null; if((values=parameterMapValues.get(name))==null){ return null; }else{ return values.toArray(new String[0]); } } /** * 根据页面的name 获取对应的单个值 * @param args */ public String getParameter(String name){ String[] values =getParameterValues(name); if(null==values){ return null; } return values[0]; } public String getUrl() { return url; } public void close(){ CloseUtil.closeIO(is); }}/*
login
/login
login
/log
*/public class Mapping { private String name; private List
urlPattern; public Mapping(){ urlPattern =new ArrayList
(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public List
getUrlPattern() { return urlPattern; } public void setUrlPattern(List
urlPattern) { this.urlPattern = urlPattern; } }/*
login
com.bjsxt.server.demo4.LoginServlet
*/public class Entity { private String name; private String clz; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClz() { return clz; } public void setClz(String clz) { this.clz = clz; } }/** * 一个请求与响应 就一个此对象 * @author Administrator * */public class Dispatcher implements Runnable{ private Socket client; private Request req; private Response rep; private int code=200; Dispatcher(Socket client){ this.client=client; try { req =new Request(client.getInputStream()); rep =new Response(client.getOutputStream()); } catch (IOException e) { //e.printStackTrace(); code =500; return ; } } @Override public void run() { try { Servlet serv =WebApp.getServlet(req.getUrl()); if(null==serv){ this.code=404; //找不到处理 }else{ serv.service(req, rep); } rep.pushToClient(code); //推送到客户端 }catch (Exception e) { e.printStackTrace(); this.code=500; } try { rep.pushToClient(500); } catch (IOException e) { e.printStackTrace(); } req.close(); rep.close(); CloseUtil.closeSocket(client); }}

 

转载于:https://www.cnblogs.com/yaowen/p/4833664.html

你可能感兴趣的文章
suse如何创建定时任务?
查看>>
suse搭建ftp服务器方法
查看>>
centos虚拟机设置共享文件夹并通过我的电脑访问[增加smbd端口修改]
查看>>
文件拷贝(IFileOperation::CopyItem)
查看>>
MapReduce的 Speculative Execution机制
查看>>
大数据学习之路------借助HDP SANDBOX开始学习
查看>>
Hadoop基础学习:基于Hortonworks HDP
查看>>
为什么linux安装程序 都要放到/usr/local目录下
查看>>
Hive安装前扫盲之Derby和Metastore
查看>>
永久修改PATH环境变量的几种办法
查看>>
大数据学习之HDP SANDBOX开始学习
查看>>
Hive Beeline使用
查看>>
Centos6安装图形界面(hdp不需要,hdp直接从github上下载数据即可)
查看>>
CentOS7 中把yum源更换成163源
查看>>
关于yum Error: Cannot retrieve repository metadata (repomd.xml) for repository:xxxxxx.
查看>>
linux下载github中的文件
查看>>
HDP Sandbox里面git clone不了数据(HTTP request failed)【目前还没解决,所以hive的练习先暂时搁置了】
查看>>
动态分区最佳实践(一定要注意实践场景)
查看>>
HIVE—索引、分区和分桶的区别
查看>>
Hive进阶总结(听课总结)
查看>>