当前位置:首页 > CN2资讯 > 正文内容

Java服务器运作 java怎么写服务器

2天前CN2资讯


1.预备知识_Socket知识回顾

1.1编写服务器用到的知识点

1)Socket编程
2)HTML
3)HTTP协议
4)反射
5)XML解析
6)服务器编写

1.2复习Socket编程

1)C/S结构:客户端与服务器端一次双向通信
2)B/S结构:浏览器与服务器

httpClient_1

Client.java

package com.bjsxt.test; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .Socket; import .UnknownHostException; public class Client { public static void main(String[] args) { //(1)创建Socket对象 Socket client=null; //(2)获取输出流-->请求 DataOutputStream dos=null; DataInputStream dis=null; try { client = new Socket("localhost", 8888); dos = new DataOutputStream(client.getOutputStream()); dos.writeUTF("我是客户端:服务器你好!"); //(3)获取输入流-->响应 dis = new DataInputStream(client.getInputStream()); System.out.println(dis.readUTF()); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(4)关闭流 IOClose.closeAll(dis,dos,client); } } }

IOClose.java

package com.bjsxt.test; import java.io.Closeable; import java.io.IOException; public class IOClose { //关闭全部的工具类 public static void closeAll(Closeable...c){ for (Closeable closeable : c) { if (closeable!=null) { try { closeable.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

httpServer_1

Server.java

package com.bjsxt.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .ServerSocket; import .Socket; public class Server { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; //(3)获取Scoket对象 //(4)获取输入流 -->得到客户端的请求 DataInputStream dis=null; DataOutputStream dos=null; try { server = new ServerSocket(8888); client = server.accept(); dis = new DataInputStream(client.getInputStream()); System.out.println(dis.readUTF()); //(5)获取输出流-->给客户端响应结果 dos = new DataOutputStream(client.getOutputStream()); dos.writeUTF("客户端您好:我是服务器,我收到了你的信息"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(dos,dis,client,server); } } }

IOClose.java

package com.bjsxt.server; import java.io.Closeable; import java.io.IOException; public class IOClose { //关闭全部的工具类 public static void closeAll(Closeable...c){ for (Closeable closeable : c) { if (closeable!=null) { try { closeable.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

Server2.java

package com.bjsxt.server; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import .ServerSocket; import .Socket; public class Server2 { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; BufferedReader br=null; try { server = new ServerSocket(8888); client = server.accept(); //获取来自浏览器的请求信息 br=new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8")); String str=null; while((str=br.readLine()).length()>0){ System.out.println(str); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(br,client,server); } } }

2. 预备知识_HTML 简单入门

2.1HTML

HTML: HyperText Markup Language 超文本标记语言用于描述网页文档的一种标记语言

2.2 第一个 HTML 文档

<html> <head> <title>第一个 HTML</title> </head> <body> <h1>hello world</h1> </body> </html>

2.3 表单 form

作用:与用户之间进行交互
method:请求方式 get/post
get 数据量小,安全性低,默认方式
post 数据量大,安全性高
action:请求的服务器路径

<form action="http://localhost:8888/index.html" method="post"> <p>用户名: <input type="text" name="uname" id="name"/> </p> <p>密码 : <input type="password" name="pwd" id="pass"/> </p> <p><input type="submit" value="登录" /> </p> </form>

id : (用户的的浏览器在文档里区分唯一性)前端区分唯一性,js 中
name:名称,后端(服务器)区分唯一性,获取值,只要提交数据
给后台(服务器)必须存在 name

httpServer_2

Server.java

package com.bjsxt.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .ServerSocket; import .Socket; public class Server { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; //(3)获取Scoket对象 //(4)获取输入流 -->得到客户端的请求 DataInputStream dis=null; DataOutputStream dos=null; try { server = new ServerSocket(8888); client = server.accept(); dis = new DataInputStream(client.getInputStream()); System.out.println(dis.readUTF()); //(5)获取输出流-->给客户端响应结果 dos = new DataOutputStream(client.getOutputStream()); dos.writeUTF("客户端您好:我是服务器,我收到了你的信息"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(dos,dis,client,server); } } }

Server2.java

package com.bjsxt.server; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import .ServerSocket; import .Socket; public class Server2 { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; BufferedReader br=null; try { server = new ServerSocket(8888); client = server.accept(); //获取来自浏览器的请求信息 br=new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8")); String str=null; while((str=br.readLine()).length()>0){ System.out.println(str); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(br,client,server); } } }

Server3.java

package com.bjsxt.server; import java.io.IOException; import java.io.InputStream; import .ServerSocket; import .Socket; public class Server3 { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; InputStream is=null; try { server = new ServerSocket(8888); client = server.accept(); //获取来自浏览器的请求信息 is=client.getInputStream(); byte [] buf=new byte[20480]; int len=is.read(buf); System.out.println(new String(buf,0,len)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(is,client,server); } } }

IOClose.java

package com.bjsxt.server; import java.io.Closeable; import java.io.IOException; public class IOClose { //关闭全部的工具类 public static void closeAll(Closeable...c){ for (Closeable closeable : c) { if (closeable!=null) { try { closeable.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

index.html

<html> <head> <title>我的第一个html</title> </head> <body> <h1>hello world</h1> <form action="http://localhost:8888/log" method="get"> <p>用户名:<input type="text" id="uname" name="username" /></p> <p>密码:<input type="password" id="pwd" name="password"/></p> <p>兴趣爱好<input type="checkbox" name="hobby" value="ball"/>球 <input type="checkbox" name="hobby" value="read"/>读书 <input type="checkbox" name="hobby" value="paint"/>画画</p> <p><input type="submit" value="登录"/></p> </form> </body> </html>

3.预备知识_HTTP协议入门

3.1协议

1)应用层:HTTP、FTP、TELNET、SNMP、DNS
2)传输层:TCP、UDP
3) 网络层:IP

3.2HTTP协议简介

HTTP:Hypertext Transfer Protocol超文本传输协议,是网络应用层的协议,建立在TCP/IP协议基础上,HTTP使用可靠的TCP连接,默认端口为80.

用户打开web浏览器(常见的HTTP客户端),输入URL地址,就能接收到远程HTTP服务器端发送过来的网页,即HTTP遵循请求(Request)/应答(Response)模型。web浏览器向web服务器发送请求,web服务器处理请求并返回适当的应答,所有HTTP连接都被构造成一套请求与应答。


HTTP客户端和服务器分别由不同的软件开发商提供,它们都可以用任意的编程语言编写,如用.NET 编写的客户程序与用Java编写的服务器程序顺利通信,就必须遵守HTTP协议,这样才能彼此都懂对方发送的消息,HTTP协议严格规定了HTTP请求和HTTP响应的数据格式。

3.3HTTP请求格式

1)请求方式、URL(统一资源定位符)、HTTP协议/版本

2)请求头 Request Header

a)请求头包含许多有关客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所有的语言,请求正文的长度等。

3)请求正文 Requet Content (只有在 post 方式才有)

请求头和请求正文之间必须有符号行(回车符或行结束符),将请求头与请求正文分开,这个行非常重要,它表示 请求头已结束,接下来的是请求正文。通常post方式的数据存放于此,请求正文中可以包含客户提交的查询字符串等信息。在实际应用中,HTTP请求正文可以包含更多的内容。

3.4HTTP 响应格式

  • HTTP 协议版本、状态代码、描述
  • 响应头(Response Head)
  • 响应正文(Respose Content)
  • httpServer_2

    Server.java

    package com.bjsxt.server; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import .ServerSocket; import .Socket; public class Server { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; //(3)获取Scoket对象 //(4)获取输入流 -->得到客户端的请求 DataInputStream dis=null; DataOutputStream dos=null; try { server = new ServerSocket(8888); client = server.accept(); dis = new DataInputStream(client.getInputStream()); System.out.println(dis.readUTF()); //(5)获取输出流-->给客户端响应结果 dos = new DataOutputStream(client.getOutputStream()); dos.writeUTF("客户端您好:我是服务器,我收到了你的信息"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(dos,dis,client,server); } } }

    Server2.java

    package com.bjsxt.server; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import .ServerSocket; import .Socket; public class Server2 { public static void main(String[] args) { //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; BufferedReader br=null; try { server = new ServerSocket(8888); client = server.accept(); //获取来自浏览器的请求信息 br=new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8")); String str=null; while((str=br.readLine()).length()>0){ System.out.println(str); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(br,client,server); } } }

    Server3.java

    package com.bjsxt.server; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import .ServerSocket; import .Socket; public class Server3 { public static void main(String[] args) { String CRLF="\r\n";//换行 String BLANK=" ";//空格 //(1)创建ServerSocket对象 ServerSocket server=null; //(2)监听是否有客户端发送请求 Socket client=null; InputStream is=null; try { server = new ServerSocket(8888); client = server.accept(); //获取来自浏览器的请求信息 is=client.getInputStream(); byte [] buf=new byte[20480]; int len=is.read(buf); System.out.println(new String(buf,0,len)); /**对Web浏览器的请求作出响应*/ StringBuilder sb=new StringBuilder(); StringBuilder sbContent=new StringBuilder();//响应的文本 sbContent.append("<html><head><title>响应结果</title></head>"); sbContent.append("<body>登录成功</body></html>"); //(1)拼接响应头 sb.append("HTTP/1.1").append(BLANK).append(200).append(BLANK).append("OK"); sb.append(CRLF);//换行 sb.append("Content-Type: text/html;charset=utf-8"); sb.append(CRLF);//换行 sb.append("Content-Length:").append(sbContent.toString().getBytes().length).append(CRLF); sb.append(CRLF);//换行,代表响应头与响应的正文部门之间的空行 sb.append(sbContent); //通过流输出 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(client.getOutputStream(),"utf-8")); bw.write(sb.toString()); bw.flush(); bw.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //(6)关闭流 IOClose.closeAll(is,client,server); } } }

    IOClose.java

    package com.bjsxt.server; import java.io.Closeable; import java.io.IOException; public class IOClose { //关闭全部的工具类 public static void closeAll(Closeable...c){ for (Closeable closeable : c) { if (closeable!=null) { try { closeable.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

    4.Tomcat服务器的快速使用

    4.1Tomcat简介

    Tomcat是在SUN公司的JSWDK( JavaServer Web
    DevelopmentKit ,是 SUN 公司推出的小型 Servlet/JSP 调试工
    具)的基础上发展起来的一个优秀的Servlet容器,Tomcat本身完全用Java语言编写。

    4.2Tomcat使用

    1)配置Tomcat

    a) JAVA_HOME Java JDK 的根目录


    b) CATALINA_HOME Tomcat 根目录

    bin:存放Tomcat脚本目录

  • 启动和关闭 Tomcat
    启动 Tomcat 服务器:startup.bat
    关闭 Tomcat 服务器:shutdown.bat

    conf:存放配置文件

  • conf—>server.xml:存放配置信息

    存放配置端口信息



    lib:存放Tomcat运行所需要的jar包


    logs:存放日志文件

    temp:存放Tomcat临时文件

    webapps:部署项目到服务器
    在 webapps 目录下新建目录存放.html 面页
    访问页面

    **work:**工作目录,将JSP文件的Java文件转换为class文件的工作目录。

    部署项目到Tomcat

    在webapps目录下创建自己的文件夹


    在该文件夹下新建一个HTML文档

    index.html

    <html> <head> <title>发布到Tomcat中的项目的主页</title> </head> <body> <h1>hello tomcat</h1> </body> </html>

    bin目录下双击

    启动Tomcat服务


    在地址栏输入http://locathost:8080/myfirst/index.html

    5.Tomcat服务器运行原理

    5.1Tomcat的运行原理

    客户浏览器发出要求访问特定德Servlet的请求。

    1)Tomcat服务器接收到客户请求并解析

    2)Tomcat服务器创建一个ServletRequest对象,在ServletRequest对象中包含了客户请求信息及其他关于客户的信息,如请求头,请求正文,以及客户机的IP地址等。

    3)Tomcat服务器创建一个ServletResponse 对象

    4)Tomcat服务器调用客户所请求的Servlet的service服务方法,并且把ServletRequest对象和ServletResponse对象做为参数传给该服务方法。

    5) Servlet 从 ServletRequest 对象中可获取客户的请求信息。

    6) Servlet 利用 ServletResponse 对象来生成响应结果。

    7) Tomcat 服务器把 Servlet 生成的响应结果发送给客户。

    8)

    6.预备_http工具查看网络交互过程

    6.1下载并安装

    httpwatch安装包:https://pan.baidu.com/s/1ogcMmZSutx6WvIvh2VNpGg 密码:ggv4

    6.2HttpWatch 的使用

  • IE 浏览器查看浏览器栏HttpWatch Professional
  • 最新版已经可以支持Google、Microsoft Edge等浏览器了下面是官方使用文档
  • 输入网址
  • 分析数据
  • 7. 手写服务器_ 整体架构和接口_ 编写 XML配置文件

    7.1 搭建项目框架

    7.2 编写 XML 文档

    <?xml version="1.0" encoding="UTF-8"?> <web-app> <servlet> <servlet-name>login</servlet-name> <serlvet-class>com.bjsxt.servlet.LoginServlet</serlvet-class> </servlet> <servlet-mapping> <serlvet-name>login</serlvet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <servlet-mapping> <serlvet-name>login</serlvet-name> <url-pattern>/log</url-pattern> </servlet-mapping> </web-app>

    7.3 编写 IOCloseUtil 类

    package com.bjsxt.util; import java.io.Closeable; import java.io.IOException; public class IOCloseUtil {//用于关系流 public static void closeAll(Closeable...close){ for (Closeable closeable : close) { if (closeable!=null) { try { closeable.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }

    8.DOM4J 解析 XML 配置文件

    8.1Entity 实体类的编写

    package com.bjsxt.server; /** * <servlet> <servlet-name>login</servlet-name> <serlvet-class>com.bjsxt.servlet.LoginServlet</serlvet-class> </servlet> * @author Administrator * */ public class Entity { /**servlet-name和一个servlet-name所对应的一个实体类*/ private String name;//servlet-name private String clazz;//servlet-class public String getName() { return name; } public void setName(String name) { = name; } public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } public Entity(String name, String clazz) { super(); = name; this.clazz = clazz; } public Entity() { super(); } }

    8.2Mapping 实体类的编写

    package com.bjsxt.server; import java.util.ArrayList; import java.util.List; /** * <servlet-mapping> <serlvet-name>login</serlvet-name> <url-pattern>/login</url-pattern> <url-pattern>/log</url-pattern> </servlet-mapping> * @author Administrator * */ public class Mapping {//映射关系,多个路径访问共享资源 private String name;//servlet-name private List<String> urlPattern;//url-pattern public String getName() { return name; } public void setName(String name) { = name; } public List<String> getUrlPattern() { return urlPattern; } public void setUrlPattern(List<String> urlPattern) { this.urlPattern = urlPattern; } public Mapping(){ urlPattern=new ArrayList<String>(); } public Mapping(String name, List<String> urlPattern) { super(); = name; this.urlPattern = urlPattern; } }

    8.3 解析 XML 文件

    package com.bjsxt.server; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import .SAXReader; public class WebDom4j {//用于解析XML private List<Entity> entityList;//用于存储是N多Entity,而每一个Entity都是servlet-name与servlet-class private List<Mapping> mappingList;//用于存储N多Mapping,而每一个Mapping都是一个servlet-name与N多个url-pattern public List<Entity> getEntityList() { return entityList; } public void setEntityList(List<Entity> entityList) { this.entityList = entityList; } public List<Mapping> getMappingList() { return mappingList; } public void setMappingList(List<Mapping> mappingList) { this.mappingList = mappingList; } //构造方法 public WebDom4j() { entityList=new ArrayList<Entity>(); mappingList=new ArrayList<Mapping>(); } //获取Document对象的方法 private Document getDocument(){ try { //(1)创建SAXReader对象 SAXReader reader=new SAXReader(); //(2)调用read方法 return reader.read(new File("src/WEB_INFO/web.xml")); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public void parse(Document doc){ //(1)获取根元素 Element root=doc.getRootElement(); //web-app //(2)获取servlet子元素 for(Iterator<Element> ite=root.elementIterator("servlet");ite.hasNext();){ Element subElement=ite.next();//得到每一个servlet //创建一个实体类 Entity ent=new Entity(); //用于存储servlet-name与servlet-class for(Iterator<Element> subIte=subElement.elementIterator();subIte.hasNext();){ Element ele=subIte.next(); //可能是servlet-name,也可能是servlet-class if("servlet-name".equals(ele.getName())){ ent.setName(ele.getText()); //给实体类中的name赋值 }else if("serlvet-class".equals(ele.getName())){ ent.setClazz(ele.getText()); } } //将Entity添加到集合中 entityList.add(ent); } //测试 /**for (Entity entity : entityList) { System.out.println(entity.getName()+"\t"+entity.getClazz()); }*/ //解析servlet-mapping for(Iterator<Element> ite=root.elementIterator("servlet-mapping");ite.hasNext();){ Element subEle=ite.next();//得到每一个servlet-mapping //创建一个Mapping类的对象 Mapping map=new Mapping(); //解析servlet-mapping下的子元素 for(Iterator<Element> subIte=subEle.elementIterator();subIte.hasNext();){ Element ele=subIte.next(); //servlet-name,也有可能是url-pattern if("serlvet-name".equals(ele.getName())){ map.setName(ele.getText()); }else if("url-pattern".equals(ele.getName())){ //获取集合对象,调用集合对象的添加方法,添加元素素 map.getUrlPattern().add(ele.getText()); } } //Mapping添加到集合中 mappingList.add(map); } //测试 for (Mapping m : mappingList) { System.out.println(m.getName()); for(String s:m.getUrlPattern()){ System.out.println(s); } } } //用于测试 public static void main(String[] args) { WebDom4j web=new WebDom4j(); web.parse(web.getDocument()); } }

    9. 反射创建 Servlet 对象

    9.1 编写 ServletContext 类

    Servlet 上下文,就是一个容器,用于存储映射关系

    package com.bjsxt.server; import java.util.HashMap; import java.util.Map; /** * Servlet上下用,就是一个容器, * @author Administrator * */ public class ServletContext { //Entity与Mapping的映射关系 private Map<String,String> servlet;//key是servlet-name (Entity中的name),值serlvet-class Entity中的clazz private Map<String,String> mapping;//key是url-pattern (Mapping中的List集合中的每一个元素),value是serlvet-name,是Mapping中的name public Map<String, String> getServlet() { return servlet; } public void setServlet(Map<String, String> servlet) { this.servlet = servlet; } public Map<String, String> getMapping() { return mapping; } public void setMapping(Map<String, String> mapping) { this.mapping = mapping; } public ServletContext() { servlet=new HashMap<String,String>(); mapping=new HashMap<String,String>(); } }

    9.2 编写 WebApp 类

  • 初始化程序运行的数据
  • 根据不同的 url 创建所请求的 Servlet 对象
  • package com.bjsxt.server; import java.util.List; import java.util.Map; import com.bjsxt.servlet.Servlet; public class WebApp {//App的意思是应用程序 private static ServletContext contxt; static{ contxt=new ServletContext(); //分别获取对应关系的Map集合 Map<String,String> servlet=contxt.getServlet(); Map<String,String> mapping=contxt.getMapping(); //创建解析XML文件对象 WebDom4j web=new WebDom4j(); web.parse(web.getDocument());//解析xml //获取解析XML之后的List集合 List<Entity> entityList=web.getEntityList(); List<Mapping> mappingList=web.getMappingList(); //将List集合中的数据存储到Map集合 for (Entity entity : entityList) { servlet.put(entity.getName(), entity.getClazz()); } // System.out.println(servlet); for( Mapping map:mappingList){ //遍历url-pattern的集合 List<String> urlPattern=map.getUrlPattern(); for(String s:urlPattern){ mapping.put(s, map.getName()); } } //System.out.println(mapping); } /** * 根据url创建不同的Servlet对象 * @param url * @return */ public static Servlet getServlet(String url){ if (url==null||url.trim().equals("")) { return null; } //调用无参构造方法创建Servlet对象 try { //如果url正确 //根据url的key获取servlet-name的值 /log=login, /reg=register String servletName=contxt.getMapping().get(url); //根据servletName得到对应的servlet-class String servletClass=contxt.getServlet().get(servletName); //得到的是一个完整个的包名+类的字符串 //使用反射创建 Servlet对象 Class<?> clazz=Class.forName(servletClass); Servlet servlet = (Servlet) clazz.newInstance(); return servlet; } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } //测试 public static void main(String[] args) { System.out.println(getServlet("/log")); System.out.println(getServlet("/login")); } }

    10. 封装 Request_method_url

    10.1 编写 Server

  • 启动服务
  • 关闭服务
  • package com.bjsxt.server; import java.io.IOException; import java.io.InputStream; import .ServerSocket; import .Socket; public class Server {//服务器,用于启动和停止服务 private ServerSocket server; public static void main(String[] args) { Server server=new Server();//创建服务器对象 server.start(); } public void start(){ this.start(8888); } public void start(int port){ try { server=new ServerSocket(port); this.receive(); //调用接收请求信息的方法 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void receive() { try { //(1)监听 Socket client=server.accept(); //获取用户的请求 /**InputStream is=client.getInputStream(); byte []buf =new byte [20480]; int len=is.read(buf); System.out.println(new String(buf,0,len));*/ //封装请求信息 Request req=new Request(client.getInputStream()); //req.show(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void stop(){ } }

    10.2 编写 HTML

    login.html

    <html> <head> <title>登录</title> </head> <body> <form action="http://localhost:8888/log" method="post"> <p>用户名:<input type="text" name="username" id="username"/></p> <p>密码:<input type="password" name="pwd" id="password"/></p> <p> 爱好:<input type="checkbox" name="hobby" value="ball"/>足球 <input type="checkbox" name="hobby" value="read"/>读书 <input type="checkbox" name="hobby" value="paint"/>画画 </p> <p><input type="submit" value="登录"/></p> </form> </body> </html>

    10.3 封装 Request_method_url

    package com.bjsxt.server; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; public class Request {/*请求*/ private InputStream is;//输入流 private String requestInfo;//请求字符串,请求方式,请求的路径,参数,协议,协议版本,请求的正文。。。 private String method;//请求的方式 private String url;//请求的url //输入框的name为key,值为value /* * key: username value :bjsxt * key:pwd value:123 * key:hobby value :read,ball * */ private Map<String,List<String>> parametermapValues;//参数 private static final String CRLF="\r\n";//换行 private static final String BLANK=" ";//空格 //构造方法,初始化属性 public Request() { parametermapValues=new HashMap<String,List<String>>(); method=""; url=""; requestInfo=""; } public Request(InputStream is){ this();//调用本类无参的构造方法 this.is=is; try { byte [] buf=new byte[20480]; int len=this.is.read(buf); requestInfo=new String(buf,0,len); } catch (IOException e) { return; } //调用本类中的分解请求信息的方法 this.parseRequestInfo(); } //分解请求信息的方法 /** * 请求方式 * 请求路径 * 请求的参数 * */ private void parseRequestInfo(){ String paraString="";//用于存储请求参数 //获取请求参数的第一行 String firstLine=requestInfo.substring(0, requestInfo.indexOf(CRLF)).trim();//从0开始,到第一个换行的位置 //分解出请求方式 int index=firstLine.indexOf("/"); this.method=firstLine.substring(0, index).trim(); //分解url ,get可能包含参数,也可能不包含参数post String urlString= firstLine.substring(index,firstLine.indexOf("HTTP/")).trim(); //判断请求方式是GET还 是POST if("get".equalsIgnoreCase(this.method)){ //包含请求参数 if (urlString.contains("?")) { String [] urlArray=urlString.split("\\?"); this.url=urlArray[0]; paraString=urlArray[1]; }else{ this.url=urlString; } }else{//post不包含请求参数 this.url=urlString; paraString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim(); } if (paraString.equals("")) { return; } //请求参数 //System.out.println(paraString); } //用于测试 /*public void show(){ System.out.println(this.url); System.out.println(this.method); }*/ }

    11. 封装 Request_ 存储参数_ 处理中文

    11.1 编写分解参数的方法

    package com.bjsxt.server; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import .URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class Request {/*请求*/ private InputStream is;//输入流 private String requestInfo;//请求字符串,请求方式,请求的路径,参数,协议,协议版本,请求的正文。。。 private String method;//请求的方式 private String url;//请求的url //输入框的name为key,值为value /* * key: username value :bjsxt * key:pwd value:123 * key:hobby value :read,ball * */ private Map<String,List<String>> parametermapValues;//参数 private static final String CRLF="\r\n";//换行 private static final String BLANK=" ";//空格 //构造方法,初始化属性 public Request() { parametermapValues=new HashMap<String,List<String>>(); method=""; url=""; requestInfo=""; } public Request(InputStream is){ this();//调用本类无参的构造方法 this.is=is; try { byte [] buf=new byte[20480]; int len=this.is.read(buf); requestInfo=new String(buf,0,len); } catch (IOException e) { return; } //调用本类中的分解请求信息的方法 this.parseRequestInfo(); } //分解请求信息的方法 /** * 请求方式 * 请求路径 * 请求的参数 * */ private void parseRequestInfo(){ String paraString="";//用于存储请求参数 //获取请求参数的第一行 String firstLine=requestInfo.substring(0, requestInfo.indexOf(CRLF)).trim();//从0开始,到第一个换行的位置 //分解出请求方式 int index=firstLine.indexOf("/"); this.method=firstLine.substring(0, index).trim(); //分解url ,get可能包含参数,也可能不包含参数post String urlString= firstLine.substring(index,firstLine.indexOf("HTTP/")).trim(); //判断请求方式是GET还 是POST if("get".equalsIgnoreCase(this.method)){ //包含请求参数 if (urlString.contains("?")) { String [] urlArray=urlString.split("\\?"); this.url=urlArray[0]; paraString=urlArray[1]; }else{ this.url=urlString; } }else{//post不包含请求参数 this.url=urlString; paraString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim(); } if (paraString.equals("")) { return; } //请求参数 //System.out.println(paraString); //调用本类中分解请求参数的方法 this.parseParam(paraString); } //用于测试 /*public void show(){ System.out.println(this.url); System.out.println(this.method); }*/ //username=bjsxt&pwd=123&hobby=ball&hobby=paint /** * username=bjsxt * pwd=123 * hobby=ball * hobby=paint * * username= * @param prarString */ private void parseParam(String prarString){ String [] token=prarString.split("&"); for(int i=0;i<token.length;i++){ String keyValues=token[i]; String []keyValue=keyValues.split("="); //username bjsxt pwd 123 if (keyValue.length==1) { //username= keyValue=Arrays.copyOf(keyValue, 2); keyValue[1]=null; } //将 表单元素的name与name对应的值存储到Map集合 String key=keyValue[0].trim(); String value=keyValue[1]==null?null:decode(keyValue[1].trim(), "utf-8"); //放到集合中存储 if (!parametermapValues.containsKey(key)) { parametermapValues.put(key, new ArrayList<String>()); } List<String> values=parametermapValues.get(key); values.add(value); } } //根据表单元素的name获取多个值 private String [] getParamterValues(String name){ //根据key获取value List<String> values=parametermapValues.get(name); if (values==null) { return null; }else{ return values.toArray(new String [0] ); } } private String getParamter(String name){ //调用本类中根据name获取多个值的方法 String [] values=this.getParamterValues(name); if (values==null) { return null; }else{ return values[0]; } } //处理中文,因类浏览器对中文进行了编码,进行解码 private String decode(String value,String code){ try { return URLDecoder.decode(value, code); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static void main(String[] args) { Request req=new Request(); //调用分解参数的方法 req.parseParam("username=%E5%8C%97%E4%BA%AC%E5%B0%9A%E5%AD%A6%E5%A0%82&pwd=123&hobby=ball&hobby=paint"); System.out.println(req.parametermapValues); //调用获取多个值的方法 String [] str=req.getParamterValues("hobby"); for (String string : str) { System.out.println(string); } //调用获取单个值的方法 System.out.println(req.getParamter("pwd")); } }

    11.2 编写根据页面上的 name 获取多个值的方法

    11.3 编写根据页面上的 name 获取单个值的方法

    11.4 编写解码的方法 1

    1.5 测试

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=%E5%8C%97%E 4%BA%AC%E5%B0%9A%E5%AD%A6%E5%A0%82&rsv_pq=f65f15f40003a658&rsv_t=d74
    7OilFeeFkf73QkinDYpKiB4y%2Ffj3mxWfE865IJ0VxoTk5Obwtc4z41pM&rqlang=cn&rsv_ente
    r=1&rsv_sug3=19&rsv_sug1=21&rsv_sug7=101

    12. 封装 Response

    12.1 封装 Response

  • 构造响应头
  • 推送到客户端
  • package com.bjsxt.server; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import com.bjsxt.util.IOCloseUtil; public class Response {//响应 private StringBuilder headInfo;//响应头 private StringBuilder content;//响应内容 private int length;//响应内容的长度 //流 private BufferedWriter bw; //两个常量,换行和空格 private static final String CRLF="\r\n";//换行 private static final String BLANK=" ";//空格 //构造方法 public Response() { headInfo=new StringBuilder(); content=new StringBuilder(); } //带参构造方法 public Response(OutputStream os){ this();//调用本类的无参构造方法 try { bw=new BufferedWriter(new OutputStreamWriter(os, "utf-8")); } catch (UnsupportedEncodingException e) { headInfo=null; } } //构造正文部分 public Response print(String info){ content.append(info); try { length+=info.getBytes("utf-8").length; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return this; } public Response println(String info){ content.append(info).append(CRLF); try { length+=(info+CRLF).getBytes("utf-8").length; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return this; } //构造响应头 private void createHeadInfo(int code){ headInfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK); switch (code) { case 200: headInfo.append("OK"); break; case 500: headInfo.append("SERVER ERROR"); break; default: headInfo.append("NOT FOUND"); break; } headInfo.append(CRLF); headInfo.append("Content-Type:text/html;charset=utf-8").append(CRLF); headInfo.append("Content-Length:"+length).append(CRLF); headInfo.append(CRLF); } /** * 推送到客户机的浏览器 * @param code */ public void pushToClient(int code){ if (headInfo==null) { code=500; } try { //调用本类中的构造响应头 this.createHeadInfo(code); bw.write(headInfo.toString()); bw.write(content.toString()); bw.flush(); this.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void close(){ IOCloseUtil.closeAll(bw); } }

    12.2 编写相应的 Servlet 构造响应内容

    package com.bjsxt.servlet; import com.bjsxt.server.Request; import com.bjsxt.server.Response; public abstract class Servlet { //是所有的请求的Servlet的父类 public void service(Request req,Response rep) throws Exception{ this.doGet( req, rep); this.doPost( req, rep); } public abstract void doGet(Request req,Response rep) throws Exception; public abstract void doPost(Request req,Response rep) throws Exception; }

    LogServlet.java

    package com.bjsxt.servlet; import com.bjsxt.server.Request; import com.bjsxt.server.Response; public class LoginServlet extends Servlet { @Override public void doGet(Request req, Response rep) throws Exception { //获取请求参数 String name=req.getParameter("username"); String pwd=req.getParameter("pwd"); if(this.login(name, pwd)){ //调用响应中的构建内容的方 rep.println(name+"登录成功"); }else{ rep.println(name+"登录失败,对不起,账号或密码不正确"); } } private boolean login(String name,String pwd){ if ("bjsxt".equals(name)&&"123".equals(pwd)) { return true; } return false; } @Override public void doPost(Request req, Response rep) throws Exception { // TODO Auto-generated method stub } }

    12.3 启动服务器进行测试

    13. 封装分发器_实现多线程

    Dispatcher.java

    package com.bjsxt.server; import java.io.IOException; import .Socket; import com.bjsxt.servlet.Servlet; import com.bjsxt.util.IOCloseUtil; /** * 一个请求与响应就是一个Dispatcher * @author Administrator * */ public class Dispatcher implements Runnable { private Request req; private Response rep; private Socket client; private int code=200;//状态码 //构造方法初始化属性 public Dispatcher(Socket client) { //将局部变量的值赋给成员变量 this.client=client; try { req=new Request(this.client.getInputStream()); rep=new Response(this.client.getOutputStream()); } catch (IOException e) { code=500; return ; } } @Override public void run() { //根据不同的url创建指定的Servlet对象 System.out.println(req.getUrl()); Servlet servlet=WebApp.getServlet(req.getUrl()); if (servlet==null) { this.code=404; }else{ //调用相应的Servlet中的service方法 try { servlet.service(req,rep); } catch (Exception e) { this.code=500; } } //将响应结果推送到客户机的浏览器 rep.pushToClient(code); IOCloseUtil.closeAll(client); } }

    14. 整合最终版

    14.1 查缺补漏完善项目

    FaviconServlet.java

    package com.bjsxt.servlet; import com.bjsxt.server.Request; import com.bjsxt.server.Response; public class FaviconServlet extends Servlet { @Override public void doGet(Request req, Response rep) throws Exception { // TODO Auto-generated method stub } @Override public void doPost(Request req, Response rep) throws Exception { // TODO Auto-generated method stub } }

    15. 总结和期望

    15.1 项目总结

    涉及知识点

  • 集合
  • IO
  • 多线程
  • 网络编程
  • 面向对象
  • 反射
  • XML
  • HTML
  • 15.2 项目思路

  • 先分析
  • 搭建项目框架
  • 一步一步实现,先从会的开始实现
  • 整体思路,宏观使用面向对象,微观使用面向过程
  • 注重代码的调试
  • 15.3 思想是从键盘中敲出来的

  • 多注重实战
  • 学知识不是目的,目的是对知识的综合运用,才能将知识
    转化为能力
  • 不要气馁,每天进步一点点,人最大的敌人是自己,今天
    的自己比昨天的自己有进步,就是成功。
  • 今天所有的付出,都会在明天以 RMB 的形式还给你。
  • 加油!!!
  • 附源码:
    链接:https://pan.baidu.com/s/1upUHY0bGXmLfLZKOt5ICxg 提取码:pfz1


      你可能想看:

      扫描二维码推送至手机访问。

      版权声明:本文由皇冠云发布,如需转载请注明出处。

      本文链接:https://www.idchg.com/info/23854.html

      分享给朋友:

      “Java服务器运作 java怎么写服务器” 的相关文章

      NameSilo优惠码:轻松节省域名注册与续费费用

      NameSilo优惠码有哪些? NameSilo提供了多种优惠码,帮助用户在注册或续费域名时节省费用。比如,新用户可以使用“NEWUSER10”享受10%的折扣,而“SAVE20”则对所有用户开放,提供20%的折扣。如果你在注册或续费.com域名,可以尝试使用“FREEDOM”优惠码,只需支付99美...

      VPSCheap评测:低价VPS服务的最佳选择与性能分析

      VPSCheap的概述 我第一次听说VPSCheap的时候,是在一个热闹的VPS论坛上。这个成立于2010年的主机商,主要提供KVM型VPS服务,其特点是低价格和无限流量。从那以后,我对VPSCheap的关注逐渐加深。它的数据中心位于美国达拉斯,给不少用户带来了良好的使用体验。论坛上的用户在讨论各自...

      inet.ws VPS测评:揭示高性价比主机服务的真实体验与分析

      在如今这个互联网发展的时代,选择一个可靠的虚拟专用服务器(VPS)提供商至关重要。我们要介绍的就是 inet.ws,一家国外的主机服务商。inet.ws 的主营业务是销售全球多节点的 VPS 服务器。自从 2023 年 8 月推出了全场 13 个机房的 7.5 折优惠活动后,它的性价比愈发吸引了许多...

      AWS注册教程:轻松创建你的AWS账户

      在当今数字化时代,云计算的广泛应用早已成为一种趋势。在这种背景下,AWS(亚马逊网络服务)以其强大的技术和丰富的服务,逐渐成为许多人选择的云平台。那么,AWS到底是什么呢?简单来说,它是一个全面的云服务平台,提供包括计算能力、存储选项、数据库、机器学习等各种服务。我一直认为,AWS之所以能够在众多云...

      深入了解DC9飞机的历史、技术特点与运营经验

      DC9概述 了解DC9这款飞机,首先得从它的历史说起。DC9,或称道格拉斯DC-9,是由道格拉斯飞机公司设计制造的中短程单通道喷气式客机。这款飞机的诞生可以追溯到20世纪60年代。道格拉斯公司在这段时间逐步崛起,骄傲地推出了DC9作为回应当时日益增长的民航市场需求。最初的设计版本虽然体积不大,但凭借...

      DigitalOcean与Vultr的全面比较与选择建议

      DigitalOcean与Vultr概述 1.1 DigitalOcean简介 DigitalOcean成立于2012年,总部位于美国纽约,这家公司一开始就定位于为开发者提供高效的云计算服务。最初的目标是简化云计算,让更多人能够轻松使用这一新兴技术。随着时间的推移,DigitalOcean不断扩展其...