前言
上个版本中我们设计了一个类HttpContext,并在其中定义了一个静态属性mimeMapping,这里面在初始化时存放了6组键值对,保存了6中不同资源后缀与对应的Content-Type的值。但是实际上资源后缀有1000多种,我们需要将它们全部支持,才可保证任何资源都可以给客户端正确响应。本版本将解决如何解析XML文件。
实现:
TOMCAT的安装目录下有一个config目录,在该目录下有一个web.xml文件,这个文件中记录了所有的资源类型。我们直接使用这个文件将内容解析出来初始化mimeMapping,那么这个Map中就可以包含这1000多种类型了。这样一来将来客户端请求什么资源我们都可以响应正确的类型了。
如何解析XML文件?
1:在当前项目目录下新建一个目录config
2:将web.xml文件拷贝到该目录下
3:在HttpContext的初始化mimeMapping方法中通过解析该xml文件将所有类型存入这个Map即可。
这里会用到dom4j解析,代码如下:
public class HttpContext {
/*
Content-Type与资源后缀的对应关系
key:资源的后缀名,如:png,jpg,css等等
value:对应的Content-Type的值,如:image/png等
*/
private static Map<String,String> mimeMapping = new HashMap<>();
static {
//静态块适合初始化静态资源
initMimeMapping();
}
public static void initMimeMapping() {
/*
* 通过解析config目录下的web.xml文件
* 将根标签下所有<mime-mapping>子标签获取回来
* 并将其中的<extension>中间的文本作为key
* 将<mime-type>中间的文本作为value
* 保存到mimeMapping这个Map中
*
* 初始化完毕后,mimeMapping应当有1011个元素。
*/
try {
//1.创建SAXReader
SAXReader reader = new SAXReader();
//2.使用SAXReader读取xml文件创建Document对象
Document doc = reader.read("config/web.xml");
//3.通过Documment对象获取根标签
Element root = doc.getRootElement();
//4.根据解析的文档结构从根标签逐级获取子标签
List<Element> list = root.elements("mime-mapping");
for (Element e : list) {
String key = e.elementText("extension");
String value = e.elementText("mime-type");
mimeMapping.put(key,value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据给定的资源后缀名获取对应的Content-Type的值
* @param ext
* @return
*/
public static String getMimeType(String ext) {
return mimeMapping.get(ext);
}
这样一来这个Map中就有1000多个元素了,那么response在设置正文后,根据后缀去这里就可以渠道对应的类型并在响应头中告知浏览器正确类型以便浏览器可以正确理解并展示了。
总结
至此,关于Tomcat底层是如何对静态资源完整响应的工作就已经基本完成,后面的版本将实现几个简单的业务,之后即将用到Servlet的思想