1.Spring MVC是什么
SpringMVC是一个基于MVC的web框架,是spring框架的一个模块,SpringMVC和spring无需通过中间整合层进行整合。
1.1 web三层架构
web三层架构分别为表现层、业务层、持久层,三层一层调用一层
- 表现层:是用于客户端与服务器端直接交互的,主要获取数据,展示数据等功能
- 业务层:对持久层调用,处理一些复杂的业务逻辑
- 持久层:直接操作数据库
1.2 传统MVC模式
MVC的全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写
1.3 SpringMVC核心架构
具体流程:
(1)首先浏览器发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
(2)DispatcherServlet——>HandlerMapping,处理器映射器将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象;
(3)DispatcherServlet——>HandlerAdapter,处理器适配器将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
(4)HandlerAdapter——>调用处理器相应功能处理方法,并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
(5)ModelAndView对象(Model部分是业务对象返回的模型数据,View部分为逻辑视图名)——> ViewResolver, 视图解析器将把逻辑视图名解析为具体的View;
(6)View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构;
(7)返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
2.SpringMVC入门
web-xml:
<!-- 配置中文乱码问题 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置前端控制器(DispatcherServlet)-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--初始化加载springmvc配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--当服务器第一次启动时,就创建servlet类,然后加载配置文件,然后扫描类中注解-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置前端控制器(DispatcherServlet):加载springmvc配置文件
配置过滤器:解决中文乱码问题(获取请求参数用)
springmvc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.baidu"></context:component-scan>
<!-- 视图解析器对象 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 开启SpringMVC框架注解的支持 -->
<mvc:annotation-driven conversion-service="conversionService"/>
</beans>
视图解析器:视图解析器将把ModelAndView解析为具体的View
属性prefix:指定路径
属性suffix:指定类型
controller:
package com.baidu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 控制器类
*/
@Controller
public class HelloController {
/**
* 入门案例
* @return
*/
@RequestMapping(path="/hello")
public String sayHello(){
System.out.println("Hello StringMVC");
return "success";
}
}
@Controller:负责注册一个bean对象(后端控制器类)到spring容器中
@RequestMapping:为控制器指定可以处理哪些 URL 请求
运行原理:
- 客户端请求提交到DispatcherServlet
- 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
- DispatcherServlet将请求提交到Controller
- Controller调用业务逻辑处理后,返回ModelAndView
- DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
- 视图负责将结果显示到客户端
3.SpringMVC进阶
3.1 获取请求参数
3.1.1 直接获取参数:在方法参数列表设置请求参数对应的参数,即可获取参数
controller:
@Controller
@RequestMapping("/param")
public class ParamController {
@RequestMapping("/testParam") /* 在方法参数列表设置请求参数对应的参数,即可获取参数*/
public String testParam(String username,String password){
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
return "success";
}
注意:这种方法获取参数,方法形参的名必须和表单名一样
也可以用@RequestParam注解修饰形参,这样就可以与表单中的名字不一样,但是有点多此一举(了解即可)
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(name = "username") String name){
System.out.println("执行了testRequestParam...");
System.out.println(name);
return "success";
}
3.1.2 获取参数绑定实体类:将参数换成实体类对象就行,SpringMVC框架会帮我们自动封装到实体类对象中,实体类的属性名和表单中名字也要一样
controller:
@RequestMapping("/saveAccount")
public String saveAccount(Account account){
System.out.println(account);
return "success";
}
3.2 常用注解
3.2.1 @RequestBody 注解:用于获取请求体信息
注意:get请求不适用
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println("执行了testRequestBody...");
System.out.println(body);
return "success";
}
3.2.2 @PathVariable 注解:restful编程风格
绑定 URL 占位符到入参
@RequestMapping("/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println("执行了testPathVariable...");
System.out.println(id);
return "success";
}
3.2.3 ModelAttribute 注解:该注解在方法上,就会优先执行相比该控制器类中的所有方法
@RequestMapping("testModelAttribute")
public String testModelAttribute(@ModelAttribute(value = "user") User user){
System.out.println("执行了testModelAttribute...");
System.out.println(user);
return "success";
}
/* //该方法先执行
@ModelAttribute
public User showUser(String uname){
//通过uname查找数据库(模拟)
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setBirthday(new Date());
return user;
}*/
/*如果注解在一个void方法上,在参数上加个map集合封装对象,然后获取参数再用该注解修饰*/
@ModelAttribute
public void showUser(String uname, Map<String,User> map) {
//通过uname查找数据库(模拟)
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setBirthday(new Date());
map.put("user", user);
}
3.3 响应
前端jsp:点击按钮发送ajax异步请求
<input type="button" id="btn" value="发送ajax请求">
<script>
$(function () {
$("#btn").click(function () {
//alert("发送了ajax请求...")
//发送ajax请求
$.ajax({
url:"user/testAjax",
contentType:"application/json;charset=utf-8",
type:"post",
data:'{"username":"张三","password":"123","age":14}',
dataType:"json",
success:function (data) {
alert(data);
alert("姓名:"+data.username+" 密码:"+data.password+" 年龄:"+data.age);
}
});
});
});
</script>
后端controller:
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println(user.toString());
//模拟查询数据库,响应给前端,
user.setUsername("李四");
user.setPassword("456");
return user;
}
@RequestBody:接收异步请求传入的json数据,MVC框架帮我们自动封装到user对象中
@ResponseBody:将后端的user对象自动转化成json数据传回前端
结果:
后端已接收并封装:
前端也接收了: