mvc-servlet优化3-dispatcherServlet引入
applicationContext.xml
<?xml version="1.0" encoding="utf-8"?>
<beans>
<!-- 这个bean标签的作用是 将来servletpath中涉及的名字对应的是fruit,那么就要FruitController这个类来处理 -->
<bean id="fruit" class="com.atguigu.fruit.controllers.FruitController"/>
</beans>
<!--
1.概念
HTML : 超文本标记语言
XML : 可扩展的标记语言
HTML是XML的一个子集
2.XML包含三个部分:
1) XML声明 , 而且声明这一行代码必须在XML文件的第一行
2) DTD 文档类型定义
3) XML正文
-->
DispatcherServlet 类
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet{
private Map<String,Object> beanMap = new HashMap<>();
public DispatcherServlet(){
}
public void init(){
try {
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
//1.创建DocumentBuilderFactory对象
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//2.创建DocumentBuilder对象
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//3.创建Document对象
Document document = documentBuilder.parse(inputStream);
//4.获取所有的bean节点
NodeList beanNodeLists = document.getElementsByTagName("bean");
for (int i = 0;i<beanNodeLists.getLength();i++){
Node beanNode = beanNodeLists.item(i);
//判断该节点的类型是否等于元素节点
if (beanNode.getNodeType() == Node.ELEMENT_NODE){
Element beanElement = (Element)beanNode;
String beanId = beanElement.getAttribute("id");
String className = beanElement.getAttribute("class");
Class controllerBeanClass = Class.forName(className);
Object beanObj = Class.forName(className).newInstance();
Method setServletContextMethod = controllerBeanClass.getDeclaredMethod("setServletContext", ServletContext.class);
setServletContextMethod.invoke(beanObj,this.getServletContext());
beanMap.put(beanId,beanObj);
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
request.setCharacterEncoding("utf-8");
//假设url是:http://localhost:8080/pro15/hello.do
//那么servletPath是: /hello.do
//我的思路是:
///第一步:/hello.do -> hello 或者 /fruit.do -> fruit
//第二步:hello -> HelloController 或者 fruit -> FruitController
String servletPath = request.getServletPath();
servletPath = servletPath.substring(1);
int lastDotIndex = servletPath.lastIndexOf(".do");
servletPath = servletPath.substring(0, lastDotIndex);
Object controllerBeanObj = beanMap.get(servletPath);
String operate = request.getParameter("operate");
if (StringUtil.isEmpty(operate)){
operate = "index";
}
try {
Method method = controllerBeanObj.getClass().getDeclaredMethod(operate, HttpServletRequest.class,HttpServletResponse.class);
if (method!=null){
method.setAccessible(true);
//找到和operate同名的方法,那么通过反射技术调用它
method.invoke(controllerBeanObj,request,response);
}else {
throw new RuntimeException("operate的值非法!");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}