目前比较好的MVC框架,老牌的有Struts1.x、Webwork (Struts2)。新的MVC框架有Spring MVC、Tapestry、JSF等。这些大多是著名团队的作品。这些框架都提供了较好的层次分隔能力。在实现良好的MVC 分隔的基础上,通过提供一些现成的辅助类库,同时也促进了生产效率的提高。
Spring框架是业务层框架,核心组件是容器 它是管理bean的,广义上讲任何一个javaBean它都管理,实例化对象 两大概念:IOC、AOP
IOC : (Inversion of Control)
它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。它是获得依赖对象的方式。
好莱坞原则,即“不要打电话过来,我们会打给你”。
AOP:( Aspect-Oriented Programming) 面向方面编程
可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。
当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
引入jar包
spring-aop-3.2.2.jar 面向切片编程
spring-aspects-3.2.2.jar 提供对AspectJ的支持,以便可以方便的将面向方面的功能集成进IDE中
spring-beans-3.2.2.jar 核心。访问配置文件、创建和管理bean 以及进行IoC/DI操作相关的所有类。
spring-context-3.2.2.jar为Spring 核心提供了大量扩展。
spring-context-support-3.2.2.jar
spring-core-3.2.2.jar Spring 框架基本的核心工具类。外部依赖Commons Logging 。
spring-expression-3.2.2.jar 配置对象的注入,它便是SpEL (Spring Expression Language)
spring-web-3.2.2.jar Web 应用开发时,用到Spring 框架时所需的核心类
spring-webmvc-3.2.2.jar Spring MVC 框架相关的所有类。包括框架的Servlets,Web MVC框架,控制器和视图支持。
注意spring3.0的包名是 org.spingframework.web.servlet-3.1.0 RELEASE.jar
com.springsource.org.apache.commons.logging-1.1.1.jar 日志
com.springsource.org.aopalliance-1.0.0.jar AOP联盟的API包,里面包含了针对面向切面的接口。
配置分发器servlet DispatchServlet
action
org.springframework.web.servlet.DispatcherServlet
action
*.action
创建控制器类
public class HomeController extends AbstractController {
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("HomeController...");
return new ModelAndView("index");
}
}
配置beans,创建spring配置文件 /WEB-INF/action-servlet.xml
创建jsp文件
<%@ page language="java" pageEncoding="UTF-8"%>
index.jsp
This is my JSP page.
发布、测试
DispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
DispatcherServlet
*.action
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
视图解析器【解析视图逻辑名对应的真实路径】【配置可省】InternalResourceViewResolver
/**
* 单例
* 控制器Action
* 处理器Action
* @author albin
*/
public class HelloAction implements Controller{
/**
* 业务方法
*/
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message","这是我的第二个springmvc应用程序,视图使用逻辑名");
//原来封装视图的真实路径
//modelAndView.setViewName("/jsp/success.jsp");
//现在封装视图的逻辑名称
modelAndView.setViewName("success");
return modelAndView;
}
}
java
/**
* 控制器
* @author 谢斌
*/
public class UserAction implements Controller{
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("操作用户");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message","操作用户成功");
modelAndView.setViewName("success");
return modelAndView;
}
}
xml
userActionID
userActionID
userActionID
java
/**
* 控制器是实现Controller接口的类
* @author 谢斌
*/
public class EmpAction implements Controller{
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
ModelAndView modelAndView = new ModelAndView();
//设置编码方式
request.setCharacterEncoding("UTF-8");
//获取员工姓名
String username = request.getParameter("username");
//显示
System.out.println("员工姓名:" + username);
//将员工姓名封装到ModelAndView对象中去
modelAndView.addObject("message",username);
//将真实路径名封装到ModelAndView对象中去
modelAndView.setViewName("/jsp/success.jsp");
return modelAndView;
}
}
xml
java
/**
* 单例
* 控制器(程序员)
*/
@Controller
public class HelloAction{
public HelloAction(){
System.out.println("HelloAction()::" + this.hashCode());
}
/**
* 业务方法
* 只要是/hello.action的请求,都交由HelloAction对象中的hello()方法去处理
*/
@RequestMapping(value="/hello.action")
public String hello(Model model) throws Exception{
System.out.println("HelloAction::hello()");
model.addAttribute("message","你好");
return "success";
}
/**
* 业务方法
* 只要是/bye.action的请求,都交由HelloAction对象中的bye()方法去处理
*/
@RequestMapping(value="/bye.action")
public String bye(Model model) throws Exception{
System.out.println("HelloAction::hello()");
model.addAttribute("message","再见");
return "success";
}
}
xml
控制器
/**
* 控制器
* @author albin
*/
@Controller
@RequestMapping(value="/user")
public class UserAction {
/**
* 用户注册
*/
@RequestMapping(value="/register")
public String registerMethod(Model model) throws Exception{
model.addAttribute("message","员工注册成功");
return "/jsp/success.jsp";
}
/**
* 用户登录
*/
@RequestMapping(value="/login")
public String loginMethod(Model model) throws Exception{
model.addAttribute("message","员工登录成功");
return "/jsp/success.jsp";
}
spring.xml
控制器
/**
* 控制器
* @author albin
*/
@Controller
@RequestMapping(value="/user")
public class UserAction {
/**
* 用户注册,只能接收POST请求
*/
@RequestMapping(method=RequestMethod.POST,value="/register")
public String registerMethod(Model model,String username,String salary) throws Exception{
System.out.println("用户注册-->" + username + ":" + salary);
model.addAttribute("message","员工注册成功");
return "/jsp/success.jsp";
}
/**
* 用户登录,即能接收POST请求,又能接收GET请求
*/
@RequestMapping(value="/login")
public String loginMethod(Model model,String username) throws Exception{
System.out.println("用户登录-->" + username);
model.addAttribute("message","员工登录成功");
return "/jsp/success.jsp";
}
}
控制器
/**
* 控制器
* @author albin
*/
@Controller
@RequestMapping(value="/user")
public class UserAction {
/**
* 用户注册,只能接收POST请求
*/
@RequestMapping(method=RequestMethod.POST,value="/register")
public String registerMethod(HttpServletRequest request,HttpServletResponse response) throws Exception{
//获取用户名和薪水
String username = request.getParameter("username");
String salary = request.getParameter("salary");
System.out.println("用户注册-->" + username + ":" + salary);
//绑定到session域对象中
request.getSession().setAttribute("username",username);
request.getSession().setAttribute("salary",salary);
//重定向/jsp/success.jsp页面
//response.sendRedirect(request.getContextPath()+"/jsp/success.jsp");
//转发/jsp/ok.jsp页面
request.getRequestDispatcher("/jsp/ok.jsp").forward(request,response);
//转发(提倡)
return "/jsp/success.jsp";
}
}
控制器
/**
* 控制器
* @author albin
*/
@Controller
@RequestMapping(value="/user")
public class UserAction {
/**
* 自定义类型转换器
*/
@InitBinder
public void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(
Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),true));
}
/**
* 用户注册,只能接收POST请求
*/
@RequestMapping(method=RequestMethod.POST,value="/register")
public String registerMethod(User user,Model model) throws Exception{
System.out.println("用户注册:" + user.toString());
//将user绑定到model对象中
model.addAttribute("user",user);
//转发到success.jsp页面
return "/jsp/success.jsp";
}
}
控制器
/**
* 控制器
* @author albin
*/
@Controller
@RequestMapping(value="/person")
public class PersonAction {
@InitBinder
public void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(
Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
/**
* 业务方法
*/
@RequestMapping(value="/register")
public String registerMethod(Bean bean,Model model) throws Exception{
System.out.println("普通用户:" + bean.getUser());
System.out.println("管理员:" + bean.getAdmin());
//将user和admin都绑定到Model
model.addAttribute("user",bean.getUser());
model.addAttribute("admin",bean.getAdmin());
//转发
return "/02_person.jsp";
}
}
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
@RequestMapping(value="/deleteAll",method=RequestMethod.POST)
public String deleteAll(Model model,int[] ids) throws Exception{
System.out.println("需要删除的员工编号分别是:");
for(int id : ids){
System.out.print(id+" ");
}
model.addAttribute("message","批量删除员工成功");
return "/jsp/ok.jsp";
}
}
控制器
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
/**
* 批量添加员工
*/
@RequestMapping(value="/addAll",method=RequestMethod.POST)
public String addAll(Model model,Bean bean) throws Exception{
for(Emp emp:bean.getEmpList()){
System.out.println(emp.getUsername()+":"+emp.getSalary());
}
model.addAttribute("message","批量增加员工成功");
return "/jsp/ok.jsp";
}
}
控制器
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
@RequestMapping(value="/find")
public String findEmpById(int id,Model model) throws Exception{
System.out.println("查询"+id+"号员工信息");
//转发到EmpAction的另一个方法中去,即再次发送请求
return "forward:/emp/update.action";
//重定向到EmpAction的另一个方法中去,即再次发送请求
//return "redirect:/emp/update.action?id=" + id;
}
@RequestMapping(value="/update")
public String updateEmpById(int id,Model model) throws Exception{
System.out.println("更新" + id +"号员工信息");
model.addAttribute("message","更新员工信息成功");
return "/jsp/ok.jsp";
}
}
案例
@Controller
@RequestMapping(value="/emp")
public class EmpAction {
/**
* @ResponseBody Emp 表示让springmvc将Emp对象转成json文本
*/
@RequestMapping(value="/bean2json")
public @ResponseBody Emp bean2json() throws Exception{
//创建Emp对象
Emp emp = new Emp();
emp.setId(1);
emp.setUsername("哈哈");
emp.setSalary(7000D);
emp.setHiredate(new Date());
return emp;
}
@RequestMapping(value="/listbean2json")
public @ResponseBody List listbean2json() throws Exception{
//创建List对象
List empList = new ArrayList();
//向List对象中添加三个Emp对象
empList.add(new Emp(1,"哈哈",7000D,new Date()));
empList.add(new Emp(2,"呵呵",8000D,new Date()));
empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
//返回需要转JSON文本的对象
return empList;
}
@RequestMapping(value="/map2json")
public @ResponseBody Map map2json() throws Exception{
//创建List对象
List empList = new ArrayList();
//向List对象中添加三个Emp对象
empList.add(new Emp(1,"哈哈",7000D,new Date()));
empList.add(new Emp(2,"呵呵",8000D,new Date()));
empList.add(new Emp(3,"嘻嘻",9000D,new Date()));
//创建Map对象
Map map = new LinkedHashMap();
//向Map对象中绑定二个变量
map.put("total",empList.size());
map.put("rows",empList);
//返回需要转JSON文本的对象
return map;
}
}
* jsp