它是基于MVC开发模式的框架,用来优化控制器.它是Spring家族的一员.它也具备IOC和AOP.
它是一种开发模式,它是模型视图控制器的简称.所有的web应用都是基于MVC开发.
M:模型层,包含实体类,业务逻辑层,数据访问层
V:视图层,html,javaScript,vue等都是视图层,用来显现数据
C:控制器,它是用来接收客户端的请求,并返回响应到客户端的组件,Servlet就是组件
1)轻量级,基于MVC的框架
2)易于上手,容易理解,功能强大
3)它具备IOC和AOP
4)完全基于注解开发
SpringMVC的执行流程
1)新建项目,选择webapp模板.
2)修改目录,添加缺失的test,java,resources(两套),并修改目录属性
3)修改pom.xml文件,添加SpringMVC的依赖,添加Servlet的依赖
<!--springMVC依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--添加servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
4)添加springmvc.xml配置文件,指定包扫描,添加视图解析器.
<!--添加包扫描-->
<context:component-scan base-package="com.bjpowernode.controller"></context:component-scan>
<!--添加视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/admin/"></property>
<!--配置后缀-->
<property name="suffix" value=".jsp"></property>
</bean>
5)删除web.xml文件,新建web.xml
6)在web.xml文件中注册springMVC框架(所有的web请求都是基于servlet的)
<!--注册SpringMVC框架-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
指定拦截什么样的请求
http://localhost:8080/one
http://localhost:8080/index.jsp
http://localhost:8080/demo.action
<a href="${pageContext.request.contextPath}/demo.action">访问服务器</a>
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
7)在webapp目录下新建admin目录,在admin目录下新建main.jsp页面,删除index.jsp页面,并新建,发送请求给服务器
8)开发控制器(Servlet),它是一个普通的类.
@Controller //交给Spring去创建对象
public class DemoAction {
/**
* 以前的Servlet的规范
* protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
* action中所有的功能实现都是由方法来完成的
* action方法的规范
* 1)访问权限是public
* 2)方法的返回值任意
* 3)方法名称任意
* 4)方法可以没有参数,如果有可是任意类型
* 5)要使用@RequestMapping注解来声明一个访问的路径(名称)
*
*/
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器被访问到了.......");
return "main"; //可以直接跳到/admin/main.jsp页面上
}
}
9)添加tomcat进行测试功能
web请求执行的流程
核心处理器
index.jsp<--------------->DispatcherServlet<------------------->SpringMVC的处理器是一个普通的方法
one.jsp <--------------->DispatcherServlet<------------------->SpringMVC的处理器是一个普通的方法
DispatcherServlet要在web.xml文件中注册才可用.
此注解就是来映射服务器访问的路径.
1)此注解可加在方法上,是为此方法注册一个可以访问的名称(路径)
@RequestMapping("/demo")
public String demo(){
System.out.println("服务器被访问到了.......");
return "main"; //可以直接跳到/admin/main.jsp页面上
}
<a href="${pageContext.request.contextPath}/demo.action">访问服务器</a>
2)此注解可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称
@RequestMapping("/user")
public class DemoAction1 {..}
<a href="${pageContext.request.contextPath}/user/demo.action">访问服务器</a>
3)此注解可区分get请求和post请求
@Controller
public class ReqAction {
@RequestMapping(value = "/req",method = RequestMethod.GET)
public String req(){
System.out.println("我是处理get请求的........");
return "main";
}
@RequestMapping(value = "/req" ,method = RequestMethod.POST)
public String req1(){
System.out.println("我是处理post请求的........");
return "main";
}
}
页面:
<form action="${pageContext.request.contextPath}/one.action">
姓名:<input name="myname"><br>
年龄:<input name="age"><br>s
<input type="submit" value="提交">
</form>
action:
@RequestMapping("/one")
public String one(String myname,int age){ ===>自动注入,并且类型转换
System.out.println("myname="+myname+",age="+(age+100));
return "main";
}
在提交请求中,保证请求参数的名称与实体类中成员变量的名称一致,则可以自动创建对象,则可以自动提交数据,自动类型转换,自动封装数据到对象中.
实体类:
public class Users {
private String name;
private int age;
}
页面:
<form action="${pageContext.request.contextPath}/two.action" method="post">
姓名:<input name="name"><br>
年龄:<input name="age"><br>
<input type="submit" value="提交">
</form>
action:
@RequestMapping("/two")
public String two(Users u){
System.out.println(u);
return "main";
}
@PathVariable常常用在restful风格的请求中,是用来解析路径中参数名称不一致的问题
仅限于超链接或地址拦提交数据.它是一杠一值,一杠一大括号,使用注解@PathVariable来解析.
<a href="${pageContext.request.contextPath}/three/张三/22.action">动态提交</a>
@RequestMapping("/three/{uname}/{uage}")
public String three(
@PathVariable("uname") ===>用来解析路径中的请求参数
String name,
@PathVariable("uage")
int age){
System.out.println("name="+name+",age="+(age+100));
return "main";
}
@RequestParam是用来解决请求参数名称不一致的问题
<h4>4.参数名称不致解决方案</h4>
<form action="${pageContext.request.contextPath}/four.action" method="post">
姓名:<input name="name"><br>
年龄:<input name="age"><br>
<input type="submit" value="提交">
</form>
action
提交请求参数与action方法的形参的名称不一致,使用注解@RequestParam来解析
/**
* 姓名:
* 年龄:
*/
@RequestMapping("/four")
public String four(
@RequestParam("name") ===>专门用来解决名称不一致的问题
String uname,
@RequestParam("age")
int uage){
System.out.println("uname="+uname+",uage="+(uage+100));
return "main";
}
<h4>5.手工提取数据</h4>
<form action="${pageContext.request.contextPath}/five.action" method="post">
姓名:<input name="name"><br>
年龄:<input name="age"><br>
<input type="submit" value="提交">
</form>
/**
* 姓名:
* 年龄:
*/
@RequestMapping("/five")
public String five(HttpServletRequest request){
String name = request.getParameter("name");
int age = Integer.parseInt(request.getParameter("age"));
System.out.println("name="+name+",age="+(age+100));
return "main";
}
配置过滤器.
<filter>
<filter-name>encodefilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceRequestEncodingparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodefilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
1)String:客户端资源的地址,自动拼接前缀和后缀.还可以屏蔽自动拼接字符串,可以指定返回的路径.
2)Object:返回json格式的对象.自动将对象或集合转为json.使用的jackson工具进行转换,必须要添加jackson依赖.一般用于ajax请求.
3)void:无返回值,一般用于ajax请求.
4)基本数据类型,用于ajax请求.
5)ModelAndView:返回数据和视图对象,现在用的很少.
1)添加jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.8version>
dependency>
2)在webapp目录下新建js目录,添加jQuery函数库
3)在index.jsp页面上导入函数库
function show() {
$.ajax({
url:"${pageContext.request.contextPath}/ajax.action",
dataType:"json",
type:"get",
success:function (list) {
// alert(list);
var s="";
$.each(list,function (i,stu) {
// alert(stu);
s+=stu.name+"----"+stu.age+"
";
});
$("#mydiv").html(s);
}
});
}
4)在action上添加注解@ResponseBody,用来处理ajax请求
@Controller
public class AjaxAction {
//处理ajax请求,一定要加@ResponseBody
@ResponseBody
@RequestMapping("/ajax")
public List<Student> ajax(){
Student stu1 = new Student("张三",22);
Student stu2 = new Student("李四",24);
Student stu3 = new Student("王五",23);
List<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
list.add(stu3);
//调用json转换工具ObjectMapper进行转换
return list; //===>springmvc负责转换成json
}
}
5)在springmvc.xml文件中添加注解驱动mvc:annotationdriven/,它用来解析@ResponseBody注解
<mvc:annotation-driven>mvc:annotation-driven>
本质还是两种跳转:请求转发和重定向,衍生出四种是请求转发页面,转发action,重定向页面,重定向action
@RequestMapping("/one")
public String one(){
System.out.println("这是请求转发页面跳转.........");
return "main"; //默认是请求转发,使用视图解析器拼接前缀后缀进行页面跳转
}
@RequestMapping("/two")
public String two(){
System.out.println("这是请求转发action跳转.........");
// /admin/ /other.action .jsp
//forward: 这组字符串可以屏蔽前缀和后缀的拼接.实现请求转发跳转
return "forward:/other.action"; //默认是请求转发,使用视图解析器拼接前缀后缀进行页面跳转
}
@RequestMapping("/three")
public String three(){
System.out.println("这是重定向页面.......");
//redirect: 这组字符串可以屏蔽前缀和后缀的拼接.实现重定向跳转。所以下面的路径要自己拼全
return "redirect:/admin/main.jsp";
}
@RequestMapping("/four")
public String four(){
System.out.println("这是重定向action.......");
//redirect: 这组字符串可以屏蔽前缀和后缀的拼接.实现重定向跳转
return "redirect:/other.action";
}
@RequestMapping("/five")
public String five(){
System.out.println("这是随便跳.......");
return "forward:/fore/login.jsp";
}
具体参考 https://blog.csdn.net/qq_41717185/article/details/108169853
建议一:
对于竭力避免表单重复提交的场景下选择重定向方式
建议二:
对于效率要求更高的场景选择服务器内请求转发
建议三:
若携带较多参数则选择服务器内请求转发
请求转发偏向于:为同一业务功能服务
重定向偏向于:不同业务功能之间的跳转
不需要去创建,直接拿来使用即可.
1)HttpServletRequest
2)HttpServletResponse
3)HttpSession
4)Model
5)Map
6)ModelMap
注意:Map,Model,ModelMap和request一样,都使用请求作用域进行数据传递.所以服务器端的跳转必须是请求转发.
重定向想要携带数据,可以用HttpSession
//做一个数据,传到main.jsp页面上
Users u = new Users("张三",22);
//各种方式传递数据
request.setAttribute("requestUsers",u);
session.setAttribute("sessionUsers",u);
model.addAttribute("modelUsers",u);
map.put("mapUsers",u);
modelMap.addAttribute("modelMapUsers",u);
requestUsers:${requestUsers}<br>
sessionUsers:${sessionUsers}<br>
modelUsers:${modelUsers}<br>
mapUsers:${mapUsers}<br>
modelMapUsers:${modelMapUsers}<br>
response:${cookie}<br>
从index.jsp页来来的数据${param.name}
@Controller
public class DataAction {
@RequestMapping("/data")
public String data(HttpServletRequest request,
HttpServletResponse response,
HttpSession session,
Model model,
Map map,
ModelMap modelMap){
//做一个数据,传到main.jsp页面上
Users u = new Users("张三",22);
//传递数据
request.setAttribute("requestUsers",u);
session.setAttribute("sessionUsers",u);
model.addAttribute("modelUsers",u);
map.put("mapUsers",u);
modelMap.addAttribute("modelMapUsers",u);
Cookie cookie = new Cookie("cookie","123456");
response.addCookie(cookie);
return "main"; //请求转发方式跳转
// return "redirect:/admin/main.jsp";
//如果是请求重定向的话,那么只剩下session的数据还能带过去,其他方式的数据的都会丢失
}
}
作用域:本页面的、请求的、会话的、全局的
package com.bjpowernode.controller;
import com.bjpowernode.pojo.Student;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
*
*/
@Controller
public class MyDateAction {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
/**
* 日期:
*
*/
// @RequestMapping("/mydate")
// public String mydate(
// @DateTimeFormat(pattern = "yyyy-MM-dd")
// Date mydate){
// System.out.println(mydate);
// System.out.println(sf.format(mydate));
// return "show";
// }
//注册一个全局的日期处理注解
@InitBinder
public void initBinder(WebDataBinder dataBinder){
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sf,true));
}
@RequestMapping("/mydate")
public String mydate(Date mydate, HttpServletRequest request){
System.out.println(mydate);
System.out.println(sf.format(mydate));
request.setAttribute("mydate",sf.format(mydate));
return "show";
}
@RequestMapping("/list")
public String list(HttpServletRequest request) throws ParseException {
Student stu1 = new Student("张三",sf.parse("2000-01-01"));
Student stu2 = new Student("李四",sf.parse("2001-08-11"));
Student stu3 = new Student("王五",sf.parse("2002-09-21"));
List<Student> list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
list.add(stu3);
request.setAttribute("list",list);
return "show";
}
}
要使用注解@DateTimeFormat,此注解必须搭配springmvc.xml文件中的
@RequestMapping("/mydate")
public String mydate(
@DateTimeFormat(pattern = "yyyy-MM-dd") //前端传过来的日期,转为日期格式注入
Date mydate){
System.out.println(mydate);
System.out.println(sf.format(mydate)); //格式日期输出
return "show";
}
全局的则不需要mvc:annotationdriven标签
注册一个注解,用来解析本类中所有的日期类型,自动转换. /*
@InitBinder
public void initBinder(WebDataBinder dataBinder){
/* registerCustomEditor的参数
参数1:转成什么类型
参数2:需要什么工具去做转换
*/
/*
CustomDateEditor的参数
参数1:格式刷工具
参数2:是否允许为空
*/
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
在页面上显示好看的日期,必须使用JSTL.
步骤:
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
如果是单个日期对象,直接转为好看的格式化的字符串进行显示.
如果是list中的实体类对象的成员变量是日期类型,则必须使用jstl进行显示.
<%--导入jstl核心标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--导入jstl格式化标签库--%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<table width="800px" border="1">
<tr>
<th>姓名</th>
<th>生日</th>
</tr>
<c:forEach items="${list}" var="stu">
<tr>
<td>${stu.name}</td>
<td>${stu.birthday}------ <fmt:formatDate value="${stu.birthday}" pattern="yyyy-MM-dd"></fmt:formatDate></td>
</tr>
</c:forEach>
</table>
https://www.zhihu.com/question/362051844/answer/1286615054
此目录下的动态资源,不可直接访问,只能通过请求转发的方式进行访问 .
@Controller
public class WebInfAction {
@RequestMapping("/showIndex")
public String showIndex(){
System.out.println("访问index.jsp");
return "index";
}
@RequestMapping("/showMain")
public String showMain(){
System.out.println("访问main.jsp");
return "main";
}
@RequestMapping("/showLogin")
public String showLogin(){
System.out.println("访问login.jsp");
return "login";
}
//登录的业务判断
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){
if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
return "main";
}else{
request.setAttribute("msg","用户名或密码不正确!");
return "login";
}
}
}
针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理.
1)preHandle():在请求被处理之前进行操作,预处理
2)postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
3)afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理.
1)继承HandlerInterceptorAdapter的父类
2)实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式
1、日志记录:记录请求信息的日志
2、权限检查,如登录检查
3、性能检测:检测方法的执行时间
4、处理cookie、本地化、国际化、主题等。
5、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)
6、登录验证,判断用户是否登录。
注意:拦截器可以配置多个,形成拦截器链,即可以多次拦截
1)改造登录方法,在session中存储用户信息,用于进行权限验证
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){
if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
//在session中存储用户信息,用于进行权限验证
request.getSession().setAttribute("users",name);
return "main";
}else{
request.setAttribute("msg","用户名或密码不正确!");
return "login";
}
}
2)开发拦截器的功能.实现HandlerInterceptor接口,重写preHandle()方法
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//是否登录过的判断
if(request.getSession().getAttribute("users") == null){
//此时就是没有登录,打回到登录页面,并给出提示
request.setAttribute("msg","您还没有登录,请先去登录!");
//最原始的请求转发
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp")
.forward(request,response);
return false;
}
return true;//放行请求
}
}
2)在springmvc.xml文件中注册拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/showLogin">mvc:exclude-mapping>
<mvc:exclude-mapping path="/login">mvc:exclude-mapping>
<bean class="com.bjpowernode.interceptor.LoginInterceptor">bean>
mvc:interceptor>
mvc:interceptors>
过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象
过滤器应用场景
1)过滤敏感词汇(防止sql注入)
2)设置字符编码
3)URL级别的权限访问控制
4)压缩响应信息
0)建库,建表
1)新建Maven项目,选择webapp模板
2)修改目录
3)修改pom.xml文件(使用老师提供)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.bjpowernodegroupId>
<artifactId>springmvc_006_ssmartifactId>
<version>1.0version>
<packaging>warpackaging>
<properties>
<junit.version>4.12junit.version>
<spring.version>5.2.5.RELEASEspring.version>
<mybatis.version>3.5.1mybatis.version>
<mybatis.spring.version>1.3.1mybatis.spring.version>
<mybatis.paginator.version>1.2.15mybatis.paginator.version>
<mysql.version>5.1.32mysql.version>
<slf4j.version>1.6.4slf4j.version>
<druid.version>1.1.12druid.version>
<pagehelper.version>5.1.2pagehelper.version>
<jstl.version>1.2jstl.version>
<servlet-api.version>3.0.1servlet-api.version>
<jsp-api.version>2.0jsp-api.version>
<jackson.version>2.9.6jackson.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>5.2.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>${mybatis.version}version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>${mybatis.spring.version}version>
dependency>
<dependency>
<groupId>com.github.miemiedevgroupId>
<artifactId>mybatis-paginatorartifactId>
<version>${mybatis.paginator.version}version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>${pagehelper.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>${jstl.version}version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>3.0.1version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jsp-apiartifactId>
<scope>providedscope>
<version>${jsp-api.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${jackson.version}version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
project>
4)添加jdbc.properties属性文件
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmuser?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123
5)添加SqlMapConfig.xml文件(使用模板)
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
configuration>
6)添加applicationContext_mapper.xml文件(数据访问层的核心配置文件)
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:jdbc.properties">context:property-placeholder>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}">property>
<property name="url" value="${jdbc.url}">property>
<property name="username" value="${jdbc.username}">property>
<property name="password" value="${jdbc.password}">property>
bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:SqlMapConfig.xml">property>
<property name="typeAliasesPackage" value="com.bjpowernode.pojo">property>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjpowernode.mapper">property>
bean>
beans>
7)添加applicationContext_service.xml文件(业务逻辑层的核心配置文件)
<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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.bjpowernode.service.impl">context:component-scan>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*select*" read-only="true"/>
<tx:method name="*find*" read-only="true"/>
<tx:method name="*serach*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*drop*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="mycut" expression="execution(* com.bjpowernode.service.impl.*.*(..))">aop:pointcut>
<aop:advisor advice-ref="myadvice" pointcut-ref="mycut">aop:advisor>
aop:config>
beans>
8)添加spirngmvc.xml文件
<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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.bjpowernode.controller">context:component-scan>
<mvc:annotation-driven>mvc:annotation-driven>
beans>
9)删除web.xml文件,新建,改名,设置中文编码,并注册spirngmvc框架,并注册Spring框架
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>encodefilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceRequestEncodingparam-name>
<param-value>trueparam-value>
init-param>
<init-param>
<param-name>forceResponseEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodefilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext_*.xmlparam-value>
context-param>
web-app>
10)新建实体类user
11)新建UserMapper.java接口
12)新建UserMapper.xml实现增删查所有功能,没有更新
13)新建service接口和实现类
14)新建测试类,完成所有功能的测试
15)新建控制器,完成所有功能
16)浏览器测试功能
provided 表示该依赖打包的时候不要打包进去
test 表示只在测试中用这个依赖
scope的几个属性详解:
如何显示某一页的数据 (当前页码-1)*每页的条数
总共有多少页:总数据数 %每页条数 ,如果是整除,则总页数 就等于 总数据数 /每页条数;
如果不整除,则总页数等于 总数据数 /每页条数 +1
其次还需要注意的是:页码page的类型尽量用封装类型Integer,而不用int;因为int的默认值是0,而0有可能是我们传过来的页码;如果用Integer判空就可以用是否为null,而不用0来判空
@RequestMapping("/selectUserPage")
public List<User> selectUserPage(String userName,String userSex,Integer page){
//根据页码计算起始行
int startRow = 0;
if(page != null){
startRow = (page-1) * PAGE_SIZE;
}
return userService.selectUserPage(userName,userSex,startRow);
}