我们已经知道,来自tomcat的 Request 请求最终到达 Wrapper 容器,也就最终进入 Servlet ,而进入Servlet后必然要执行service方法,然后执行doXXX()。
但现在的 web 应用很少有直接将交互全部页面都用 servlet 来实现,而是采用更加高效开发web的 MVC 框架来实现。这些 MVC 框架基本的原理都是将所有的请求都映射到一个 Servlet,然后去实现 service 方法,这个方法也就是 MVC 框架的入口。
如何扩展?
//抽象Action
public interface Action {
//在这里或者具体实现类中我们可以灵活的传很多想要的值,比如strut2中用到的ActionForm
public String execute(HttpServletRequest request,ActionForm actionForm, HttpServletResponse response) throws Exception;
//或者
public String execute(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
public class DemoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestURI = request.getRequestURI();
String path = requestURI.substring(requestURI.indexOf("/",1),requestURI.indexOf("."));
if("/login".equals(path)){
action = new LoginAction();
}else if("/addUser".equals(path)){
action = new SysUserAction();
}else{
throw new RuntimeException("请求不匹配");
}
//抽象Action
ActionMapping actionMapping =(ActionMapping)map.get(path);
// 采用反射动态实例化Action
Action action = (Action)class.forName(type).newInstance();
String forward ="";
try {
forward= action.execute(request, response);
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(forward).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
//自己的Action
public class LoginAction implements Action {
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
。。。省略
return "/success.jsp";
}
}
这里我们发现,在DemoServlet 类中,存在大量的if和else,而当我们添加自己的Action时,就需要修改if/else,这就不符合对扩展开发,对修改关闭原则,这时我们想到了配置文件,用反射进行配置。
<action-config>
<action path ="/login" type = "com.wybqq.servlet.LoginAction ">
<forward name = "success">success.jsp</forward>
<forward name = "error">error.jsp</forward>
</action>
。。。省略
</action-config>
这时,我们通过创建actionMapping对象,采用反射来动态实例化Action,自动将Servlet请求转移到我们的loginAtion中。
。。。省略
ActionMapping actionMapping =(ActionMapping)map.get(path);
// 采用反射动态实例化Action
Action action = (Action)class.forName(type).newInstance();
String forward = action.execute(request.response);
request.getRequestDispatcher(forward).forward(request, response);
。。。省略