软件开发中的MVC设计模式
软件开发的目标是减小耦合,让模块之前关系清晰.
MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数据库三层分离,减小耦合.
1)Model : 负责抽象并存储数据库数据
2)Controller : 负责数据的转化和传输
3)View : 负责展示数据
注意 : ORM框架一般都会将数据库数据封装存储至Model类中,所以MVC框架其实只做了一件事,开发者需要做三件.
MVC框架 : 前台数据与实体数据的互为转化
开发者 : 配置框架,编写业务代码,前台数据展示页面
SpringMVC简介
Spring 框架提供了MVC模块,主要作用也是将前台数据和实体数据进行转化,先来看看.
上述为一张自制的Spring MVC工作流程图,从上面的环节可以很清晰地明白SpringMVC的工作关系,上面的方法是DispatcherServlet的方法.由上可见,在SpringMVC中承担主要工作的是DispatcherServlet,而所有部分除了ModelAndView之类基本就是Controller层的组成部分.
SpringMVC入门案例(XML配置版)
由上图指导,我们可以清晰地知道我们需要怎么配置这个框架
1)导入支持包,Spring core,Spring web,Spring aop这三个模块的包,并且应用了Servlet,所以servlet支持包,以及log4j这种包.应用jsp技术需要导入standard,jstl等包.
2)在web.xml中配置DispatcherServlet
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
web.xml
3)编写Controller类
/** * 控制器 * @author AdminTC */ public class HelloAction implements Controller{ /** * 业务方法 */ public ModelAndView handleRequest(HttpServletRequest requqest,HttpServletResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message","这是我的第一个springmvc应用程序"); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } }
HelloAction.java
4)编写页面,在/WebRoot/下创建jsp/success.jsp
<%@ page language="java" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>这是我的第一个springmvc应用程序</title> </head> <body> success.jsp<br/> ${message} </body> </html>
success.jsp
5)在/WEB-INF/创建DispatcherServlet-servlet.xml配置文件,xml头部信息与spring.xml相同
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd "> <!-- 注册控制器(程序员) --> <bean name="/hello.action" class="com.harry.mvc.HelloAction"></bean> <!-- 映射器(框架) --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean> <!-- 适配器(框架) --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean> <!-- 视图解析器(框架) --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean> </beans>
DispatcherServlet-servlet.xml
注意 : 可以在web.xml中修改DispatcherServlet-servlet.xml文件名及其路径
<!-- 注册springmvc框架核心控制器 --> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:com.harry.mvc.config.spring.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
web.xml
映射器-适配器-视图解析器-控制器
映射器(映射什么请求交给什么控制器)
1) org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping(核心)
作用:将开发者定义的Controller(Action)所定义的<bean>标签中的name属性作为请求路径
<!-- 注册控制器(程序员) --> <bean name="/hello.action" class="com.harry.mvc.HelloAction"></bean> <!-- 映射器(框架) --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
DispatcherServlet-servlet.xml
2) org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
作用:将多个路径映射至同一个Controller(Action)
<!-- 注册控制器(开发者) --> <bean id="userActionID" class="com.harry.mvc.UserAction"></bean> <!-- 注册映射器(handler包)(框架) --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="/delete.action">userActionID</prop> <prop key="/update.action">userActionID</prop> <prop key="/find.action">userActionID</prop> </props> </property> </bean>
DispatcherServlet-servlet.xml
适配器(在多个Controller中寻找对应的Controller)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
视图解析器(指定逻辑名的前后缀)
org.springframework.web.servlet.view.InternalResourceViewResolver
作用是解析视图逻辑路径名称对应的真实路径
<!-- 视图解析器(框架) --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
DispatcherServlet-servlet.xml
控制器 (开发者编写加入其他业务代码的入口)
public class EmpAction implements Controller{ public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception { System.out.println("EmpAction::handleRequest"); request.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message",username); modelAndView.setViewName("/jsp/success.jsp"); return modelAndView; } }
实现Controller接口
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.multiaction.MultiActionController; public class UserController extends MultiActionController{ public ModelAndView home(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView model = new ModelAndView("home"); model.addObject("message", "Home"); return model; } public ModelAndView add(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView model = new ModelAndView("user"); model.addObject("message", "Add"); return model; } public ModelAndView remove(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView model = new ModelAndView("user"); model.addObject("message", "Remove"); return model; } }
继承多动作控制器,能够同时绑定多个方法
注意 : Spring MVC中前面三者配置方式方法众多,但它们做的事情差不多,所以理解了后完全可以自己查找文档.
常见问题
日期转换
在默认情况下,springmvc不能将String类型转成Date类型,必须自定义类型转换器
public class AdminAction extends MultiActionController{ @Override protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception { binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true)); }
编码转换
由于提交数据的规范是使用POST方法,所以Spring提供了解决中文乱码问题的方案
<!-- 编码过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
web.xml