# DispatcherServlet與controller的概念
###### tags: `Java Web-Servlet`
###### tags: `Java Web-mvc`
### 事由:
當建立許多Servlet,每個Servlet都有各自的方法,若要調用方法,都要使用反射來調用?
### 解決思路:

### 使用核心控制器DispatcherServlet來解決
根據用戶的請求,將用戶轉發到對應的Servlet,再對應到裏頭的methods
### 好處:
可以把底下的Controller重複使用到的反射代碼,統整放到DispatcherServlet
```java=
//*.do:表示攔截所有.do的請求
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
@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
// 我的思路是:
// 第1步: /hello.do -> hello 或者 /fruit.do -> fruit
// 第2步: hello -> HelloController 或者 fruit -> FruitController
//在application.xml的配置文件中,描寫關鍵字與controller類的關係
String servletPath = request.getServletPath();
//去除/,剩下hello.do
servletPath = servletPath.substring(1);
//去除.do,剩下hello
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" ;
}
//先找出要使用的servlet底下所有的方法
//再利用反射來調用選擇的方法
//如此一來,就能把每個controller都要重複寫的反射代碼,統整到dispatcherServlet
try {
Method method = controllerBeanObj.getClass().getDeclaredMethod(operate,HttpServletRequest.class,HttpServletResponse.class);
if(method!=null){
//将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
//值为 false 则指示反射的对象应该实施 Java 语言访问检查
//由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的
method.setAccessible(true);
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();
}
}
}
```
### 如何讓Dispatcher可以引導到其他Servlet
1.Controller在內存中形成容器beanMap,
```java=
private Map<String,Object> beanMap = new HashMap<>();
```
2.容器中有各種組件,並且與xxx.do對應

3.把XxxController與xxx的關係在xml配置文件中描述
```xml=
<beans>
<!--這個bean標籤的作用,是將來servletPath中涉及的名字對應的是fruit,那麼就要FruitController這個類來處理 -->
<bean id="fruit" class="com.atguigu.fruit.controllers.FruitController"/>
</beans>
```
4.Servlet類中的方法對應
