抛弃框架的基于纯 Java Servlet 与 JSP的网站系统开发

我一个朋友初学JAVA,让我给他讲讲Web开发这方面的东西,老实说几年前用过的Struts现在早就忘光了...

 

平常接些JAVA单子基本也就用 nutz 和 spring mvc ,sese [自己拼的一个小框架] 这3种东西

 

但是这些对初学者似乎还是很复杂.

 

 

让我给他讲 struts 确实不会,就按我的思路给讲好了 ... 以上都是废话...

 

作为现在流行的java web开发框架,基本都是MVC导向的... 此处我就歪歪下自己的想法

 

剥掉 M 就只剩余 C + V ,把 JSP+JSTL+EL 指向 模版视图[V] , 那么把V完全可以无视了,此时只剩下控制器 C

 

现在很多框架把 控制器 使用非Servlet的类来实现,方便测试吧,可能... 那么此处也就遵循好了,方便测试吧...

public abstract class BaseController {
	
	protected IRequestEntry requestEntry ;

	public void init(){}

	public abstract boolean executeAction(String actionName) ;
	
	public static BaseController newInstance(String controllerClass) {
		try {
			Object controller = Class.forName(controllerClass).newInstance();
			if (controller instanceof BaseController){
				return (BaseController) controller ;
			}
		}
		catch(ClassNotFoundException ex){}
		catch(Exception ex){}
		
		return null ;
	}

	public IRequestEntry getRequestEntry() {
		return requestEntry;
	}

	public void setRequestEntry(IRequestEntry requestEntry) {
		this.requestEntry = requestEntry;
	}

}

 

这样的控制器应该能够接受吧,算是基础类了吧... 无论是 spring mvc 还是 struts 基本都有一个分发器对象,用来将请求发送到 指定的控制器/Action里面,此处衍生了N多的XML配置文件,这样的我很不喜欢,说白了就是单一入口 的功能呗

 

我很讨厌 XML配置文件,很无语... 当初使用XML的目的,我感觉 应该是为了 解耦合和自定义常用参数 ... 可惜到现在膨胀到

方方面面 写代码的同时还要写XML,还美其名曰 为了解耦和 我不知道到底实现了没有 反正我不喜欢... 这也是我为什么从JAVA转行到PHP的原因之一.... 可能是我畏惧吧

 

IRequestEntry

 

作用就是 请求的入口点 里面封装了 常用的一些 方法:

public interface IRequestEntry extends IDataService {
	
	public String getRequestParameter(String parameter) ;
	
	public void setView(String view,String format) ;
	
	public void setView(String view) ;
	
	public void assign(String key,Object value) ;
	
	public boolean isPost() ;
	
	public boolean isGet() ;
	
	public boolean isAjax() ;
}

 

  IDataService

 

interface IDataService {
	public void service(Object request) throws Exception ;
}
 

请求的入口点 的作用 最明显的就是 充当 分发器...

 

为了尽可能的不使用 配置文件 这里使用 惯例设置吧 通过URI中挂载的参数 来传递 控制器 和 action 名字进来 , 并通过这些信息来加载指定的控制器对象,这里

 

HttpRequestEntry

 

public class HttpRequestEntry extends HttpServlet implements IRequestEntry {
	
	// 控制器基本信息
	private String controllerPackage = "" , currentController = "Application" ,currentAction = "index" ;
	private String viewBaseDir = "" ;
	
	private HttpServletRequest request = null ;

	public void init() throws ServletException {
		super.init();
		this.setControllerPackage(this.getInitParameter("controllerPackage"));
		this.setViewBaseDir(this.getInitParameter("viewBaseDir")) ;
		
		// ServletContext context = this.getServletContext();
		// -- load and init db pool
	}
	
	public void service(Object request) throws ControllerNotFound,ActionNotFound {
		// parseURI  -- load controller
		String controllerClass = this.getControllerClass(this.currentController) ;
		BaseController controller = BaseController.newInstance(controllerClass) ;
		
		if (controller != null){
			controller.setRequestEntry(this);
			
			boolean isExistAction = controller.executeAction(this.currentAction);
			if (!isExistAction){
				throw new ActionNotFound(controllerClass,this.currentAction) ;
			}
		}else {
			throw new ControllerNotFound(controllerClass) ;
		}
	}
	
	/**
	 * 每次Http请求,此方法仅仅执行一次
	 */
	public void service(HttpServletRequest request,HttpServletResponse response)
		throws IOException, ServletException {
		
		this.request = request ;
		
		this.setCurrentController(request.getParameter("controller"));
		this.setCurrentAction(request.getParameter("action"));	
		try {
			this.service(request);
			
		} catch (ControllerNotFound ex) {
			System.out.println(ex.getLocalizedMessage());
		} catch (ActionNotFound ex) {
			System.out.println(ex.getLocalizedMessage());
		}
		
		String viewName = this.getView() ;
		if (viewName != null){
			// 渲染视图
			String viewPath = "" ;
			
			if (this.viewBaseDir.endsWith("/"))
				viewPath = this.viewBaseDir + viewName ;
			else
				viewPath = this.viewBaseDir + "/" + viewName ;
			
			RequestDispatcher rd = this.getServletContext().getRequestDispatcher(viewPath);
			if (rd != null){
				rd.forward(request, response);
				
			}else {
				System.out.println("cannot load view file: " + viewPath);
			}
		}

	}

	// public boolean forward(String path){}

	// public boolean redirect(String uri,int timeout){}
	
	public String getRequestParameter(String parameter){
		return this.request.getParameter(parameter) ;
	}
	
	public void setView(String view,String format){
		this.request.setAttribute("#view#",view) ;
	}
	
	public String getView(){
		Object view = request.getAttribute("#view#") ;
		return  view != null ? (String) view : null ;
	}
	
	public void setView(String view){
		this.request.setAttribute("#view#","JSP") ;
	}
	
	public void assign(String key,Object value){
		this.request.setAttribute(key, value) ;
	}
	
	public boolean isPost(){
		return this.request.getMethod().equals("POST");
	}
	
	public boolean isGet(){
		return this.request.getMethod().equals("GET");
	}
	
	public boolean isAjax(){
		String r = this.request.getHeader("HTTP_X_REQUESTED_WITH") ;
		if (r != null && "xmlhttprequest".equals(r.toLowerCase())) return true ;
		return false ;
	}
	
	public String getControllerClass(String controller){
		return this.controllerPackage == "" ? controller : this.controllerPackage + "." + controller ;
	}
	
	public String getCurrentController() {
		return this.currentController;
	}

	public void setCurrentController(String currentController) {
		if (currentController == null || "".equals(currentController.trim()))
			currentController = "Application" ;
		else 
			currentController = com.moogens.Toolkit.toUpperFirstChar(currentController) ;
		
		this.currentController = currentController ;
	}

	public String getCurrentAction() {
		return this.currentAction;
	}

	public void setCurrentAction(String currentAction) {
		this.currentAction = currentAction == null ? "index" : currentAction ;
	}

	public String getControllerPackage() {
		return controllerPackage;
	}

	public void setControllerPackage(String controllerPackage) {
		this.controllerPackage = controllerPackage == null ? "" : controllerPackage;
	}

	public String getViewBaseDir() {
		return viewBaseDir;
	}

	public void setViewBaseDir(String viewBaseDir) {		
		if (viewBaseDir == null || "".equals(viewBaseDir.trim() ))
			viewBaseDir = "/WEB-INF/views" ;
		
		if (!viewBaseDir.startsWith("/")) 
			viewBaseDir = "/" + viewBaseDir ;
		
		String realBaseDir = getServletContext().getRealPath(viewBaseDir);
		File baseDir=new File(realBaseDir);
		if(!baseDir.exists()) baseDir.mkdir();
		this.viewBaseDir = viewBaseDir;
	}
}
 

重要的代码,此处因为每次HTTP请求只会执行1次,所以在这个方法里面去处理请求 并 负责常规的一些操作即可

 

public void service(HttpServletRequest request,HttpServletResponse response)
		throws IOException, ServletException {
		
		this.request = request ;
		
		this.setCurrentController(request.getParameter("controller"));
		this.setCurrentAction(request.getParameter("action"));	
		try {
			this.service(request);
			
		} catch (ControllerNotFound ex) {
			System.out.println(ex.getLocalizedMessage());
		} catch (ActionNotFound ex) {
			System.out.println(ex.getLocalizedMessage());
		}
		
		String viewName = this.getView() ;
		if (viewName != null){
			// 渲染视图
			String viewPath = "" ;
			
			if (this.viewBaseDir.endsWith("/"))
				viewPath = this.viewBaseDir + viewName ;
			else
				viewPath = this.viewBaseDir + "/" + viewName ;
			
			RequestDispatcher rd = this.getServletContext().getRequestDispatcher(viewPath);
			if (rd != null){
				rd.forward(request, response);
				
			}else {
				System.out.println("cannot load view file: " + viewPath);
			}
		}

	}

 

真正的数据处理的地方,加载控制器,执行action

 

	public void service(Object request) throws ControllerNotFound,ActionNotFound {
		// parseURI  -- load controller
		String controllerClass = this.getControllerClass(this.currentController) ;
		BaseController controller = BaseController.newInstance(controllerClass) ;
		
		if (controller != null){
			controller.setRequestEntry(this);
			
			boolean isExistAction = controller.executeAction(this.currentAction);
			if (!isExistAction){
				throw new ActionNotFound(controllerClass,this.currentAction) ;
			}
		}else {
			throw new ControllerNotFound(controllerClass) ;
		}
	}

 

控制器的一个例子

 

public final class Application extends BaseController {

	public Application() {
		// TODO: Add your code here
	}

       // 这个方法由子类自己实现,至于里面有多少个action 已经 action 对应的方法名字等等 必须在这里面
	public boolean executeAction(String action) {
			
		if (action.equals("index")){		
			this.indexAction();	
			return true ;
		}else if (action.equals("show")){
			this.showAction();	
			return true ;
		}
		
		return false ;
	}

	protected void indexAction(){
		 this.requestEntry.assign("title",this.toString() + " [indexAction]");
		 this.requestEntry.setView("application.jsp","JSP");
	}
	
	protected void showAction(){
		this.requestEntry.assign("title",this.toString() + " [showAction]");
		this.requestEntry.setView("application.jsp","JSP");
	}
}

 

 

基本Over了 这样的代码 在 Tomcat6上 确实可以跑 不知道效率怎么样 我也不知道 .... 应该是够简单明了的

 

 

 

 

我从接触计算机书籍的第一天起, 就认准一个死理:”如果你想从垃圾堆中找点吃的, 那么你就买中国人写的计算机书籍吧.”

 

 

------------------------------------------------------

 

做过小结: 附件代码

你可能感兴趣的:(java,框架,jsp,mvc,servlet)