当服务启动之后,如果指定的某个Context没有指定页面,也就是uri为/
,那么默认进入index.html
或者index.jsp
实现的思想就是,在项目配置文件夹conf下建立一个web.xml,这个配置文件中保存着设置好的文件,当一个访问未指定具体的哪个文件时,就去解析这个文件,获取其中存在的文件。
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<welcome-file-list>
<welcome-file>index.heml</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
建立工具类webXmlUtil来解析这个文件
package jerrymice.util;
import cn.hutool.core.io.FileUtil;
import jerrymice.catalina.Context;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
/**
* @author xsl20
*/
public class WebXmlUtil {
public static String getWelcomeFile(Context context) {
String xml = FileUtil.readUtf8String(Constant.webXmlFile);
Document document
= Jsoup.parse(xml);
Elements elements = document.select("welcome-file");
for (Element element : elements) {
File tmpFile = new File(context.getDocBase(), element.text());
if (tmpFile.exists()) {
// 如果找到了配置文件中指定的文件
return tmpFile.getName();
}
}
return "index.html";
}
}
下面改动Request类,根据请求解析其uri,然后先直接根据uri来获取context对象,这样就可以保证像/b
这样的访问可以获取到context,如果此时获取到的context不为null,那么就直接返回即可,如果获取到的context为null,那么就说明此时的uri不是一个文件夹或者是一个不存在的文件夹,那就继续向下执行,尝试从uri中解析出path,如果获取到的path为null,那么访问的就是ROOT目录下的文件,如果不为空,就用这个path去获取context对象,如果获取到context对象为空,说明没有这个path,那么将context的path指定为根目录下的那个context。尽管这个context是对应着根目录的,但是uri并没有变,例如访问一个不存在的目录/c/
,那么这个请求对应的context的path就是/
,但是这个uri对应的fileName是c/
,这个文件本身并不存在,所以会报404错误。
public void parseContext(){
Engine engine = service.getEngine();
// 根据获取到的uri去扫描得到的映射中去寻找这个文件夹,这样/b就能够获取匹配而不一定是/b/
context = engine.getDefaultHost().getContext(uri);
if (context != null) {
return;
}
String path = StrUtil.subBetween(uri, "/", "/");
if (null == path) {
// 如果uri = /timeConsume.html,那么path = null, 不对uri进行改动
path = "/";
}
else {
// uri = /dir1/1.html, 那么path= dir1, 经过此处之后path=/dir1
// uri = /b/, path = /b
path = "/" + path;
}
context = engine.getDefaultHost().getContext(path);
if (null == context){
context = engine.getDefaultHost().getContext("/");
}
}
public Request(Socket socket, Service service) throws IOException {
this.socket = socket;
this.service = service;
parseHttpRequest();
if (StrUtil.isEmpty(requestString)){
return;
}
parseUri();
parseContext();
// 比如 uri 是 /a/index.html, 获取出来的 Context路径不是 "/”, 那么要修正 uri 为 /index.html
if (!"/".equals(context.getPath())){
// 如果访问的地址是/a,那么经过remove之后uri就变为“”了,考虑到这种情况,让uri等于"/"
uri = StrUtil.removePrefix(uri, context.getPath());
if (StrUtil.isEmpty(uri)){
uri = "/";
}
}
}
uri 最后都会被修正为/文件名
的形式, 然后在server中再去掉前面的/
,得到文件名
下面是Server类的修改
if("/".equals(uri)){
uri = WebXMLUtil.getWelcomeFile(request.getContext());
}
当uri是根目录时,就去访问配置文件中指定的那几个文件中存在的那一个,如果都不存在的话,就默认访问index.html
,这会报404错误。
测试结果
/b/
时,会自动跳转到/b/index.html原文:https://www.cnblogs.com/xsliu/p/13443278.html