模拟请求和响应
需求:
假设用户会在浏览器中输入某些地址:比如: http:///abc.html 、 http:///def.html
根据请求地址的不同,进行不同的响应:(即显示对应的页面内容: 默认输出结果)。
思路1:
在代码中根据地址的不同 用 if 判断,然后 执行不同的逻辑
if(“abc.html”.equals(url)){
//返回abc结果
}else if(“def.html”.equal(url)){
//返回def结果
}
思路不好,不利于程序的扩展。当改变映射规则时,需要重新编写Java代码。
思路2:
想避免固化的逻辑,应该将映射规则配置在外部的文件中。
- url地址 --> 映射某个程序的功能
- 用properties文件或 XML 文件都可以来描述
下面用 XML 格式 实现。
格式一:
<mapping>
<url>abc.html</url>
<function>com.xxx.Mxx.method</function>
</mapping>
<mapping>
<url>def.html</url>
<function>com.xxx.Mxx.method</function>
</mapping>
格式二:
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>com.xxx.Mxx</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>abc.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>def.html</url-pattern>
</servlet-mapping>
定义接口(叫它Servlet)实现 类的功能
功能1:初始化方法 void init();
功能2:用户请求过来以后,工作的内容 void service();
功能3:销毁方法 void destroy();
后续的开发工作是:
要想定义一个服务器端的行为,就创建一个类,实现Serlvet接口。然后实现它中定义的方法。
想要跟某个URL地址对应,修改xml配置文件即可。
代码演示:
配置xml
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://www.example.org/web-app_2_5"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd" version="1">
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>com.example.web.AbcServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/abc.html</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>def</servlet-name>
<servlet-class>com.example.web.DefServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>def</servlet-name>
<url-pattern>/def.html</url-pattern>
</servlet-mapping>
定义一个接口实现三个方法。
Demo类做一个 请求和响应的 模拟
- 启动
解析web.xml文件
将结果存放在 Map 中
思考:
key: String url地址
value: // String 包名+类名
// Servlet的实例对象
Servlet中的init初始化方法怎么调用呢?
方法执行以来与对象。
- 等待用户服务
读取用户的url地址
判断系统中是否能处理(看一下字典中是否包含对应的key),
如果可以,则调用map中value的service方法。
如果不可以,返回404错误。
- 退出系统
假设用户输入的是bye,执行退出逻辑。
遍历map中的所有servlet实例,调用它们的destroy方法。
public class Demo {
private static Map<String,Servlet> mappings = new HashMap<>();
private static Map<String,String> servlets = new HashMap<>();
private static Map<String,String> servlet_mappings=new HashMap<>();
public static void main(String[] args) {
start();
work();
}
public static void start() {
//加载web.xml
URL resource = Demo.class.getResource("web.xml");
SAXReader reader = new SAXReader();
try {
Document read = reader.read(resource);
//得到根元素
Element rootElement = read.getRootElement();
Iterator iterator = rootElement.elementIterator();
while(iterator.hasNext()){
Element next = (Element) iterator.next();
if("servlet".equals(next.getName())){
String sname = next.element("servlet-name").getTextTrim();
String sclass = next.element("servlet-class").getTextTrim();
servlets.put(sname, sclass);
}else if("servlet-mapping".equals(next.getName())){
String sname = next.element("servlet-name").getTextTrim();
String url=next.element("url-pattern").getTextTrim();
servlet_mappings.put(sname, url);
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
//解析完成,进入初始化的流程
for(Map.Entry<String, String> entry: servlet_mappings.entrySet()){
String sname = entry.getKey();
String sClass = servlets.get(sname);
String url = entry.getValue();
//创建class的对象
try {
Class<Servlet> aClass = (Class<Servlet>) Class.forName(sClass);
Servlet servlet = aClass.newInstance();
servlet.init();//进行初始化
mappings.put(url, servlet);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
public static void work() {
while(true){
//等待输入
System.out.println("请输入要访问的地址:");
Scanner scanner = new Scanner(System.in);
String url = scanner.next();
if("bye".equalsIgnoreCase(url)){
stop();
System.exit(0);
// break;
}
Servlet servlet = mappings.get(url);
if(servlet==null){
System.out.println("404错误!");
continue;
}
servlet.service();//进行响应。
}
}
public static void stop() {
for(Map.Entry<String,Servlet> entry:mappings.entrySet()){
Servlet value = entry.getValue();
value.destroy();//销毁逻辑
}
}
}