设计模式-----MVC
一、MVC框架
主要是将web程序,分为三个层次,model层,view层,control层。其中,大家各尽其责,model层主要负责javabean类,和数据库类,主要负责数据。view层,负责显示,control层负责业务逻辑处理。使得网站的结构更加清晰,维护更加便利。
第一、控制层:主控制器的实现。
主控制器,如果不经过主控制器,我们的可以通过连接地址来直接访问servlet程序,但是如果我们需要隐藏servlet的映射地址,和不希望用户直接就能访问我的servlet,我们可以只写一个servlet,也就是主控制器,通过这个servlet,根据用户输入的请求地址,调用对应处理程序,处理程序进行处理,比如在请求对象中加入属性,或者在会话对象中加入属性 ,然后返回结果给主控制器,主控制器根据返回结果跳转。这样一来,就只有一个servlet,这个servlet我们通过配置url映射,可以将需要主控制器处理的一类访问进行处理,如果.do结尾的访问。
首先,配置一个servlet作为主控制器:
<servlet> <description>主控制器</description> <servlet-name>control</servlet-name> <servlet-class>lmj.servlet.ControlServlet</servlet-class> <init-param> <param-name>ShowMainPage</param-name> <param-value>lmj.action.ShowMainPage</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>control</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
在上面的配置中,给servlet配置了初始参数,并且给了参数的值,我们需要根据它来进行反射来动态的调用处理程序。经过上面的配置,凡是.do结尾的请求,都会访问这个servlet,也就这个对应的java类,下来看看在java程序中,如果根据请求来动态调用处理程序:
public class ControlServlet extends HttpServlet { //不管是get或者是post请求都会先调用servlet的service方法,所以我们可以直接重新这个方法 @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //拿到请求的地址,解析出需要的部分,再通过它查看初始参数对应的值,再根据初始化参数的值,反射出处理程序的对象 //处理对象调用处理程序,返回处理结果。 String spath = request.getRequestURI(); //截取需要的部分,去掉前面的路径和后缀.do //现在将user的文件放在一个文件夹 比如 8080/boke5/user/mainpage.do 需要保留/user/mainpage.do //因为已经将只有通过/user/*这样的访问才可以访问到user文件夹资源,我们在配置参数的时候也是/user/**.do //现在,需要用户输入 /user/ 我们才会调用主控制程序中对应的处理程序,不然我们不做处理,而这样/user/的输入 //是经历权限过滤的,所以处理程序不需要再判断权限。我们的配置参数加上了/user/,所有需要截取/user/** String path0 = spath.substring(spath.indexOf("/")+1,spath.lastIndexOf(".do")); System.out.println("****访问路径截取1"+path0); String path = path0.substring(path0.indexOf("/")+1); System.out.println("****访问路径截取2"+path); //通过该servlet对象得到初始参数,初始参数的值就是对应的处理程序 String classpath = this.getInitParameter(path); System.out.println(classpath); //如果有对应的处理程序,就处理,没有就跳转到错误页面.
分析:首先我们覆写了httpservlet的service方法,覆写这个方法的原因是,不管你是post还是get请求访问该servlet都会调用这个方法,就不用在覆写post和get方法。
注意第二点:我们通过请求对象,得到用户的请求地址,在截取出我们需要的部分,再根据这儿部分去查找匹配主控制servlet有没有与之对应的初始参数名,如果有就取出来,这个值就是进行处理的类的全名称,得到了类全名称,就可以通过反射得到类的对象,再调用处理方法,级可以给主servlet返回处理结果。
这里需要看清楚通过this.getInitParameter(path); 来查找初始参数
下面看一看处理程序,我们规定一个接口,所有的处理程序都必须实现该接口,也作为处理程序的标志。
public interface ActionInterface { public String execute(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException; }
该接口,只需定义一个处理方法,该方法需要传入请求对象和响应对象,这样我们才好处理
再看处理程序类怎么写:
public class ShowMainPage implements ActionInterface { @Override public String execute(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // 通过model层,得到所有需要的数据, // 再将所有传递的数据,放到需要的地方,比如request或者session // 得到所有最新文章,和最新用户 // 查询所有文章 // 得到第几页 int page=0; try { page = Integer.parseInt(request.getParameter("page")); } catch (Exception e) { //如果取得第几个页面出错,则表示第一个页面 page=1; } GetArticleDao getarticle = new GetArticleDao(); //参数0表示查询得到的是所有的文章 ArrayList<Article> articles= getarticle.getNerArticle(page, 0); //得到最后一页的页数,0表示所有文章 int lastpage= getarticle.getNum(0); //将当前是第几个页面,最后的页数,该页需要显示的文章,放在request中, // 主控制器,跳转到指定的jsp,jsp就可以访问这些数据 if(page<=0||page>lastpage){ return "error.jsp"; } request.setAttribute("lastpage", lastpage); request.setAttribute("page", page); request.setAttribute("articles", articles); // return "mainpage.jsp"; } }
处理完成之后我们就返回一个需要跳转的地址,主控制根据它来跳转即可。
上面所述,也就是控制层。
视图层,就是jsp页面,通过el表达式,和jstl核心标签,方便的进行取值和显示。
model层,在很多情况下,我们需要操作数据库,我们单独写出很多操作数据库的类,供处理程序来调用,这样结构根据清晰。需要使用到的对象,也写在该包下,也就够成了model层。