MVC设计模式:
- 是这个几个名词的缩写:mode (模型),view(视图),controller(控制器).。
- 是一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
- MVC模式优点:耦合性低,重用性高,部署快,可维护性高。
- MVC模式缺点:不适合小型,中等规模应用程序,增加系统结构和实现的复杂性。
- MVC图解:
基于MVC设计框架:
springMVC:
SpringMVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架。
springMVC工作流程:
-
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet调用HandlerAdapter处理器适配器
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
组件:
以下组件通常使用框架提供实现:
DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其它组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。
HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
HandlAdapter:通过扩展处理器适配器,支持更多类型的处理器。
ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel等。
下边两个组件通常情况下需要开发:
Handler:处理器,即后端控制器用controller表示。
View:视图,即展示给用户的界面,视图中通常需要标签语言展示模型数据。
常用注解:
@Controller:用于标识是处理器类
@RequestMapping:请求到处理器功能方法的映射规则(@RequestMapping(value="/user")或@RequestMapping("/user"))
@RequestParam:绑定单个请求参数(
value:参数名字,即入参的请求参数名字,如value=“studentid”表示请求的参数区中的名字为studentid的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码;
defaultValue:默认值,表示如果请求中没有同名参数时的默认值
)
@PathVariable:用于将请求URL中的模板变量映射到功能处理方法的参数上
@RequestBody:@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转换为json、xml等格式的数据并绑定到controller方法的参数上。
@ResponseBody:该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端
Struts2:
Apache Struts 2最初被称为WebWork 2,它是一个简洁的、可扩展的框架,可用于创建企业级Java web应用程序。设计这个框架是为了从构建、部署、到应用程序维护方面来简化整个开发周期
- Struts2的前端控制器是个Filter(核心过滤器StrutsPrepareAndExecuteFilter)。
架构图解:
配置文件及加载顺序:
Struts2中的配置文件
配置文件的数量:
一共有6个配置文件。
6个配置文件执行时机:
default.properties 它都是key=value的形式。类似于开关。
struts-default.xml 配置的都是struts2的核心。纯struts2核心。
struts-plugin.xml 它是当我们使用了plugin的jar时才有的配置文件。如果没用插件,就没有。
struts.xml 我们程序中的struts2核心配置。是针对当前项目的核心配置。 推荐的
struts.properties struts2不仅支持基于xml的配置还可以再使用.properties。但是我们不推荐使用
web.xml 配置的是struts2的一些开关性配置。靠过滤器的初始化参数配置
Struts常见Action的3中方式:
- 1)普通的Java类
2)实现Action接口
3)继承ActionSupport类------(有Action接口的优点和自身的校验功能) -
Action接口中提供了五个逻辑视图名称:
* SUCCESS :成功
* ERROR :错误
* INPUT :用于数据校验
* LOGIN :用于登录
* NONE :页面不跳转
Struts2中Action方法的3种访问方式:
1)动态访问:
作用:减少Action数量 缺点:信息不安全
语法:actionName!methodName.action
使用:将属性struts.enable.DynamicMethodInvocation设置为true
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
2)通过method属性配置:
优点:避免动态方法调用的安全隐患
缺陷:导致大量的Action配置
3)通过通配符的配置方式:
<action name= "*User" class="cn.jbit.houserent.action.UserAction" method="{1}">
<result name=”success”>/{1}_success.jsp</result>
<result name="input">/{1}.jsp</result>
<result name="error">/error.jsp</result>
</action>
说明:------页面提交的路径要有一个统一的模块 *name(统一名)
编写form表单中action=”loginUser.action”
则struts.xml中的代码相当于
method="login"
/login_success.jsp
/login.jsp
Struts2三种访问Servlet的方式:
1)使用ActionContext对象访问
2)使用ServletActionContext对象访问
3)实现ServletRequestAware或ServletContextAware接口重写特定方法访问
OGNL表达式及相关对象:
1.什么OGNL表达式:OGNL的全称是对象图导航语言(Object-Graph Navigation Language),它是一种功能强大的开源表达式语言,使用这种表达式语言,可以通过某种表达式语法,存取Java对象的任意属性,调用Java对象的方法,同时能够自动实现必要的类型转换。如果把表达式看作是一个带有语义的字符串,那么OGNL无疑成为了这个语义字符串与Java对象之间沟通的桥梁。
- Struts2默认表达式。
- OGNL表达式不仅可以用于取值显示,还可以赋值。
-
<%--导入标签库--%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%--要想使用OGNL表达式,需要借助struts2的标签--%>
<s:property value=""/>
-
<s:property value="%{'OGNLExpression'}"/>
<s:property value='%{"OGNLExpression1"}'/>
-
OGNL表达式在取值时,只能作用在struts2的标签中,不能写在HTML标签里
2.ContexMap对象:
是OGNL上下文对象,是struts2中封装数据最大的对象,它是一个Map结构对象
3.ActionContex对象:
- 是Struts2提供操作ContextMap的一个工具类。
- 在StrutsPrepareAndExecuteFilter的doFilter方法执行时创建。
- 是线程安全对象:每次创建ActionContext时,把对象绑定到当前线程上
4.ValueStack对象:
- ValueStack是Struts的一个接口,字面意义为值栈,OgnlValueStack是ValueStack的实现类,客户端发起一个请求struts2架构会创建一个action实例同时创建一个OgnlValueStack值栈实例,OgnlValueStack贯穿整个 Action 的生命周期。
- 它是ContextMap中的一部分,里面的结构是一个List,是我们可以快速访问数据一个容器。它的封装是由struts2框架完成的。
Struts2拦截器:
1)执行流程:
客户端请求Action,1执行核心过滤器,在核心过滤器内部创建了Action的代理类,调用代理类的execute方法,在execute方法内部执行ActionInvocation的invoke方法。在invoke方法内部递归调用拦截器的拦截的方法。如果没有下一个拦截器执行目标Action,Action执行结束后根据Result进行页面跳转,执行拦截器的后面相应的代码,最后由response对象生成响应
2)执行时机:
在访问struts2核心内部时,在动作方法执行之前先正序执行,然后执行动作方法,执行完动作方法和结果视图之后,再倒序执行。所以它是先进后出,是个栈的结构,如图解:
3)定义拦截器:继承AbstractInterceptor,或者继承MethodFilterInterceptor。重写doInterceptor方法。
public class PrivilegeInterceptor extends MethodFilterInterceptor {
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
// 判断session中是否有登录的用户的信息。
User existUser = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
// 如果有信息放行,没有回到登录页面。
if(existUser == null){
// 说明没有登录过。
return "login";
}else{
// 已经登录成功。相当于放行
return invocation.invoke();
}
}
}
Struts2注解开发常用注解:
@NameSpace:
出现的位置:
它只能出现在package上或者Action类上。一般情况下都是写在Action类上。
作用:
指定当前Action中所有动作方法的名称空间。
属性:
value:指定名称空间的名称。写法和xml配置时一致。不指定的话,默认名称空间是""。
示例:
@Namespace("/")
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
private Customer customer = new Customer();
@Override
public Customer getModel() {
return customer;
}
}
@ParentPackage:
出现的位置:
它只能出现在package上或者Action类上。一般情况下都是写在Action类上。
作用:
指定当前动作类所在包的父包。
属性:
value:指定父包的名称。
示例:
@ParentPackage("struts-default")
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
private Customer customer = new Customer();
@Override
public Customer getModel() {
return customer;
}
}
@Action:
出现的位置:
它只能出现在Action类上或者动作方法上。一般情况下都是写在动作方法上。
作用:
指定当前动作方法的动作名称。此时action注解就是xml配置中的name属性。
属性:
value:指定动作名称。即与请求路径对应
results[]:它是一个数组,数据类型是注解。用于指定结果视图。此属性可以没有,当没有该属性时,表示不返回任何结果视图。即使用response输出响应正文。
interceptorRefs[]:它是一个数组,数据类型是注解。用于指定引用的拦截器。
示例:
@Action(value="addUICustomer",results={
@Result(name="addUICustomer",location="/jsp/customer/add.jsp")
})
public String addUICustomer(){
return "addUICustomer";
}
@Result:
出现的位置:
它可以出现在动作类上,也可以出现在Action注解中。
作用:
出现在类上,表示当前动作类中的所有动作方法都可以用此视图。
出现在Action注解中,表示当前Action可用此视图。
属性:
name:指定逻辑结果视图名称。
type:指定前往视图的方式。例如:请求转发,重定向,重定向到另外的动作。
location:指定前往的地址。可以是一个页面,也可以是一个动作类路径。
@Action(value="addCustomer",results={
@Result(name="addCustomer",type="redirect",location="/jsp/success.jsp")
})
public String addCustomer(){
customerService.saveCustomer(customer);
return "addCustomer";
}
Results:
出现的位置:
它可以出现在动作类上,也可以出现在Action注解中。
作用:
用于配置多个结果视图。
属性:
value:它是一个数组,数据类型是result注解。
示例:
@Results({
@Result(name="login",location="/login.jsp"),
@Result(name="error",location="/error.jsp")
})
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
private Customer customer = new Customer();
@Override
public Customer getModel() {
return customer;
}
}