SpringMVC框架的入门
一. 概述
随着Web应用复杂度的不断提升,单纯使用JSP技术完成Web应用程序开发的弊端越来越明显.在应用程序中引入控制器(Servlet/Filter)则可以有效的避免在JSP页面编写大量的业务和页面跳转代码.而JSP则专门用于展示内容,这种程序设计模式就是我们要学习的MVC设计模式了.了解了MVC设计模式之后,我们就开始学习Controller层的框架产品Spring MVC.
二. MVC设计模式
1.开发架构的形式
- C/S 客户端/服务器端
- B/S 浏览器/服务器(java开发中的结构)
- 在企业级的项目(J2EE)中,几乎都是基于B/S架构的开发
2.标准的三层架构
- 表现层
- 业务层
- 持久层
总结:三层架构在我们的实际开发中经常使用,每一层各司其职
3.服务器端的三层架构的介绍
3.1表现层
表现层又称为Web层
作用:
接收客户端提交的Http请求,向客户端响应结果
组成:
表现层=显示层+控制层
显示层:在客户端显示结果
控制层:接收请求,处理请求,响应
依赖:
表现层依赖于业务层,当表现层接收到客户端请求要调用业务层进行处理并将结果响应给客户端.
设计模型:
MVC模型
3.2业务层:
即Service层
作用:
负责业务逻辑的处理,与项目的需求有关
依赖:
表现层依赖业务层,业务层不依赖表现层
当进行数据持久化操作的时候,业务层依赖持久层也就是事务处理
3.3持久层:
即Dao层
作用:
负责数据持久化操作,和数据库进行交互,对数据库表进行CRUD操作
组成:
数据库+数据访问层
数据库:是对数据进行持久化的载体
数据访问层:是业务层和持久层交互的载体,业务层通过数据访问层将数据持久化到数据库中
###4.MVC模型
4.1定义
MVC=Model(模型)+View(视图)+Controller(控制器)
是用于设计Web应用程序表现层的模式
4.2Model(模型)
模型对象拥有最多的处理任务,是应用程序的主体部分.数据模型,一般封装用户数据的
作用:
负责数据逻辑(业务规则)的处理和实现数据操作(在数据库中存取操作)
对应的组件:
JavaBean(对象)=处理业务逻辑的Service层+数据库操作相关的Dao层+贯穿于各层之间的数据模型就是数据实体POJO
4.3View(视图)
对应组件:
JSP/HTML/freemarker/thymeleaf
作用:
展示数据
负责格式化数据并把数据呈现给用户,包括=数据展示+用户交互+数据验证+页面设计等.
4.4Controller(控制器)
对应组件:
Servlet:(学过)
Spring MVC:(即将要学)
Struts2
作用:
负责接收并转发请求,对请求进行处理后指派视图并将响应结果发送给客户端.
5.MVC两种模式
5.1 JSP Model1
当业务流程比较简单的时候,可以把控制器的功能交给视图来实现.这种模式称为JSP Model1,即Model1模式只有视图+模型,没有控制器(JSP+JavaBean)
(1)Model1的基础是JSP,它由JSP和JavaBean组成.
(2) JSP从Http request中获得所需的数据,并进行业务逻辑的处理,然后将结果通过Http Response返回给前端浏览器.
(3) 从中可见,Model1在一定程度上实现了MVC,即JSP将控制层和视图层合二为一,JavaBean为模型层.其中JSP身兼多职,既要负责视图层的数据显示,又要负责业务流程的控制,结构比较混乱,并且也不是我们所希望的松耦合架构模式.所以当业务流程复杂的时候并不推荐使用.
5.2JSP Model2
相比于JSP Model1,当业务流程复杂的时候,就需要把业务流程控制交给控制器来实现,JSP专注于视图的显示即可.这种模式就是JSP Model2(即JSP+Servlet+JavaBean)相比Model1,Model2是将控制层(Servlet)单独划分出来负责业务流程的控制,接收请求,创建所需的JavaBean实例,并将处理后的数据再返回给视图层(JSP)进行界面的数据展示.这样的结构清晰,效果明显优化好多.并且也是一个松耦合的架构模式,所以除非项目非常简单,一般情况下建议使用JSP Model2.
6.MVC整体处理过程
6.1MVC整体的处理过程
(1)首先视图提供系统与用户交互的界面,并发送用户输入给控制器
(2) 控制器接收用户请求,并决定应用调用哪个模型来进行处理
(3) 模型根据用户请求进行相应的业务逻辑处理,并返回处理结果(数据)
(4) 控制器根据返回的处理结果,调用相应的视图格式化模型返回的数据,并通过视图呈现给用户结果
7.MVC优点
- 多视图共享一个模型,大大提高代码的可重用性
- MVC三个模块相互独立,松耦合结构
- 控制器提高了应用程序的灵活性和可配置性
- 有利于软件工程化管理
- 总之:我们通过MVC的设计模式最终可以打造出一个
松耦合+高重用性+高可适配性=完美架构
8.MVC缺点
- 原理复杂
- 增加了系统结构和实现的复杂性
- 视图对模型数据的低效率访问
###9.总结
对于MVC来说,它并不适合小型甚至中型规模的项目,花费大量时间将MVC应用到规模并不是很大的应用程序通常是得不偿失,所以对于MVC设计模式的使用要根据具体的应用场景来决定
package com.tye.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@Controller
public class DemoController {
@RequestMapping("/hello")
public String test1() {
System.out.println("hello");
return "home";
}
@RequestMapping("/test2")
public String test2(int sid,String sname){
System.out.println(sid+""+sname);
return "home";
}
@RequestMapping("/test3")
public String test3(int gender,String uname){
System.out.println(gender+""+uname);
return "home";
}
@RequestMapping("/test4")
public String test4(int age, String uname, HttpServletRequest request, HttpSession httpSession){
if(age<17){
httpSession.setAttribute("uname",uname);
return "redirect:child.jsp";
}else {
request.setAttribute("uname",uname);
return "adult";
}
}
@RequestMapping("/ajaxDemo2")
public void ajaxDemo2(HttpServletResponse res){
try {
System.out.println("enter");
PrintWriter pw = res.getWriter();
pw.write("hello wo shi tye");
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/test5",method= RequestMethod.POST)
public String test5(@RequestParam(value = "age",required = false,defaultValue = "0")int ageee,
@RequestParam(value = "uname")String name){
System.out.println(ageee+1);
return null;
}
@RequestMapping(value = "/test6/{type}/xx",method= RequestMethod.GET)
public String test6(@PathVariable("type")int type){
System.out.println("type"+type);
return null;
}
@RequestMapping(value = "/test7/{type}/{uname}",method= RequestMethod.GET)
public String test7(@PathVariable("type")int type,@PathVariable("uname")String xingming){
System.out.println("type"+type+"uname"+xingming);
return null;
}
@RequestMapping(value = "/test8",method= RequestMethod.GET)
@ResponseBody
public String test8(){
return "<h1 align='center'>sdfiudshfdsihdf</h1>";
}
@RequestMapping(value = "/test9")
@ResponseBody
public String test9(){
return "sdffdsfds";
}
}
package com.tye.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.tye.model.entity.Msg;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.tye.dao.BaseDao;
import com.tye.dao.StudentDao;
import com.tye.model.dto.StudentScoreVo;
import com.tye.model.entity.Student;
import com.tye.service.StudentService;
import com.tye.service.impl.StudentServiceImpl;
@Controller
public class StudentController {
private StudentService stuService = new StudentServiceImpl();
@RequestMapping("/reg")
public String reg(Student student,HttpServletRequest request) {
int i = BaseDao.getSession(true).getMapper(StudentDao.class).addStudent(student);
if (i>0) {
return "index";
} else {
request.setAttribute("info", "数据库操作失败");
return "reg";
}
}
@RequestMapping("/phoneCheck")
public void phoneCheck(String shouji,HttpServletResponse res) {
int i = BaseDao.getSession().getMapper(StudentDao.class).checkPhoneCount(shouji);
String answer = "ok";
if (i>0) {
answer="no";
}
try {
PrintWriter pw = res.getWriter();
pw.write(answer);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping("/login")
public String login(String sid,String phone,HttpServletRequest request,HttpSession session) {
System.out.println(sid);
try {
int sidint = new Integer(sid);
Student stu = stuService.getStuBySid(sidint, phone);
if (stu!=null) {
//登录成功
session.setAttribute("stu", stu);
if (stu.getLevel()==5) {
//班主任
return "redirect:/initMaster.do";
}else {
return "home";
}
} else {
return "index";
}
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("info", "sid内容有问题");
return "error";
}
}
@RequestMapping("/initMaster")
public String initMaster(HttpServletRequest request) {
System.out.println("1111");
List<StudentScoreVo> stus = stuService.getAllStu();
List<Msg> msgs = stuService.getUnreadMsg();
int size = msgs.size();
request.setAttribute("msgs", msgs);
request.setAttribute("size", size);
request.setAttribute("stus", stus);
return "master";
}
@RequestMapping("/sendMsg")
public String sendMsg(String sname,String msg,HttpServletRequest request) {
String info="";
if (stuService.addMsg(sname,msg)) {
info="消息已发送";
} else {
info="消息发送出错";
}
request.setAttribute("info", info);
return "home";
}
@RequestMapping("/dealMsg/{type}")
public String dealMsg(@PathVariable("type")int type,@RequestParam("mid")int mid,HttpServletRequest request) {
String info="";
if (!stuService.dealMsg(mid,type)) {
info="消息处理出错";
}
request.setAttribute("info", info);
return "redirect:/initMaster.do";
}
}
package com.tye.dao;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class BaseDao {
public static SqlSessionFactory getFactory() {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static SqlSession getSession() {
return getFactory().openSession();
}
public static SqlSession getSession(boolean isAutoCommit) {
return getFactory().openSession(isAutoCommit);
}
}
package com.tye.dao;
import java.util.List;
import com.tye.model.dto.StudentScoreVo;
import com.tye.model.entity.Msg;
import com.tye.model.entity.Student;
import org.apache.ibatis.annotations.Param;
public interface StudentDao {
List<StudentScoreVo> getScoreInfo();
Student getStuBySid(int sid);
int addStudent(Student student);
int checkPhoneCount(String phone);
int insertMsg(@Param("sname")String sname,@Param("msg")String msg);
List<Msg> getMsgsByStatus(int status);
int updMsg(@Param("mid")int mid,@Param("type")int type);
}
package com.tye.model.entity;
public class Student {
int sid,age,gender,level,yanzhi;
String phone,sname;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public int getYanzhi() {
return yanzhi;
}
public void setYanzhi(int yanzhi) {
this.yanzhi = yanzhi;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
package com.tye.service.impl;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import com.tye.model.entity.Msg;
import com.tye.service.StudentService;
import com.tye.dao.BaseDao;
import com.tye.dao.StudentDao;
import com.tye.model.dto.StudentScoreVo;
import com.tye.model.entity.Student;
public class StudentServiceImpl implements StudentService{
@Override
public Student getStuBySid(int sid,String phone) {
Student stu = BaseDao.getSession().getMapper(StudentDao.class).getStuBySid(sid);
if (stu!=null&&stu.getPhone().equals(phone)) {
return stu;
}else {
return null;
}
}
@Override
public List<StudentScoreVo> getAllStu() {
return BaseDao.getSession().getMapper(StudentDao.class).getScoreInfo();
}
@Override
public boolean addMsg(String sname, String msg) {
int i = BaseDao.getSession(true).getMapper(StudentDao.class).insertMsg(sname, msg);
if (i>0) {
return true;
}
return false;
}
@Override
public List<Msg> getUnreadMsg() {
List<Msg> msgs = BaseDao.getSession(true).getMapper(StudentDao.class).getMsgsByStatus(1);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (Msg msg : msgs) {
String ctime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// sdf.format(msg.getCreatedTime());
msg.setCreatedTimeStr(ctime);
String utime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
;
// sdf.format(msg.getUpdatedTime());
msg.setUpdatedTimeStr(utime);
}
return msgs;
}
@Override
public boolean dealMsg(int mid, int type) {
int i = BaseDao.getSession(true).getMapper(StudentDao.class).updMsg(mid,type);
if (i>0) {
return true;
}
return false;
}
}
package com.tye.service;
import java.util.List;
import com.tye.model.dto.StudentScoreVo;
import com.tye.model.entity.Msg;
import com.tye.model.entity.Student;
public interface StudentService {
Student getStuBySid(int sid,String phone);
List<StudentScoreVo> getAllStu();
boolean addMsg(String sname,String msg);
List<Msg> getUnreadMsg();
boolean dealMsg(int mid,int type);
}