目录
什么是SpringMVC
什么是MVC?
SpringMVC框架的优点
SpringMVC执行的流程
基于注解的springmvc框架开发步骤
五种数据提交方式的优化
完成ajax请求访问服务器,返回学生集合.
SpringMVC默认的参数类型
日期处理
SpringMVC的拦截器
拦截器执行的时机
拦截器实现的两种方式
拦截器实现的步骤
SSM整合的步骤
它是基于MVC开发模式的框架,用来优化控制器.它是Spring家族的一员.它也具备IOC和AOP.
它是一种开发模式,它是模型视图控制器的简称.所有的web应用都是基于MVC开发.
M:模型层,包含实体类,业务逻辑层,数据访问层
V:视图层,html,javaScript,vue等都是视图层,用来显现数据
C:控制器,它是用来接收客户端的请求,并返回响应到客户端的组件,Servlet就是组件
1)轻量级,基于MVC的框架
2)易于上手,容易理解,功能强大
3)它具备IOC和AOP
4)完全基于注解开发
DispatcherServlet是中心,HandlerMapping、HandlerAdapter、ViewResolver是他的三个好帮手。
1)新建项目,maven模版选择webapp,补全目录(添加缺失的test,java,resources(两套),并修改目录属性)。
2):在pom.xml文件中添加依赖,添加SpringMVC的依赖,添加Servlet的依赖。
(有一个注意点:javax的Servlet依赖只支持tomcat9及以下。 tomcat应开使用jakat版本的Servlet)
org.springframework
spring-webmvc
5.2.5.RELEASE
javax.servlet
javax.servlet-api
3.1.0
3):添加springmvc.xml配置文件,指定包扫描和添加视图解析器
4)如果你的web.xml文件版本低于4.0则删除web.xml文件,新建4.0版本的web.xml,然后编写这个文件,它主要负责中文解析器的配置(格式固定可以直接拿走使用)和Springmvc框架的注册
encode
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceRequestEncoding
true
forceResponseEncoding
true
encode
/*
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
*.action
5)在webapp目录下创建admin(刚刚前缀的名字)目录,在他目录下创建main.jsp(他作为程序要跳转的界面里面的内容可以随便编写)
6):删除webapp目录下自带的index.jsp文件,在新建一个index.jsp文件,没什么原因,自带的丑,新建后按照自己的需求写前端界面。比如
单个数据提交
7):开发普通类Servlet,就是controller目录下的类(接收请求响应的)
* 以前的Servlet的规范
* protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} 需要通过request,response来完成响应和接收需求。下面是springmvc中的使用。
@Controller //交给Spring去创建对象
public class DemoAction {
/**
* action中所有的功能实现都是由方法来完成的
* action方法的规范
* 1)访问权限是public
* 2)方法的返回值任意
* 3)方法名称任意
* 4)方法可以没有参数,如果有可是任意类型
* 5)要使用@RequestMapping注解来声明一个访问的路径(名称)
*
*/
@RequestMapping("/demo")
public String demo(){
System.out.println("demo服务器被访问到了.......");
return "main"; //可以直接跳到/admin/main.jsp页面上
}
}
里面用到的注解
@Controller:spring里面的用来创建对象
@RequestMapping:springmvc里面的,用来映射服务器访问的路径.
- 此注解可加在方法上,是为此方法注册一个可以访问的名称(localhost:8080/demo)
RequestMapping("/demo")
public String demo(){
System.out.println("服务器被访问到了.......");
return "main"; //可以直接跳到/admin/main.jsp页面上
}
访问服务器
- 此注解可以加在类上,相当于是包名(虚拟路径),区分不同类中相同的action的名称(localhost:8080:/user/demo)
@RequestMapping("/user")
public class DemoAction1 {..}
访问服务器
- 此注解可区分get请求和post请求
@Controller
public class ReqAction {
@RequestMapping(value = "/req",method = RequestMethod.GET)
public String req(){
System.out.println("我是处理get请求的........");
return "main";
}
使用@Controller 注解的处理器的方法,其返回值常用的有四种类型:
1)单个提交数据
action:
@RequestMapping("/one")
public String one(String myname,int age){ ===>自动注入,并且类型转换
System.out.println("myname="+myname+",age="+(age+100));
return "main";
}
2)对象封装提交数据
在提交请求中,保证请求参数的名称与实体类中成员变量的名称一致,则可以自动创建对象,则可以自动提交数据,自动类型转换,自动封装数据到对象中.
实体类:
public class Users {
private String name;
private int age;}
页面:
action:
@RequestMapping("/two")
public String two(Users u){
System.out.println(u);
return "main";
}
3)动态占位符提交
仅限于超链接或地址拦提交数据.它是一杠一值,一杠一大括号,使用注解@PathVariable来解析.
动态提交
@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";
}vv
4)映射名称不一致
提交请求参数与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";
}
5)手工提取数据
/**
* 姓名:
* 年龄:
*/
@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";
}
创建项目添加依赖:
创建配置文件springmvc.xml(主要是包扫描、添加ajax的注解驱动)
配置pom.xml文件(负责配置中文解析器和注册springmvc以及springmvc配置文件的注册)
和上面一样
创建实体类
public class Student {
private String name;
private int age;
引入js库,创建前端index.jsp
最后创建controller的类,负责请求的处理和响应
@Controller
public class AjaxAction {
//处理ajax请求,一定要加@ResponseBody
@ResponseBody
@RequestMapping("/ajax")
public List ajax(){
Student stu1 = new Student("张三",22);
Student stu2 = new Student("李四",24);
Student stu3 = new Student("王五",23);
List list = new ArrayList<>();
list.add(stu1);
list.add(stu2);
list.add(stu3);
//调用json转换工具ObjectMapper进行转换
return list; //===>springmvc负责转换成json
}
不需要去创建,直接拿来使用即可.
1)HttpServletRequest
2)HttpServletResponse
3)HttpSession
4)Model
5)Map
6)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);
main界面拿数据
requestUsers:${requestUsers}
sessionUsers:${sessionUsers}
modelUsers:${modelUsers}
mapUsers:${mapUsers}
modelMapUsers:${modelMapUsers}
从index.jsp页来来的数据${param.name}
1)日期的提交处理
A.单个日期处理
要使用注解@DateTimeFormat,此注解必须搭配springmvc.xml文件中的
B.类中全局日期处理
注册一个注解,用来解析本类中所有的日期类型,自动转换.
@InitBinder
public void initBinder(WebDataBinder dataBinder){
dataBinder.registerCustomEditor(Date.class,new CustomDateEditor(sf,true));
}
日期的显示处理
在页面上显示好看的日期,必须使用JSTL.
步骤
1):添加依赖jstl
2):在页面上导入标签库
如果是单个日期对象,直接转为好看的格式化的字符串进行显示.
如果是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" %>
3)使用标签显示数据
姓名 | 生日 |
---|---|
${stu.name} | ${stu.birthday}------ |
@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";
}
注意:资源在WEB-INF目录下 此目录下的动态资源,不可直接访问,只能通过请求转发的方式进行访问 .
针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理.
1)preHandle():在请求被处理之前进行操作,预处理
2)postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
3)afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理.
1)继承HandlerInterceptorAdapter的父类
2)实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式
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()方法
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文件中注册拦截器
1)建库建表
2)建项目选webapp模版,建好目录
3):修改pom.xml文件,引入下列依赖
4.0.0
com.bjpowernode
springmvc_006_ssm
1.0
war
4.12
5.2.5.RELEASE
3.5.1
1.3.1
1.2.15
5.1.7
1.6.4
1.1.12
5.1.2
1.2
3.0.1
2.0
2.9.6
org.springframework
spring-context
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-jms
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
5.2.5.RELEASE
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
com.github.miemiedev
mybatis-paginator
${mybatis.paginator.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
mysql
mysql-connector-java
5.1.32
com.alibaba
druid
${druid.version}
junit
junit
${junit.version}
test
jstl
jstl
${jstl.version}
javax.servlet
javax.servlet-api
3.0.1
provided
javax.servlet
jsp-api
provided
${jsp-api.version}
com.fasterxml.jackson.core
jackson-databind
${jackson.version}
org.apache.maven.plugins
maven-compiler-plugin
1.8
UTF-8
src/main/java
**/*.properties
**/*.xml
false
src/main/resources
**/*.properties
**/*.xml
false
3)添加jdbc.properties属性文件
4)添加SqlMapConfig.xml文件这里只需要日志配置
5):添加applicationContext_mapper.xml文件(数据访问层的核心配置文件)
主要负责读取配置文件、配置数据源连接数据库、配置SqlSessionFactoryBean、注册mapper.xml文件
添加applicationContext_service.xml文件(业务逻辑层的核心配置文件)
主要进行 对service的实现类进行包扫描、配置数据源、配置事务切面、配置切入点并绑定。
添加spirngmvc.xml文件,主要负责controller包扫描和注解驱动
删除web.xml文件,新建,改名,设置中文编码,并注册spirngmvc框架,并注册Spring框架
encode
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceRequestEncoding
true
forceResponseEncoding
true
encode
/*
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
/
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext_*.xml
新建实体类user
新建UserMapper.java接口
public interface UserMapper {
List selectUserPage(
@Param("userName")
String userName,
@Param("userSex")
String userSex,
@Param("startRow") //算好的起始行的值
int startRow);
int createUser(User user);
int deleteUserById(String userId);
int getRowCount(
@Param("userName")
String userName,
@Param("userSex")
String userSex);
}
新建UserMapper.xml实现增删查所有功能
user_id,card_type,card_no,user_name,user_sex,user_age,user_role
insert into user values(#{userId},#{cardType},#{cardNo},#{userName},#{userSex},#{userAge},#{userRole})
delete from user where user_id = #{userId}
新建service接口和实现类
public interface UserService {
/**
* url /user/selectUserPage?userName=z&userSex=男&page=null
*/
List selectUserPage(String userName,String userSex,int startRow);
/**
* /user/createUser(参数见下面)
*/
int createUser(User user);
/**
* user/ deleteUserById?userId= 15968162087363060
*/
int deleteUserById(String userId);
/**
* /user/getRowCount?userName=z&userSex=男
*/
int getRowCount(String userName,String userSex);
@Service
public class UserServiceImpl implements UserService {
//切记切记:一定会有数据访问层的对象
@Autowired
UserMapper userMapper;
@Override
public List selectUserPage(String userName, String userSex, int startRow) {
return userMapper.selectUserPage(userName,userSex,startRow);
}
@Override
public int createUser(User user) {
return userMapper.createUser(user);
}
@Override
public int deleteUserById(String userId) {
return userMapper.deleteUserById(userId);
}
@Override
public int getRowCount(String userName, String userSex) {
return userMapper.getRowCount(userName,userSex);
}
新建测试类,完成所有功能的测试
//@RunWith 就是一个运行器,@RunWith(SpringJUnit4ClassRunner.class),让测试运行于Spring测试环境, @ContextConfiguration这个注解通常与@RunWith(SpringJUnit4ClassRunner.class)联合使用用来测试
@RunWith(SpringJUnit4ClassRunner.class) //启动spring容器,
@ContextConfiguration(locations = {"classpath:applicationContext_mapper.xml","classpath:applicationContext_service.xml"})
public class MyTest {
@Autowired
UserService userService;
@Test
public void testSelectUserPage(){
List list = userService.selectUserPage("三","男",0);
list.forEach(user -> System.out.println(user));
}
@Test
public void testDeleteUserById(){
int num = userService.deleteUserById("15968162087363060");
System.out.println(num);
}
@Test
public void testGetRowCount(){
int num = userService.getRowCount(null,"男");
System.out.println(num);
}
@Test
public void testCreateUser(){
User u = new User("125412145214547846","身份证","121451245784","哈哈","男","23","工人");
int num = userService.createUser(u);
System.out.println("-----"+num);
}
新建控制器,完成所有功能
@CrossOrigin //在服务器端支持跨域访问
@RestController //如果本类中全部都是ajax请求,则使用此注解,方法上的@ResponseBody可不写
@RequestMapping("/user")
public class UserController {
//切记切记:一定会有业务逻辑层的对象
@Autowired
UserService userService;
public static final int PAGE_SIZE = 5;
//user/selectUserPage?userName=z&userSex=男&page=null
@RequestMapping("/selectUserPage")
public List selectUserPage(String userName,String userSex,Integer page){
//根据页码计算起始行
int startRow = 0;
if(page != null){
startRow = (page-1) * PAGE_SIZE;
}
return userService.selectUserPage(userName,userSex,startRow);
}
///user/getRowCount?userName=z&userSex=男
@RequestMapping("/getRowCount")
public int getRowCount(String userName,String userSex){
return userService.getRowCount(userName,userSex);
}
///user/deleteUserById?userId= 15968162087363060
@RequestMapping("/deleteUserById")
public int deleteUserById(String userId){
return userService.deleteUserById(userId);
}
///user/createUser(参数见下面)
@RequestMapping("/createUser")
public int createUser(User user){
String userId = System.currentTimeMillis()+"";
user.setUserId(userId);
return userService.createUser(user);
}
}