1、什么是MVC:
MVC(Model View Controller)是一种软件设计的框架模式,它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离。把众多的业务逻辑聚集到一个部件里面,当然这种比较官方的解释是不能让我们足够清晰的理解什么是MVC的。用通俗的话来讲,MVC的理念就是把数据处理、数据展示(界面)和程序/用户的交互三者分离开的一种编程模式。
Model(模型):所有的用户数据、状态以及程序逻辑,独立于视图和控制器
1、entity 封装数据
2、dao 返回结果处理
3、service 进行业务处理
View(视图):呈现模型,类似于Web程序中的界面,视图会从模型中拿到需要展现的状态以及数据,对于相同的数据可以有多种不同的显示形式(视图)
1、view:展示页面
Controller(控制器):负责获取用户的输入信息,进行解析并反馈给模型,通常情况下一个视图具有一个控制器
1、controller:接受用户端请求,将模型和视图联系在一起以实现用户请求的功能
1.2、为什么要使用MVC
1:可以使同一个程序使用不同的表现形式,如果控制器反馈给模型的数据发生了变化,那么模型将及 时通知有关的视图,视图会对应的刷新自己所展现的内容
2:因为模型是独立于视图的,所以模型可复用,模型可以独立的移植到别的地方继续使用
3:前后端的代码分离,使项目开发的分工更加明确,程序的测试更加简便,提高开发效率
1.3、web程序中MVC的优点
1、 耦合性低:视图(页面)和业务层(数据处理)分离,一个应用的业务流程或者业务规则的改变只需要改动MVC中的模型即可,不会影响到控制器与视图
2、部署快,成本低:MVC使开发和维护用户接口的技术含量降低。使用MVC模式使开发时间得到相当大的缩减,它使程序员(Java开发人员)集中精力于业务逻辑,界面程序员(HTML和JSP开发人员)集中精力于表现形式上
3、可维护性高:分离视图层和业务逻辑层也使得WEB应用更易于维护和修改
1.4、web程序中MVC的缺点
1、调试困难:因为模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难,每个构件在使用之前都需要经过彻底的测试
2、不适合小型,中等规模的应用程序:在一个中小型的应用程序中,强制性的使用MVC进行开发,往往会花费大量时间,并且不能体现MVC的优势,同时会使开发变得繁琐
3、增加系统结构和实现的复杂性:对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率
4、视图与控制器间的过于紧密的连接并且降低了视图对模型数据的访问:视图与控制器是相互分离,但却是联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能
2、spring mvc框架简介及特点
1、Spring MVC采用了松散耦合的可插拔组件结构,比其他的MVC框架更具有灵活性和扩展性,Spring MVC通过使用一套注解,使一个Java类成为前端控制器(Controller),不需要实现任何接口,同时,Spring MVC支持RES形式的URL请求,除此之外,Spring MVC在在数据绑定、视图解析、本地化处理及静态资源处理上都有许多不俗的表现。
2、Spring MVC围绕DispatcherServlet(前端控制器)为中心展开,DispatcherServlet(前端控制器)是Spring MVC的中枢,和MVC的思想一样,它负责从视图获取用户请求并且分派给相应的处理器处理,并决定用哪个视图去把数据呈现给给用户
2.1、spring mvc生命周期:
2.2、spring mvc特点
1、清晰的角色划分:控制器,验证器,命令对象,表单对象和模型对象;分发器,处理器映射和视图解析器;等等。
2、直接将框架类和应用类都作为JavaBean配置,包括通过应用上下文配置中间层引用,例如,从web控制器到业务对象和验证器的引用。
3、可适应性,但不具有强制性:根据不同的情况,使用任何你需要的控制器子类(普通控制器,命令,表单,向导,多个行为,或者自定义的),而不是要求任何东西都要从Action/ActionForm继承。
4、可重用的业务代码,而不需要代码重复:你可以使用现有的业务对象作为命令对象或表单对象,而不需要在ActionForm的子类中重复它们的定义。
5、可定制的绑定和验证:将类型不匹配作为应用级的验证错误,这可以保存错误的值,以及本地化的日期和数字绑定等,而不是只能使用字符串表单对象,手动解析它并转换到业务对象。
6、可定制的处理器映射,可定制的视图解析:灵活的模型可以根据名字/值映射,处理器映射和视图解析使应用策略从简单过渡到复杂,而不是只有一种单一的方法。
7、可定制的本地化和主题解析,支持JSP,无论有没有使用Spring标签库,支持JSTL,支持不需要额外过渡的Velocity,等等。
8、简单而强大的标签库,它尽可能地避免在HTML生成时的开销,提供在标记方面的最大灵活性。
下面我们就自己来搭建一个spring mvc框架:
第一步:创建MAVEN项目(这里就不多做讲解了)
建好之后如图所示:
第二步:我们先导入pom.xml依赖包:
4.0.0
com.hxzy.spring
springmvc
0.0.1-SNAPSHOT
jar
springmvc
http://maven.apache.org
UTF-8
junit
junit
3.8.1
test
org.springframework
spring-web
4.0.9.RELEASE
org.springframework
spring-webmvc
4.0.9.RELEASE
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet
jstl
1.2
com.oracle
ojdbc6
11.2.0.1
commons-io
commons-io
2.1
commons-fileupload
commons-fileupload
1.2
第三步:在resource文件夹下创建spring-mvc.xml,进行配置
ViewResolver是一个试图解析器,就是我们第一部分提到的springMVC生命周期中的第五步,上面这段的配置的意思就是,当我们从后端控制器中返回的视图时,前端控制器就根据这一段配置来返回一个具体的视图,如后端控制返回的是一个hello,根据上面的配置,最后前端控制器会组并成这样的一个地址:/web-inf/jsp/hello.jsp,然后从/web-inf/jsp/这个目录下面查找一个hello.jsp返回客户端
第四步:配置web.xml文件
springmvc1
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath*:spring-mvc.xml
dispatcherServlet
*.html
上述的配置的就是前段控制器,在servlet-mapping配置了*.html,意味着所有以.html结尾的请求多会通过这个servlet,当dispatcherServlet启动时,他默认会在web-info目录下查找一个spring-mvc.xml的配置文件。上面我们通过显示指定了这个文件的位置,即在类路径底下的spring-servlet.xml.这个文件我们会在第二步点给他家做详细介绍。
contextConfigLocation
classpath:spring-mvc.xml
org.springframework.web.context.ContextLoaderListener
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
①、这样我们的spring mvc框架就搭建好了,可以开始写代码了,我们来看个简单的登录例子:
实体层(entity):User
public class User {
private String username;
private String password;
省略get和set方法….
数据处理层(dao)
UserDao:
public interface UserDao {
public User getUser(User user);
}
BaseDao:
public abstract class BaseDao {
private String username = "scott";
private String password = "sa";
private String url = "jdbc:oracle:thin:@localhost:1521:orcl";
public static Connection conn= null;
public static PreparedStatement pstm= null;
public static ResultSet rs= null;
/**
* *得到连接
*/
public Connection getConn() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* *关闭连接
*/
public void closeConn() {
try {
if(rs!=null) {
rs.close();
}
if(pstm!=null) {
pstm.close();
}
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
接口实现类(Impl):
public class UserDaoImpl extends BaseDao implements UserDao{
@Override
public User getUser(User user) {
// TODO Auto-generated method stub
String sql = "select username,password from t_user where username = ? and password= ?";
User userinfo = null;
try {
conn = getConn();
pstm = conn.prepareStatement(sql);
pstm.setString(1, user.getUsername());
pstm.setString(2, user.getPassword());
rs = pstm.executeQuery();
while(rs.next()) {
userinfo = new User(rs.getString("username"),rs.getString("password"));
}
} catch (SQLException e) {
// TODO: handle exception
e.printStackTrace();
}
return userinfo;
}
}
业务逻辑层(service):
UserService:
public interface UserService {
public User getUser(User user);
}
接口实现类:
UserServiceImpl:
public class UserServiceImpl implements UserService{
UserDao userdao = new UserDaoImpl();
@Override
public User getUser(User user) {
// TODO Auto-generated method stub
return userdao.getUser(user);
}
}
控制层(Controller):
LoginController:
@Controller//声明这个类是个控制器,在spring-mvc.xml文件标签中配置了扫描器。
@RequestMapping("/user")//声明一个路径,只要符合"/user"路径的都会通过这个控制器中的方法做处理
public class LoginController {
UserService userservice = new UserServiceImpl();
@RequestMapping(method = RequestMethod.POST,value = "login")
public ModelAndView login(@ModelAttribute User user,ModelAndView mav) {
User u = userservice.getUser(user);
if(u==null) {
mav.setViewName("../login");//返回登录界面
}else {
mav.setViewName("../info");//进入登录成功界面
mav.addObject(u);//参数传递
}
return mav;
}
}
JSP页面:
login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
Insert title here
Info.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
${user.username }
②、现在我们再来看个上传下载的例子,工作中也会时常用到:
UploadController:
UploadController:
@Controller
public class UploadController {
@RequestMapping("/upload")//映射请求地址
public String upload(@RequestParam("file") MultipartFile file) throws UnsupportedEncodingException{//绑定参数
String path = this.getClass().getResource("/").getPath();//获得当前文件的路径
path = path.substring(0, path.indexOf("/WEB-INF")+1)+"upload";
System.out.println(path);
File file2 = new File(path);
if(!file2.exists()) {
file2.mkdirs();//创建保存文件的目录
}
File file3 = new File(path+"/"+file.getOriginalFilename());//上传文件的路径+文件名
if(!file3.exists()) {
try {
file3.createNewFile();//创建上传的文件
file.transferTo(file3);//将上传的文件保存到服务器上指定的文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
}
上传下载jsp页面:
upload.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
③、很多时候需求上需要对表单进行国际化处理,这里我也写了一个例子:
Messages_en.properties:(英语)
username = username
Messages_zh.properties:(中文)
username = \u7528\u6237\u540d
Messages_jp.properties:(日语)
username = \u30e6\u30fc\u30b6\u30fc\u540d
控制层(GJHController):
@Controller
public class GJHController {
@Autowired//指定成员变量 消除set,get方法
private SessionLocaleResolver sessionLocaleResolver;
@RequestMapping("/gjh.html")
public String gjh(@RequestParam("locale") String locale,HttpServletRequest request,HttpServletResponse response) {
if("zh".equals(locale)) {
sessionLocaleResolver.setLocale(request, response, Locale.CHINA);
}else if("en".equals(locale)){
sessionLocaleResolver.setLocale(request, response, Locale.ENGLISH);
}else {
sessionLocaleResolver.setLocale(request, response, Locale.JAPAN);
}
return "gjh";
}
}
Jsp页面:gjh.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
Insert title here
中国话
英国话
日本话
这样,你应该对spring mvc框架的理解有所加深了吧,请大家多多关注。。