Java学习总结 SpringBoot整合Spring MVC
 
1.SpringMVC概述
 
MVC(Model–view–controller)是软件工程中的一种软件架构模式,基于此模式把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。目的是通过这样的设计使程序结构更加简洁、直观,降低问题的复杂度。其中各个组成部分的职责为: 视图(View) - UI设计人员进行图形界面设计,负责实现与用户交互。 控制器(Controller)- 负责获取请求,处理请求,响应结果。 模型(Model) - 实现业务逻辑,数据逻辑实现。
 
我们在软件设计时,通常要遵循一定的设计原则。MVC架构模式的设计中,首先基于单一职责原则(SRP-Single responsibility principle)让每个对象各司其职,各尽所能。 然后再基于“高内聚,低耦合”的设计思想实现相关层对象之间的交互。这样可以更好提高程序的可维护性和可扩展性。 JavaEE技术体系中,MVC设计思想的实现,如图-14所示:  在上图中,Servlet充当MVC中的Controller,负责调用model处理业务,负责转发或重定向某个页面,在页面(view)上呈现数据。 模块封装了对Servlet的技术的应用,简化了程序员对请求和响应过程中数据的处理。Spring MVC 是Spring 框架中基于MVC设计思想实现的一个用于处理Web请求的模块。其简易架构分析,如下图所示:  DispatcherServlet :前端控制器, 处理请求的入口。 HandlerMapping:映射器对象, 用于管理url与对应controller的映射关系。 Interceptors:拦截器,实现请求响应的共性处理。 Controller:后端控制器-handler, 负责处理请求的控制逻辑。 ViewResolver:视图解析器,解析对应的视图关系(前缀+viewname+后缀)。 备注:假如希望了解Spring MVC的详细处理流程可以基于断点调试法进行跟踪。
 
2.初始配置
 
1. 添加Spring MVC依赖
 
编辑pom.xml文件,添加web依赖,Thymeleaf依赖,代码如下: Web依赖(提供了Spring MVC核心API,同时会嵌入一个Tomcat服务器)
 
<dependency>
		<groupId>org
.springframework
.boot
</groupId
>
		<artifactId>spring
-boot
-starter
-web
</artifactId
>
</dependency
>
 
Thymeleaf依赖(提供了一个视图解析器对象以及数据绑定机制)
 
<dependency>
	   <groupId>org
.springframework
.boot
</groupId
>
	   <artifactId>spring
-boot
-starter
-thymeleaf
</artifactId
>
</dependency
>
 
其中: Spring Web Starter 提供Spring MVC 依赖支持,并会自动添加一个tomcat依赖,作为嵌入式web服务器使用.thymeleaf是一个html模板引擎,提供了与Spring MVC进行整合的API,可作为MVC架构中Web应用的View层。
 
2. 配置Spring MVC 核心对象
 
在application.proper视ties文件中添加图解析器配置(假如没有配置也会默认配置,在默认配置中prefix默认值为classpath:/templates/,后缀默认为.html)。
 
spring
.thymeleaf
.prefix
=classpath
:/templates
/pages
/
spring
.thymeleaf
.suffix
=.html
 
说明:要基于配置在src/main/resources目录下创建templates/pages目录
 
3.Spring MVC 进行入门实践
 
第一步:编写GoodsController类并将其交给spring管理。这样的Controller在SpringMVC 规范中通常称之为Handler(处理器),我们在企业中有时也会将此对象理解为一个后端控制器。
 
package com
.cy
.pj
.goods
.controller
;
@Controller
	
@RequestMapping("/goods/")
public class GoodsController {
     @RequestMapping("doGoodsUI")
public String 
doGoodsUI() {
	   return "goods";
	}
}
 
第二步:需要在/templates/pages/目录下创建goods.html 第三步:启动服务器(默认项目嵌入的是tomcat),打开浏览器进行访问测试。 http://localhost:8080/goods/doGoodsUI API应用设计,如图所示: 
 
课堂练习1:将数据库中的商品数据查询出来更新到页面上。
 
查询时序分析:
 
 
第一步:定义pojo对象(com.cy.pj.goods.pojo.Goods)
 
package com
.cy
.pj
.goods
.pojo
;
import java
.util
.Date
;
public class Goods {
    private Long id
;
    private String name
;
    private String remark
;
    private Date createdTime
;
    public Long 
getId() {
        return id
;
    }
    public void setId(Long id
) {
        this.id 
= id
;
    }
    public String 
getName() {
        return name
;
    }
    public void setName(String name
) {
        this.name 
= name
;
    }
    public String 
getRemark() {
        return remark
;
    }
    public void setRemark(String remark
) {
        this.remark 
= remark
;
    }
    public Date 
getCreatedTime() {
        return createdTime
;
    }
    public void setCreatedTime(Date createdTime
) {
        this.createdTime 
= createdTime
;
    }
    @Override
    public String 
toString() {
        return "Goods{" +
                "id=" + id 
+
                ", name='" + name 
+ '\'' +
                ", remark='" + remark 
+ '\'' +
                ", createdTime=" + createdTime 
+
                '}';
    }
}
 
第二步:定义GoodsDao接口及方法
 
package com
.cy
.pj
.goods
.dao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import org
.apache
.ibatis
.annotations
.*
;
import java
.util
.List
;
@Mapper
public interface GoodsDao {
    
    @Select("SELECT id,name,remark,createdTime FROM tb_goods")
    List
<Goods> findObjects();
}
 
第三步:定义GoodsService接口及其实现类
 
GoodsService
 
package com
.cy
.pj
.goods
.service
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import java
.util
.List
;
public interface GoodsService {
    List
<Goods> findGoods();
}
 
GoodsServiceImpl
 
package com
.cy
.pj
.goods
.service
.impl
;
import com
.cy
.pj
.goods
.dao
.GoodsDao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Service
;
import java
.util
.List
;
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsDao goodsDao
;
    @Override
    public List
<Goods> findGoods() {
        Long start
=System
.currentTimeMillis();
        List
<Goods> list
=goodsDao
.findObjects();
        long end
=System
.currentTimeMillis();
        System
.out
.println("query time:"+(end
-start
));
        return list
;
    }
}
 
第四步:定义GoodsController及其url映射
 
package com
.cy
.pj
.goods
.controller
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Controller
;
import org
.springframework
.ui
.Model
;
import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
import java
.util
.List
;
@Controller
@RequestMapping("/goods/")
public class GoodsController {
    @Autowired
    private GoodsService goodsService
;
    
    
    
    
    
    @RequestMapping("doGoodsUI")
    public String 
doGoodsUI(Model model
) {
        
        List
<Goods> list 
= goodsService
.findGoods();
        
        model
.addAttribute("list", list
);
        
        return "goods";
        
        
        
        
    }
}
 
第五步:定义goods.html,通过Thymeleaf模板将活动数据呈现在页面上
 
<!DOCTYPE html
>
<html lang
="en" xmlns
:th
="http://www.thymeleaf.org">
<head>
    <meta charset
="UTF-8">
    <title>Title
</title
>
</head
>
<body>
    <table>
        <thead>
            <th>id
</th
>
            <th>name
</th
>
            <th>remark
</th
>
            <th>createdTime
</th
>
        </thead
>
        <tbody>
            <tr th
:each
="g:${list}" >
                <td th
:text
="${g.id}"></td
>
                <td th
:text
="${g.name}"></td
>
                <td th
:text
="${g.remark}"></td
>
                <td th
:text
="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td
>
            </tr
>
        </tbody
>
    </table
>
</body
>
</html
>
 
第六步:运行Application启动服务器,在网页中输入url地址
 
启动服务器:  在网页中输入url地址:http://localhost:8080/goods/doGoodsUI 查询结果如下: 
 
课堂练习二:基于ID删除商品库中的商品信息
 
时序分析:
 
 
第一步:GoodsDao中定义基于id删除记录的方法 deleteById(Integer id);
 
package com
.cy
.pj
.goods
.dao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import org
.apache
.ibatis
.annotations
.*
;
import java
.util
.List
;
@Mapper
public interface GoodsDao {
    
    @Delete("delete from tb_goods where id=#{id}")
    int deleteById(Integer id
);
    
    
    @Select("SELECT id,name,remark,createdTime FROM tb_goods")
    List
<Goods> findObjects();
}
 
第二步:GoodsService及实现类中定义deleteById(Integer id)方法用于执行记录删除
 
GoodsService
 
package com
.cy
.pj
.goods
.service
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import java
.util
.List
;
public interface GoodsService {
    List
<Goods> findGoods();
    void deleteById(Integer id
);
}
 
GoodsServiceImpl
 
package com
.cy
.pj
.goods
.service
.impl
;
import com
.cy
.pj
.goods
.dao
.GoodsDao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Service
;
import java
.util
.List
;
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsDao goodsDao
;
    @Override
    public List
<Goods> findGoods() {
        Long start
=System
.currentTimeMillis();
        List
<Goods> list
=goodsDao
.findObjects();
        long end
=System
.currentTimeMillis();
        System
.out
.println("query time:"+(end
-start
));
        return list
;
    }
    @Override
    public void deleteById(Integer id
) {
        int rows
=goodsDao
.deleteById(id
);
    }
}
 
第三步:ActivityController中定义doDeleteById(Integer id)方法用于处理删除请求
 
package com
.cy
.pj
.goods
.controller
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Controller
;
import org
.springframework
.ui
.Model
;
import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
import java
.util
.List
;
@Controller
@RequestMapping("/goods/")
public class GoodsController {
    @Autowired
    private GoodsService goodsService
;
    
    @RequestMapping("doDeleteById")
    public String 
doDeleteById(Integer id
){
        
        goodsService
.deleteById(id
);
        
        
        return "redirect:doGoodsUI";
    }
    
    
    
    
    @RequestMapping("doGoodsUI")
    public String 
doGoodsUI(Model model
) {
        
        List
<Goods> list 
= goodsService
.findGoods();
        
        model
.addAttribute("list", list
);
        
        return "goods";
        
        
        
        
    }
}
 
第四步:定义goods.html,通过Thymeleaf模板将活动数据呈现在页面上
 
<!DOCTYPE html
>
<html lang
="en" xmlns
:th
="http://www.thymeleaf.org">
<head>
    <meta charset
="UTF-8">
    <title>Title
</title
>
</head
>
<body>
    <table>
        <thead>
            <th>id
</th
>
            <th>name
</th
>
            <th>remark
</th
>
            <th>createdTime
</th
>
        </thead
>
        <tbody>
            <tr th
:each
="g:${list}" >
                <td th
:text
="${g.id}"></td
>
                <td th
:text
="${g.name}"></td
>
                <td th
:text
="${g.remark}"></td
>
                <td th
:text
="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td
>
                <td><a th
:href
="@{/goods/doDeleteById(id=${g.id})}">delete
</a
></td
>
            </tr
>
        </tbody
>
    </table
>
</body
>
</html
>
 
第五步:运行Application启动服务器,在网页中输入url地址
 
启动服务器:  在网页中输入url地址:http://localhost:8080/goods/doGoodsUI  点击delete 
 
课堂练习三:将页面用户输入的商品信息写入到数据库
 
时序分析
 
 
第一步:在GoodsDao中定义insert(Goods entity)方法以及SQL映射
 
package com
.cy
.pj
.goods
.dao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import org
.apache
.ibatis
.annotations
.*
;
import java
.util
.List
;
@Mapper
public interface GoodsDao {
    
    @Delete("delete from tb_goods where id=#{id}")
    int deleteById(Integer id
);
    
    
    int deleteObjects(Integer
...ids
);
    
    @Select("SELECT id,name,remark,createdTime FROM tb_goods")
    List
<Goods> findObjects();
    @Insert("insert into tb_goods (name,remark,createdTime) values(#{name},#{remark},now())")
    int insert(Goods entity
);
}
 
第二步:在GoodsService接口及实现类中添加insert(Goods entity)
 
GoodsService
 
package com
.cy
.pj
.goods
.service
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import java
.util
.List
;
public interface GoodsService {
    List
<Goods> findGoods();
    void deleteById(Integer id
);
    int insert(Goods entity
);
}
 
GoodsServiceImpl
 
package com
.cy
.pj
.goods
.service
.impl
;
import com
.cy
.pj
.goods
.dao
.GoodsDao
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Service
;
import java
.util
.List
;
@Service
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsDao goodsDao
;
    @Override
    public List
<Goods> findGoods() {
        Long start
=System
.currentTimeMillis();
        List
<Goods> list
=goodsDao
.findObjects();
        long end
=System
.currentTimeMillis();
        System
.out
.println("query time:"+(end
-start
));
        return list
;
    }
    @Override
    public void deleteById(Integer id
) {
        int rows
=goodsDao
.deleteById(id
);
    }
    @Override
    public int insert(Goods entity
) {
        int rows
=goodsDao
.insert(entity
);
        return rows
;
    }
}
 
第三步:在GoodsController对象中添加doSaveGoods方法并定义url映射
 
package com
.cy
.pj
.goods
.controller
;
import com
.cy
.pj
.goods
.pojo
.Goods
;
import com
.cy
.pj
.goods
.service
.GoodsService
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Controller
;
import org
.springframework
.ui
.Model
;
import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
import java
.util
.List
;
@Controller
@RequestMapping("/goods/")
public class GoodsController {
    @Autowired
    private GoodsService goodsService
;
    
    @RequestMapping("doDeleteById")
    public String 
doDeleteById(Integer id
){
        
        goodsService
.deleteById(id
);
        
        
        return "redirect:doGoodsUI";
    }
    @RequestMapping("doSaveGoods")
    public String 
doSaveGoods(Goods entity
){
        goodsService
.insert(entity
);
        return "redirect:doGoodsUI";
    }
    
    
    
    
    @RequestMapping("doGoodsUI")
    public String 
doGoodsUI(Model model
) {
        
        List
<Goods> list 
= goodsService
.findGoods();
        
        model
.addAttribute("list", list
);
        
        return "goods";
        
        
        
        
    }
}
 
第四步:在页面中goods.html添加form表单(用户填写数据)并设置样式
 
<!DOCTYPE html
>
<html lang
="en" xmlns
:th
="http://www.thymeleaf.org">
<head>
    <meta charset
="UTF-8">
    <title>Title
</title
>
</head
>
<body>
   <form action
="/goods/doSaveGoods" method
="post">
       <ul>
           <li>name
:
           <li><input type
="text" name
="name">
           <li>remark
:
           <li><textarea rows
="5" cols
=""50 name
="remark"></textarea
>
           <li><input type
="submit" value
="save"></li
>
       </ul
>
   </form
>
   <fieldset>
       <legend>商品列表
</legend
>
       <table width
="50%">
    <table>
        <thead>
            <th>id
</th
>
            <th>name
</th
>
            <th>remark
</th
>
            <th>createdTime
</th
>
        </thead
>
        <tbody>
            <tr th
:each
="g:${list}" >
                <td th
:text
="${g.id}"></td
>
                <td th
:text
="${g.name}"></td
>
                <td th
:text
="${g.remark}"></td
>
                <td th
:text
="${#dates.format(g.createdTime,'yyyy/MM/dd HH:mm')}"></td
>
                <td><a th
:href
="@{/goods/doDeleteById(id=${g.id})}">delete
</a
></td
>
            </tr
>
        </tbody
>
    </table
>
</body
>
</html
>
 
第五步:在表单中输入数据,然后点击保存按钮,将数据传递到服务端