目录
B/S架构及C/S架构:
C/S架构:
Client/Server架构,即服务器/客户端架构。是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,需要安装客户端才可进行管理操作。 常见的C/S架构有:QQ、百度网盘等。
优点:
(1)界面和操作可以很丰富。 (2)大部分数据保存在客户端、相对安全。 (3)大部分功能集成在客户端,只需从服务器下载少量数据,因此访问速度很快。
缺点:
(1)升级维护工作量较大,每一个客户端都需要升级。 (2)用户群固定,由于程序需要安装才可以使用个,因此不适合面向一些不可知的用户。
B/S架构原理剖析
首先何为B/S架构:B/S架构全称为Browser/Server,即浏览器/服务器结构。Browser指的是web浏览器,极少数业务逻辑在前端实现,主要的业务逻辑在服务器端实现。Browser客户端-WebApp服务器端和DB端构成了所谓的三层架构。B/S架构的系统无需特别安装,只有Web浏览器即可。B/S架构中,现实逻辑交给Web浏览器,业务处理逻辑放在了WebApp上,这样就避免了庞大的胖客户端,减少了客户端的压力。因为客户端包含的逻辑很少,因此也被称为瘦客户端。
优点:
(1)客户端无需安装,有Web浏览器即可。 (2)B/S架构可以放在广域网上,通过一定的权限控制实现多客户访问的目的,交互性较强。 (3)B/S架构无需升级多个客户端,升级服务器即可。
缺点:
(1)在跨浏览器上,B/S架构不尽如人意。 (2)表现要达到C/S架构的程度需要花费不少精力。 (3)在速度和安全性上需要花费巨大的设计成本,这是B/S架构最大的问题。
接口与协议的作用:
接口和协议可以理解为一种行业的标准或者规范,只有提前制定好规范和标准,将来各个部件或组件才可以做到无缝对接,接口的存在使整个系统变的具有很强的可接插特性,使整个系统各个组件之间达到松耦合,具备很强的高扩展力。Java 语言连接数据库的 API 被称为 JDBC 接口,该接口是 SUN 公司负责制定的,连接数据库的 Java程序员只需要面向 JDBC接口调用相关的方法即可完成底层数据库 CRUD 操作,该规范的出现让操作数据库的 Java 程序和底层具体的数据库产品解耦合,Java程序无须依赖底层具体的数据库产品,可以真正做到“一套 Java程序”连接并操作各种不同类型的数据库系统。再例如“不同版本的浏览器”都可以访问“百度网站”,并且最终在浏览器中显示的百度页面都是相同的,这说明“浏览器软件”和“百度服务器软件”之间是解耦合的,它们之所以可以做到解耦合就是因为这两个软件在互相传递数据的时候必然是遵守某种传送标准的,这种标准就是 W3C 制定的 HTTP 协议(超文本传输协议)。
总的来说,面向接口编程可以解耦合。
B/S架构原理1:
B/S架构的系统参与者:
(1)Web客户端Browser
(2)Web服务器端Server
(3)WebApp
(4)数据库服务器
B/S架构的系统中参与者之间的接口与协议:
第一:Web 客户端 Browser 和 Web 服务器端 Server 之间是 W3C 制定的 HTTP 协议。 第二:Web 服务器和 Web 应用之间是 SUN 制定的 Servlet 接口。 第三:Web 应用中的小 java 程序和数据库服务器之间是 SUN 制定的 JDBC 接口。
B/S架构原理2:
我们要做的就是重新制定Servlet接口(虽然SUN已经制定Servlet接口,但是为了更好理解尝试重新制定)、后进行Web服务器开发当我们的服务器研发成功后,可以开发一个web应用对该服务器进行测试。
HTTP超文本传输协议
什么是协议?
计算机 A 和计算机 B 之间在传送数据的时候,提前制定好的一种数据传送格式,计算机 A 向计算机B发送一个数据包,计算机 B 必须提前知道该数据包的数据格式,才可以成功的将该数据包中有价值的数据解析出来。 例如:小张和小王聊天,小张说:“你吃饭了吗?”,小王说:“吃了”。可见小张和小王可以正常 沟通交流,他们为什么可以正常沟通交流呢?因为小张和小王都遵守同一套协议,该协议就是中国普 通话协议,其实我们从幼儿园就开始学习这套协议了。
什么是HTTP协议?
HTTP 协议是一种超文本传输协议,超文本表示不仅可以传送普通的文本,还可以传送一些二进制数据,例如:图片、声音、视频、流媒体等数据。 HTTP 协议是 W3C(万维网联盟组织)制定的,该协议规定了浏览器软件和 web 服务器软件之间在传送数据的时候采用什么样的格式。这样就可以做到不同类型的浏览器访问不同类型的 Web 服务 器。浏览器和 Web 服务器之间解耦合。 浏览器 Browser 向 Web 服务器发送数据,称为请求 request,Web 服务器向浏览器发送数据,称为响应 response。
HTTP协议初步
请求协议包括的主要部分 A、请求行 B、消息报头 C、空白行 D、请求体
请求协议的详细内容: 响应协议包括的主要部分 A、状态行 B、 响应报头 C、空白行 D、响应体
响应协议的详细内容
Socket编程
什么是Socket编程?
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket。 Socket 的英文原义是“孔”或“插座”。通常也称作"套接字",用于描述 IP 地址和端口,可以用来实现不同计算机之间的通信。在 Internet 上的主机一般运行了多个服务软件,同时提供几种服务。 每种服务都打开一个 Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket 正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供 220 伏交流电, 有的提供 110 伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。
连接过程
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤: 服务器监听,客户端请求,连接确认。
第一步:服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状 态,实时监控网络状态。 第二步:客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。 为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口 号,然后就向服务器端套接字提出连接请求。 第三步:连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就 响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确 认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的 连接请求。
Java中如何实现Socket编程:
JavaSE 中提供了实现 Socket 编程的 API,让网络编程变的更简单,更加面向对象。要实现两台计算 机(两个服务)之间的通讯,至少编写以下的代码:
服务器端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServerSocket {
public static void main(String[] args) {
ServerSocket serverSocket=null;
Socket clientSocket=null;
BufferedReader br=null;
try {
serverSocket=new ServerSocket(8080);
clientSocket=serverSocket.accept();
br=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String temp=null;
while((temp=br.readLine())!=null){
System.out.println(temp);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br!=null){
try{
br.close();
}catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(clientSocket!=null){
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端:
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClientSocket {
public static void main(String[] args) {
Socket clientSocket=null;
PrintWriter out=null;
try {
clientSocket = new Socket("localhost", 8080);
out=new PrintWriter(clientSocket.getOutputStream());
String msg="Hello world!";
out.print(msg);
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out!=null){
out.close();
}
if(clientSocket!=null){
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行时先启动服务器端程序,在启动客户端程序,可将客户端内容输出至服务器端。
在自己的浏览器中输入:http://localhost:8080, 服务器端会输出自己浏览器的request:
软件测试
软件测试技术是软件开发过程中的一个重要组成部分,是贯穿整个软件开发生命周期、对软件产品(包括阶段性产品)进行验证和确认的活动过程,其目的是尽快尽早地发现在软件产品中所存在的 各种问题-与用户需求、预先定义的不一致性。检查软件产品的 bug。写成测试报告,交于开发人员修 改
软件测试技术包括哪些:
A、黑盒测试
黑盒测试也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看 作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试, 它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生 正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功 能进行测试。黑盒测试是以用户的角度,从输入数据与输出数据的对应关系出发进行测试的。
B、 白盒测试
软件的白盒测试是对软件的过程性细节做细致的检查。这种方法是把测试对象看做一个打开的盒 子,它允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路 径进行测试。通过在不同点检查程序状态,确定实际状态是否与预期的状态一致。因此白盒测试又称 为结构测试或逻辑驱动测试。白盒测试一般有专门的白盒测试人员测试。
C、 单元测试
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元 的含义,一般来说,要根据实际情况去判定其具体含义,如 Java 里单元指一个类。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。单元测试一般由程序员自己完成。并且测试完成之后需要提交单元测试报告。
D、压力测试
压力测试属于性能测试的一部分,测试系统的最大负载情况。 E、 其它测试 易用性测试 安全性测试 ……
如何做单元测试?
手动单元测试
Java 的单元测试有专门的开源项目,例如:JUnit, 首先需要到 JUnit 官网下载 JUnit 相关 jar 包,我们这里使用 JUnit4-4.12,JUnit 官网地址:http://junit.org/junit4/ JUnit-4.12 下载完成后存放到本地硬盘中 打开IDEA,并点击 将文件添加进来即可。
使用IDEA做单元测试,可专门为测试代码创建测试文件夹,具体方法为Project Structure->Project Settings->Modules->Mark as ->Tests即可。 进行单元测试时,具体方法如下: 源代码:
package com.sh.junit;
public class MyMath {
public static int sum(int a,int b){
return a+b;
}
public static int divide(int a,int b){
return a/b;
}
}
测试代码:
import com.sh.junit.MyMath;
import org.junit.Test;
import static org.junit.Assert.*;
public class MyMathTest {
@Test
public void testSum(){
int actual=MyMath.sum(10,10);
int expected=20;
assertEquals(expected,actual);
}
}
测试结果: 测试正确: 若错误: 以上方法为手动创建测试,下面我们自动生成测试类。
自动单元测试
还是老一套:导入junit,写好源代码待测试、创建好测试文件夹test 打开要测试的类:按住ctrl+shift+t 点击Creat New Test… 出现下面页面,然后勾选要测试的方法。 会自动生成单元测试类,并需要将JUnit4 add to path… 编写方法,测试完成: 可以用此方法测试后面编写的程序。
代码实现
基本方法讲完之后, 分析一下我们的需求: 下图中的类使我们将会用到的 逐个解释: conf:用于存放服务器端口号的配置文件 oa:webapp的配置文件其中包括index静态界面、login登录静态界面(后续待完善,准备添加)、userSave静态界面
以及可能将要扮演的角色:Web服务器开发人员、WebApp开发人员、SUN公司制定标准人员。
作为Web服务器开发人员
Servlet.xml
<?xml version="1.0" encoding="UTF-8" ?>
<server>
<service>
<connector port="8080"></connector>
</service>
</server>
web.xml 用于构成<servlet-name,<urlpattern,servletclass>>
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.sh.oa.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>userSaveServlet</servlet-name>
<servlet-class>com.sh.oa.servlet.UserSaveServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userSaveServlet</servlet-name>
<url-pattern>/user/save</url-pattern>
</servlet-mapping>
</web-app>
OA办公系统首页
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>OA办公系统首页</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<body>
<center><font size="35xp" color="blue">OA办公系统首页</font></center>
</body>
</html>
localhost:8080/oa/userSave.html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>oa办公系统-用户信息保存</title>
</head>
<body>
<form action="/oa/user/save" method="get">
用户名
<input type="text" name="username">
<br/>
性别
<input type="radio" name="sex" value="m"/>男
<input type="radio" name="sex" value="f"/>女
<br/>
兴趣
运动<input type="checkbox" name="interest" value="sport"/>
音乐<input type="checkbox" name="interest" value="music"/>
旅游<input type="checkbox" name="interest" value="travel"/>
美食<input type="checkbox" name="interest" value="food"/>
<br/>
<input type="submit" value="保存">
</form>
</body>
</html>
src/httpserver表示我们作为服务器开发人员需要完成的工作: core为核心类包,util为工具类包
core包中: BootStrap为程序主入口:
package com.sh.httpserver.core;
import com.sh.httpserver.util.Logger;
import org.dom4j.DocumentException;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class BootStrap {
public static void main(String[] args) {
start();
}
public static void start() {
ServerSocket serverSocket=null;
Socket clientSocket =null;
BufferedReader br = null;
try {
String[] webAppNames={"oa"};
WebParser.parser(webAppNames);
Logger.log("httpserver start!");
int port=ServerParser.getPort();
Logger.log("httpserver-port:"+port);
serverSocket=new ServerSocket(port);
Logger.log("httpserver started");
while(true) {
clientSocket = serverSocket.accept();
new Thread(new HandlerRequest(clientSocket)).start();
}
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} finally{
if(serverSocket!=null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
HandlerRequest为请求处理入口:
package com.sh.httpserver.core;
import com.sh.httpserver.util.Logger;
import com.sh.oa.servlet.LoginServlet;
import com.sh.oa.servlet.ServletCache;
import javax.servlet.Servlet;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.util.Map;
public class HandlerRequest implements Runnable{
public Socket clientSocket;
public HandlerRequest(Socket clientSocket){
this.clientSocket=clientSocket;
}
@Override
public void run() {
BufferedReader br=null;
Logger.log("httpserver thread:"+Thread.currentThread().getName());
PrintWriter out=null;
try {
br=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out=new PrintWriter(clientSocket.getOutputStream());
String requestLine=br.readLine();
String requestsURI=requestLine.split(" ")[1];
if(requestsURI.endsWith(".html")||requestsURI.endsWith(".htm")){
requestStaticPage(requestsURI,out);
}else{
String servletPath=requestsURI;
if(servletPath.contains("?")){
servletPath=servletPath.split("[?]")[0];
}
String webAppName= servletPath.split("[/]")[1];
Map<String,String> servletMap=WebParser.servletMaps.get(webAppName);
String urlPattern =servletPath.substring(1+webAppName.length());
String servletClassName= servletMap.get(urlPattern);
if(servletClassName!=null) {
out.print("HTTP/1.1 200 OK\n");
out.print("Content-Type:text/html;charset=utf-8\n\n");
RequestObject requestObj=new RequestObject(requestsURI);
Servlet servlet = ServletCache.get(urlPattern);
if(servlet==null){
Class c =Class.forName(servletClassName);
servlet=(Servlet)c.getDeclaredConstructor().newInstance();
ServletCache.put(urlPattern,servlet);
}
Logger.log("获取到Servlet对象"+servlet);
ResponseObject responseObj=new ResponseObject();
responseObj.setWriter(out);
servlet.service(requestObj,responseObj);
}else {
StringBuilder html=new StringBuilder();
html.append("HTTP/1.1 404 NotFound\n");
html.append("Content-Type:text/html;charset=utf-8\n\n");
html.append("<html>");
html.append("<head>");
html.append("<title>404-错误</title>");
html.append("<meta content='text/html;charset=utf-8'/>");
html.append("</head>");
html.append("<body>");
html.append("<center><font size='35px' color='red'>404-Not Found</font></center>");
html.append("</body>");
html.append("</html>");
out.print(html);
}
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} finally{
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(clientSocket!=null){
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void requestStaticPage(String requestsURI, PrintWriter out) {
String htmlPath=requestsURI.substring(1);
BufferedReader br=null;
try {
br=new BufferedReader(new FileReader(htmlPath));
StringBuilder html=new StringBuilder();
html.append("HTTP/1.1 200 OK\n");
html.append("Content-Type:text/html;charset=utf-8\n\n");
String temp=null;
while((temp=br.readLine())!=null){
html.append(temp);
}
out.print(html);
} catch (FileNotFoundException e) {
StringBuilder html=new StringBuilder();
html.append("HTTP/1.1 404 NotFound\n");
html.append("Content-Type:text/html;charset=utf-8\n\n");
html.append("<html>");
html.append("<head>");
html.append("<title>404-错误</title>");
html.append("<meta content='text/html;charset=utf-8'/>");
html.append("</head>");
html.append("<body>");
html.append("<center><font size='35px' color='red'>404-Not Found</font></center>");
html.append("</body>");
html.append("</html>");
out.print(html);
} catch (IOException e) {
e.printStackTrace();
}
}
}
RequestObject和ResponseObject:
package com.sh.httpserver.core;
import javax.servlet.ServletRequest;
import java.util.HashMap;
import java.util.Map;
public class RequestObject implements ServletRequest {
private Map<String,String[]> parameterMap=new HashMap<>();
public RequestObject(String requestURIAndData){
if(requestURIAndData.contains("?")){
String[] uriAndData=requestURIAndData.split("\\?");
if(uriAndData.length>=2){
String data=uriAndData[1];
if(data.contains("&")){
String[] nameAndValues=data.split("&");
for(String nameAndValue:nameAndValues){
String[] nameAndValueArr=nameAndValue.split("=");
if(parameterMap.containsKey(nameAndValueArr[0])){
String[] values=parameterMap.get(nameAndValueArr[0]);
String[] newValues=new String[values.length+1];
System.arraycopy(values,0,newValues,0,values.length);
if(nameAndValueArr.length>1){
newValues[newValues.length-1]=nameAndValueArr[1];
}else{
newValues[newValues.length-1]="";
}
parameterMap.put(nameAndValueArr[0],newValues);
}else{
if(nameAndValueArr.length>1){
parameterMap.put(nameAndValueArr[0],new String[]{nameAndValueArr[1]});
}else{
parameterMap.put(nameAndValueArr[0],new String[]{""});
}
}
}
}else{
String[] atrs=data.split("=");
if(atrs.length>1){
parameterMap.put(atrs[0],new String[]{atrs[1]});
}else{
parameterMap.put(atrs[0],new String[]{""});
}
}
}
}
}
public String getParameter(String attributeName){
String[] parameterValues=parameterMap.get(attributeName);
if(parameterValues!=null&¶meterValues.length!=0){
return parameterValues[0];
}
return null;
}
public String[] getParameterValues(String attributeName){
return parameterMap.get(attributeName);
}
}
package com.sh.httpserver.core;
import javax.servlet.ServletResponse;
import java.io.PrintWriter;
public class ResponseObject implements ServletResponse {
private PrintWriter out;
public void setWriter(PrintWriter out){
this.out=out;
}
public PrintWriter getWriter(){
return out;
}
}
ServerParser用于解析server.xml文件得到端口号(解耦合,所以用配置文件存储信息而非直接写入)
package com.sh.httpserver.core;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ServerParser {
public static int getPort(){
int port=8080;
try {
SAXReader saxReader=new SAXReader();
Document doc=saxReader.read("conf/server.xml");
Element connectorElt=(Element) doc.selectSingleNode("//connector");
port=Integer.parseInt(connectorElt.attributeValue("port"));
} catch (DocumentException e) {
e.printStackTrace();
}
return port;
}
}
WebParser用于解析应用信息,使每个用户名对应相应的类名等
package com.sh.httpserver.core;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class WebParser {
public static Map<String,Map<String,String>> servletMaps=new HashMap<>();
public static void parser(String[] webAppNames) throws DocumentException {
for(String wepAppName:webAppNames){
Map<String,String> servletMap=parser(wepAppName);
servletMaps.put(wepAppName,servletMap);
}
}
private static Map<String,String> parser(String webAppName) throws DocumentException{
String webPath = webAppName + "/WEB-INF/web.xml";
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(webPath));
List<Element> servletNodes= document.selectNodes("/web-app/servlet");
Map<String,String> servletInfoMap = new HashMap<String,String>();
for(Element servletNode: servletNodes){
Element servletNameElt=(Element) servletNode.selectSingleNode("servlet-name");
String servletName=servletNameElt.getStringValue();
Element servletClassElt=(Element) servletNode.selectSingleNode("servlet-class");
String servletClassName=servletClassElt.getStringValue();
servletInfoMap.put(servletName,servletClassName);
}
List<Element> servletMappingNodes= document.selectNodes("/web-app/servlet-mapping");
Map<String,String> servletMappingInfoMap =new HashMap<>();
for(Element servletMappingNode: servletMappingNodes){
Element servletNameElt= (Element)servletMappingNode.selectSingleNode("servlet-name");
String servletName =servletNameElt.getStringValue();
Element urlPatternElt = (Element) servletMappingNode.selectSingleNode("url-pattern");
String urlPattern =urlPatternElt.getStringValue();
servletMappingInfoMap.put(servletName,urlPattern);
}
Set<String> servletNames= servletInfoMap.keySet();
Map<String,String> servletMap= new HashMap<>();
for(String servletName: servletNames){
String servletClassName=servletInfoMap.get(servletName);
String urlPattern=servletMappingInfoMap.get(servletName);
servletMap.put(urlPattern,servletClassName);
}
return servletMap;
}
}
DateUtil 日期工具类,单独写出,供所有其他类可用
package com.sh.httpserver.util;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
private static SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
private DateUtil(){}
public static String getCurrentTime(){
return dateFormat.format(new Date());
}
}
Logger日志记录类
package com.sh.httpserver.util;
public class Logger {
private Logger(){
}
public static void log(String msg){
System.out.println(" [INFO] "+ DateUtil.getCurrentTime()+" "+msg);
}
}
作为WebApp开发人员
下面我们转换角色,看看webapp开发人员要完成的工作:
登录业务服务器,目前较为不满意,等到学会相应技术回来修改。
package com.sh.oa.servlet;
import com.sh.httpserver.core.RequestObject;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.Servlet;
import java.io.PrintWriter;
public class LoginServlet implements Servlet {
public void service(ServletRequest requestObj, ServletResponse response){
System.out.println("正在验证身份,请稍等.....");
PrintWriter out=response.getWriter();
out.print("<html>");
out.print("<head>");
out.print("<title>正在验证</title>");
out.print("<meta content='text/html;charset=utf-8'/>");
out.print("</head>");
out.print("<body>");
out.print("<center><font size='35px' color='blue'>正在验证身份,请稍等</center>");
out.print("</body>");
out.print("</html>");
}
}
伪单例,将已有服务器写入缓存,不必一个一开。
package com.sh.oa.servlet;
import javax.servlet.Servlet;
import java.util.HashMap;
import java.util.Map;
public class ServletCache {
private static Map<String, Servlet> servletMap=new HashMap<>();
public static Servlet get(String urlPattern){
return servletMap.get(urlPattern);
}
public static void put(String urlPattern,Servlet servlet){
servletMap.put(urlPattern,servlet);
}
}
UserSaveServlet处理用户信息保存业务
package com.sh.oa.servlet;
import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.PrintWriter;
public class UserSaveServlet implements Servlet {
@Override
public void service(ServletRequest request, ServletResponse response) {
String username=request.getParameter("username");
String sex=request.getParameter("sex");
String []interests =request.getParameterValues("interest");
StringBuilder interest=new StringBuilder();
for(String n:interests){
interest.append(n);
interest.append(" ");
}
PrintWriter out=response.getWriter();
out.print("用户名:"+username+"<br>");
out.print("性别:"+sex+"<br>");
out.print("兴趣:"+interest+"<br>");
}
}
SUN公司需要做的是什么? 当然是制定接口!
作为SUN公司接口制定人员
Servlet接口
package javax.servlet;
import com.sh.httpserver.core.RequestObject;
public interface Servlet {
void service(ServletRequest request, ServletResponse response);
}
ServletRequest接口
package javax.servlet;
public interface ServletRequest {
String getParameter(String attributeName);
String[] getParameterValues(String attributeName);
}
ServletResponse接口
package javax.servlet;
import java.io.PrintWriter;
public interface ServletResponse {
PrintWriter getWriter();
}
Well,that’s all. 29710-words
|