minicat 1.0我们实现了返回固定的字符串"Hello minicat"。
minicat 2.0封装Request和Response对象,返回html静态资源文件。
minicat 3.0需求:
请求servlet动态资源
思路分析:
想实现servlet动态资源请求,就需要将Servlet初始化在容器中(Map)。
如何初始化呢?
- 将配置信息配置在web.xml中
- 使用dom4j解析web.xml内容
- 使用反射机制将servlet初始化在Map中
配置web.xml
配置web.xml之前,需要先自定义一个DemoServlet,需要有常见的doGet和doPost方法。
进一步想平时写Servlet都需要继承HttpServlet抽象类,所以先自己定义一个HttpServlet抽象类,以便后续做容器初始化。
先定义Servlet接口
public interface Servlet {
void init() throws Exception;
void destroy() throws Exception;
void service(Request request,Response response) throws Exception;
}
HttpServlet实现Servlet
public abstract class HttpServlet implements Servlet {
public abstract void doGet(Request request,Response response);
public abstract void doPost(Request request,Response response);
@Override
public void service(Request request, Response response) throws Exception {
if ("GET".equalsIgnoreCase(request.getMethod())) {
doGet(request,response);
}else{
doPost(request,response);
}
}
}
接下来就是常规的DemoServlet编写了
public class DemoServlet extends HttpServlet{
@Override
public void doGet(Request request, Response response) {
String content = "<h1>get request</h1>";
try {
response.output(HttpProtocolUtil.getHttpHeader200(content.getBytes().length)+content);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(Request request, Response response) {
String content = "<h1>post request</h1>";
try {
response.output(HttpProtocolUtil.getHttpHeader200(content.getBytes().length)+content);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void init() throws Exception {
}
@Override
public void destroy() throws Exception {
}
}
DemoServlet准备完成后,就可以配置web.xml了
<?xml version="1.0" encoding="UTF-8" ?>
<web-app>
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>server.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
使用dom4j解析web.xml
web.xml已经配置完成,解析来就需要对它进行解析,也就是初始化的过程,所以需要放在上一篇的start()方法中初始化。
public void start() throws Exception {
loadServlet();
}
private void loadServlet() {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(resourceAsStream);
Element rootElement = document.getRootElement();
List<Element> selectNodes = rootElement.selectNodes("//servlet");
for (Element element : selectNodes) {
Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
String servletName = servletnameElement.getStringValue();
Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
String servletClass = servletclassElement.getStringValue();
Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
}
} catch (DocumentException | ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
使用反射机制将servlet初始化在Map中
眼尖的同学估计看到了,这一步骤其实就是在loadServlet()方法中实现的
添加map容器
private Map<String,HttpServlet> servletMap = new HashMap<String,HttpServlet>();
private void loadServlet() {
servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());
}
演示效果
已经初始化map容器了,那就需要在start方法中引用,start方法完整代码如下
public void start() throws Exception {
loadServlet();
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("---->>>minicat start on port:"+port);
while (true) {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
Request request = new Request(inputStream);
Response response = new Response(socket.getOutputStream());
if(servletMap.get(request.getUrl()) == null) {
response.outputHtml(request.getUrl());
}else{
HttpServlet httpServlet = servletMap.get(request.getUrl());
httpServlet.service(request,response);
}
socket.close();
}
}
效果演示
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)