Java MVC三层架构在各框架中的特征
整理源生的jsp+servlet框架、struts1、struts2、springMVC这几个框架,激动之中未免有些不足,在这些框架里面要想从整体的角度考虑,就必须把客户端到服务器端所有的东西理清晰。
1.基于web开发中最原始的jsp+Servlet 图形化理解jsp+servlet结构:
1.从结构上分析jsp+servlet图解原理:
在基于mvc设计模式下的最原始的jsp+Servlet框架,在某种程度上是不能够达到mvc最直观的体现。当客户端发送请求到服务器时,服务器会将从客户端接收到的信息通过封装技术进行解析,在交给web容器,web容器会通过一篇web.xml的配置文件去找与之相匹配的servlet,此时servlet会开启一个线程,只要是符合web.xml中所配置的某一个servlet时,该servelt就会启动,然后servlet在去调用service或者service的接口实现类,service(impl)在去调用dao(impl),dao通过从数据库(Database)那获取到数据,在封装到model实体类中去。Servlet在完成这一系类的动作后,最终将为我们返回一个jsp页面,最后该页面在返回到客户端展示给客户。
2.从web.xml配置上:
<?xml version="1.0"?> <web-app> <servlet> <servlet-name>TextSerevlet</servlet-name> <servlet-class>com.lh.serivlet.UserSerivlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TextSerevlet</servlet-name> <url-pattern>/accessServlet</url-pattern> </servlet-mapping> </web-app>
注:需要用到的每一篇servlet都要写入它的配置文件。Web.xml的配置量大,繁杂。从性能优异的角度考虑,它的运行性能是最快的,但是开发性能就很有难度。
3.控制器:
Jsp+servlet的控制器是:工程中的每一个xxxServlet就充当一个控制器,但是必须去extends HttpServlet,并重写 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }
4.作用域对象
ServletContext(上下文),也叫全局的作用域对象。
Session(会话)服务器的一次会话中或者服务器超时。
Request(请求)在一次请求的过程中。
Respones(响应)
5.数据绑定:没有,只能通过数组去获取页面的数据。
6.类型转换:将jsp页面的数据转换为String类型。也可以是基本数据类型。但是要进行强制转换。
7.有效性验证:可以在某一个需要用到Servlet的类中用java代码进行验证。也可以在jsp页面书写ajax代码进行验证或者是定义function()函数,在函数中用正则表达式加以判断。
8.操作业务层对象调业务方法:在某一个XxxServlet中extends HttpServlet并重写doPost()和doGet()方法,我们只需在doGet()或者doPost()中用request.getParameter()方法来得到页面的数据。如果我们要操作到业务层我们只需在当前的这个类中实例化出业务层的类,即XxxService dao = new XxxServiceImpl();然后获取实体Bean对象中的属性。最后在我们需要用到数据访问层的哪一个具体的业务实现方法就用实例化出的dao调用所需方法即可。
9.返回:可以返回对象,也可以返回具体要跳转的哪个页面。
10.在js页面做显示:EL表达式,JSP脚本表达式
11.标签:HTML标签,JSP自定义标记库,JST L标准标记库。
12.文件上传:页面需要怎样获取?<form action=”file” method=”post” enctype=”multipart/form-data”>
服务器怎么获得?1.必须导入文件上传的jar包。2.
13.过滤器:我们自己定义的一个类XxxFilter 必须implements Filter接口,并实现它的三个方法,destroy(),doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException ,init(FilterConfig arg0)。在doFilter()中调用chain.doFilter(request, response)方法,表示将请求交给下一个组件。
1.从结构上分析Struts1图解原理:
客户端发送请求到服务器,服务器将收到的信息传给web容器,这时,web容器会通过到web.xml配置文件中去查找那篇符合命名规范的action属性中的*.do,在交给ActionServlet(中央核心控制器),通过该配置,web容器将信息传给具体的某一个XxxAction,该XxxAction会继承Action,并重写它的
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { ........ }
方法,同时,我们可以在该XxxAction中去调用JavaBean中的实体对象。但是,需要注意的是,在ActionServlet到Action这一过程中,我们是通过Form组件技术来对jsp页面的信息来进行了一次封装,达到了前端页面(jsp)和后台的实体Bean对象之间的一次数据的绑定。最后再是到Struts-config.xml文件中进行进行配置,通过正确的配置找到所需的jsp.
2从web.xml配置上:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!-- 主配置文件,param-name的值为config --> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-lx.xml,/WEB-INF/struts-zh.xml</param-value> </init-param> <!-- 子配置文件,param-name的值只能以config/开头 <init-param> <param-name>config/m1</param-name> <param-value>/WEB-INF/struts-zh.xml</param-value> </init-param> --> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <filter> <filter-name>CharsetFilter</filter-name> <filter-class> com.lovo.struts.filter.CharsetFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> <init-param> <param-name>ignore</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharsetFilter</filter-name> <url-pattern>*.do</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CharsetFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
注:从上面的配置中我们可以看出,servlet的配置是必不可少的。
3.控制器:ActionServlet是struts1的中央核心控制器,它在web.xml中配置成自动启动的Servlet,在启动时中央核心控制器会读取配置文件(struts-config.xml)的配置信息,为struts中不同的模块初始化相应的对象。
6.类型转换:LoginForm loginF = (LoginForm)form;
7.有效性验证:验证框架,不能重写Validate方法。也可以自定义验证规则,但是必须做配置。
9.返回:Action将业务处理的不同结果返回一个目标响应对象给中央核心控制器,或者返回一个页面mapping.findForward("success")
10.在js页面做显示:EL表达式,自定义标签库,直接在jsp页面上写java代码。
11.标签:
3.基于web开发中Struts2框架的结构图:
1.从结构上分析Struts2图解原理:
Struts2的思想是基于JOPO(简单的老的Java对象)的一种新思想而产生的。一度影响了重量级的容器。它的实现是靠用简单的javabean对象去完成各种复杂的功能。我们也可以把这一实现的过程称为JOPO。
在Struts2中是没有容器的。当客户端发送一个请求时,在服务器上会经过层层过滤器,最后到达FilterDispatcher(Struts2中的中央核心控制器),中央核心控制器在通过层层的拦截器去找相应的Action,最后Action返给我们一个所访问的页面,由于在Struts2中的拦截器是上下文相互环绕的,所以,在当Action中的Resulet返给我们一个页面的同时还会在次进行后期的拦截器处理,就这样一层层的拦截,直到将最终所取得的信息传给HttpServletResponse,在接着就是HttpServletResponse会将得到的信息响应给HttpServletRequest.但在这个响应的过程中也再次经过了过滤器的过滤。直到信息完整的到达HttpServletRequest。
2从web.xml配置上:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
3.控制器:核心控制器:FilterDispatcher,在web应用中负责拦截所有的用户请求,如果用户的请求以 .ation结尾,则该请求被传入到struts2框架处理。业务控制器: Action(在struts2中起作用的实际上不是用户自定义的Action,而是系统自动生成的action代理,但该代理是以用户自定义的action为目标的)
4.作用域对象:有前面的struts1中我们可以从Action的execute方法中将请求和响应当做参数传递给了Action,但是在Struts2中我们会发现Action的execute方法是没有任何的参数,所以也就无法得到作用域对象。那么,Struts2又是如何得到作用域对象的呢?分析:当Struts2的过滤器启动的时候,首先就会初始化一个叫做ServletActionContext的类。它掌管着所有的作用域对象。代码展示如下:
import org.apache.struts2.ServletActionContext; public class ContextAction implements Action { public String execute() throws Exception { //获得请求 HttpServletRequest request = ServletActionContext.getRequest(); //获得会话 HttpSession session = request.getSession(); //获得上下文对象 ServletContext application = ServletActionContext.getServletContext(); } }
10.在js页面做显示:OGNL
11.标签:OGNL表达式、EL表达式、Struts2框架自身提供的标签库、html标签。
1.从结构上分析springMVC图解原理:
springMVC的出现是在struts2的发展上而兴起的。SpringMVC的设计思想被评委教科书式的框架,它是最能体现出MVC设计模式中的分离与互用的极致。所以,基于springMVC的原理我们是非常有必要进行掌握并深入理解的。我们必须清楚的了解Spring的MVC框架主要由DispatcherServlet、处理器映射、处理器、视图解析器、视图组成。浏览器发送请求到spring容器,spring容器通过在web.xml配置文件中找到中央核心控制器(DispatcherServlet)的url配置,并且在web.xml中还必须要配置一个初始化的加载参数(详见下面2),当DispatcherServlet接收到一个请求后,它会通过请求的HandlerMapping处理映射路径去找到在Spring-servlet.xml配置文件中的一个处理器(Controller),该处理器会找到具体的某一个Xxxservlet,Xxxservlet会将所获取到的信息间接的传给DispatcherServlet,在这一个过程中会有一个ModelAndView的对象产生(体现出了SpringMVC分离的思想)。当DispatcherServlet得到这个ModelAndView后会将信息传给ViewResolver,这时ViewResolver会将符合格式的view返回出来,最后再将符合格式的数据响应到浏览器端。
2从web.xml配置上:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>mySpring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/mySpring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mySpring</servlet-name> <url-pattern>*.spring</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 注:<init-param>参数的配置是必不可少的。必须是在/WEB-INF目录下的classes子目录下的我们自己定义的 哪一篇xxx-servlet.xml文件。
3.控制器:DispatcherServlet,该控制的作用是将请求转发到相应的应用控制器。
4.作用域对象:在SpringMVC中不推荐使用。
5.数据绑定:springMVC支持的数据绑定有6种,1.有基本数据类型绑定(String和String[])。2.简单对象类型绑定(类似与struts中的ActionForm)。3.List类型绑定(必须创建ArrayList对象来进行绑定)。4.Set类型绑定(必须在Set对象中Add相应的数量的模型对象)。5.Map类型绑定(必须依靠Bean对象)。6.复合数据类型绑定(要求在自己定义的Bean对象上的某个属性也必须是一个Bean对象)。
6.类型转换:在SpringMVC中有两种类型转换的方式.1.属性编辑器(propertyEditor),属性编辑器是我们最传统的做法。我们只需要通过一个@InitBider注解来完成,方法中的参数是WebRequestDateBinder或者WebDateBinder。在这个方法中,我们可以通过重写PropertyEditorSupport中的setAsText()来定义自己的转换规则。
2.类型转换器(Converter),相对于第一种属性编辑器它的功能更大,它可以对任何类型的数据进行转换。我们在编写一个类型转换器时,一定要去implements它的Converter接口。
7.有效性验证:通过注解的形式来注入@pattern和@valid来进行有效性验证,这也是我们常用到的验证注入。
1.导包
2.书写配置springMVC自己提供的文件上传的配置。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="100000000"> </property> </bean>
3.写jsp页面,注意文件上传的<form>表单里面的属性。
<form action="upload.spring" name="uploadForm" method="post" enctype="multipart/form-data"> ............ </form>
4.书写控制器UploadController在控制器的方法处理中,从作用域中获取file文件,通过path路径和文件名将文件存入到当前工程的文件夹下。
package com.lh.controller; import java.io.File; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.commons.CommonsMultipartFile; @Controller public class UploadController { @RequestMapping("/upload") public String upload(HttpServletRequest request ,@RequestParam("file")CommonsMultipartFile file){ //从作用域中获取文件的path路径,通过request.getSession().getServletContext().getRealPath("upload")。 String path = request.getSession().getServletContext().getRealPath("upload"); //通过file来获取文件名。 String name = file.getOriginalFilename(); try { file.getFileItem().write(new File(path+"/"+name)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return "upload"; } return "success"; } }
5.测试文件是否上传成功。
在springMVC中实现拦截器,调用它的3个方法。:
1.书写拦截器有两种方式: 1-1继承HandlerInterceptorAdaptor类,代码展示如下: package com.lh.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class Interceptor1 extends HandlerInterceptorAdapter {
//在控制器传递到拦截器将数据交给DisPacheServlet的过程中将资源清理。 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("The Main of claening...."); } //在方法之后 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("The Main of after..."); } //在方法之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("The Main of Before...."); return true; } }
1-2.实现HandlerInterceptor接口 代码展示如下:
package com.lh.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class Interceptor2 implements HandlerInterceptor { //在控制器传递到拦截器将数据交给DisPacheServlet的过程中将资源清理。 public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception { System.out.println("The Mian of cleaning2....."); } //在方法之后 public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception { System.out.println("The Mian of After..."); } //在方法之前 public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("The Mian of Befor....."); return true; } }
2. 在xml中配置拦截器:
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/register.spring"></mvc:mapping> <bean class="com.lh.interceptor.Interceptor1"></bean> </mvc:interceptor> </mvc:interceptors>
注:如果有多个拦截器就需要配置拦截器栈(先进后出)。
3.在tomcat服务器上发布,测试拦截效果是否达到。
来自:http://my.oschina.net/win199176/blog/208171