1. 基本概念
1.1 什么是SpringMVC
所谓MVC,就是模型(Model),视图(View),控制器(Controller)。是一种软件设计规范。通过业务逻辑、数据、显示的方式来组织代码。
- 模型(Model)
- 视图(View)
- 控制器(Controller)
1.2 MVC的执行流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89cKevik-1628728815225)(C:\Users\CoolGuy\AppData\Roaming\Typora\typora-user-images\image-20210729083944088.png)]
1.3 HelloWorld
创建流程
1.创建Maven工程,并引入依赖
2.配置web.xml
前两步可以通过idea直接创建MVC项目以省略;
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<!--需要修改下路径-->
<url-pattern>/</url-pattern>
</servlet-mapping>
3.配置servlet
xmlns:context="http://www.springframework.org/schema/context"
<context:component-scan base-package="com.gao.controller" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<!-- 这个配置是配置JSP页面的位置,按照你自己的配置来配 -->
<value>/WEB-INF</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
4.创建请求控制器
4.创建请求控制器
@Controller
@RequestMapping("/hi")
public class TestController {
@RequestMapping("/say")
public String say(Model model) {
model.addAttribute("msg","hello world");
return "/jsp/say";
}
}
=====================
请求url是 localhost:8080/hi/say;返回的是 ~~~/jsp/say.jsp;
2.注解
2.1 @RequestMapping
1.RequestMapping的作用是将请求和处理请求的控制器方法关联起来,建立映射关系;
2.RequestMapping的位置有两个,分别用来标识一个类和一个方法
类未标识时,默认是 "/"
3. @RequestMapping(value = {"/say_out","/say"}, method = RequestMethod.GET)
value属性的作用是映射地址(~~感觉多次一举~~)
method指定处理请求的控制器方法------默认Get方法
4.param属性
5.headers属性
2.2 路径中的占位符
/**
* 可以提取说明要传递的参数格式;
* 一旦说明,就一定要存在,否则会无法访问。
*/
@RequestMapping("/say/{id}/{username}")
public String say(Model model,@PathVariable("id") String id,@PathVariable("username") String username) {
model.addAttribute("msg","hello world");
System.out.println("id :"+id+"\nusername: "+username);
return "/jsp/say";
}
3. MVC获取请求参数
3.1 通过Servlet-API获取
浏览器请求:
http://localhost:8080/say?username=%27admin%27&password=2468
控制器获取:
String username = httpServletRequest.getParameter("username");
String password = httpServletRequest.getParameter("password");
@RequestMapping("judge")
public String Judge(HttpServletRequest request){
String username = request.getParameter("username");
System.out.println("hello world");
return "test2";
}
===========
不需要在路径中书写占位符也能获取。
3.2 通过POJO获取
POJO是指普通旧式java对象,即在控制器中以一个实体类作为形参,当浏览器传输的请求参数名和实体类中的属性名一致时,会自动为属性赋值。
@RequestMapping("/say4")
public String say(User user) {
System.out.println(user.toString());
return "/jsp/say4";
}
<form th:action="/testpojo" method="post">
<%-- 我使用的是JSP页面,所以路径不是@{/testpojo}--%>
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="男">男<input type="radio" name="sex" value="女">女<br>
年龄:<input type="text" name="age"><br>
邮箱:<input type="text" name="email"><br>
<input type="submit">
</form>
3.3通过其他方法获取
1.通过控制器参数获取请求参数
@RequestMapping("/testParam")
public String testParam(String username, String password){
System.out.println("username:"+username+",password:"+password);
return "success";
}
2.@RequestParam
~~~~
3.@RequestHeader
~~~~
4.@CookieValue
3.3 MVC过滤器解决乱码问题
SpringMVC提供的编码过滤器CharacterEncodingFilter可以解决编码问题,使用前需要在web.xml中注册。
<!--配置springMVC的编码过滤器-->
<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>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.域对象共享数据
共享数据,即是controller控制器向前端响应数据。
@RequestMapping("hello")
public String hello(HttpSession session){
session.setAttribute("test1","我在Any页面中都能获取");
return "test";
}
===========
需要注意的是,创建的对象应该在形参中
4.1 PageContext对象
作用域范围:当前jsp页面内有效
4.2 request对象
作用域范围:一次请求内。
作用: 解决了一次请求内的资源的数据共享问题
4.3 session对象
作用域范围:一次会话内有效。
说明:浏览器不关闭,并且后台的session不失效,在任意请求中都可以获取到同一个session对象。
作用:解决了一个用户不同请求的数据共享问题。
4.4 application(ServletContext)对象
作用域范围:整个项目内有效。
特点:一个项目只有一个,在服务器启动的时候即完成初始化创建,无论如何获取都是同一个项目。
作用:解决了不同用户的数据共享问题。
5.Controller控制器的返回值
在web项目中,controller的返回值一般有两种:
- 返回对应的页面(例如html页面,jsp页面)
- 返回数据(例如json格式的数据)
5.1 使用@Controller注解,返回对应的页面
@Controller
public class UserController {
@Resource
private IUserService userService;
@RequestMapping("/userLogin")
public String userLogin(@Param("userName") String userName){
return "success";//返回对应的名为success的页面
}
}
5.2 在方法上加上@ResponseBody注解,数据直接响应到浏览器。
要想返回json,还需要进行配置;配置过程在下面7.4小节。
@RequestMapping("/getDepts")
@ResponseBody
public List<Department> getDepts(){ //查找所有部门
List<Department> depts=userService.findAllDepts();
return depts;
}
6.数据共享方法
6.1 使用ServletAPI向request域对象共享数据
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){
request.setAttribute("testScope", "hello,servletAPI");
return "success";
}
6.2 使用ModelAndView向request域对象共享数据
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
/**
* ModelAndView有Model和View的功能
* Model主要用于向请求域共享数据
* View主要用于设置视图,实现页面跳转
*/
ModelAndView mav = new ModelAndView();
//向请求域共享数据
mav.addObject("testScope", "hello,ModelAndView");
//设置视图,实现页面跳转
mav.setViewName("success");
return mav;
}
6.3 使用Model向request域对象共享数据
@RequestMapping("/testModel")
public String testModel(Model model){
model.addAttribute("testScope", "hello,Model");
return "success";
}
6.4 使用map向request域对象共享数据
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map){
map.put("testScope", "hello,Map");
return "success";
}
6.5 使用ModelMap向request域对象共享数据
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap){
modelMap.addAttribute("testScope", "hello,ModelMap");
return "success";
}
6.6 Model、ModelMap、Map的关系
Model、ModelMap、Map类型的参数其实本质上都是 BindingAwareModelMap 类型的
public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}
6.7 向session域共享数据
@RequestMapping("/testSession")
public String testSession(HttpSession session){
session.setAttribute("testSessionScope", "hello,session");
return "success";
}
6.8 向application域共享数据
@RequestMapping("/testApplication")
public String testApplication(HttpSession session){
ServletContext application = session.getServletContext();
application.setAttribute("testApplicationScope", "hello,application");
return "success";
}
7.RESTful
7.1
Representational State Transfer,表现层资源状态转移。
- 资源是由URI来指定。
- 只是一种设计风格。
- 对资源的操作包括获取、创建、修改和删除,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
- 通过操作资源的表现形式来操作资源。
- 资源的表现形式则是XML或者HTML,取决于读者是机器还是人、是消费Web服务的客户软件还是Web浏览器。当然也可以是任何其他的格式,例如JSON。
6.2查询操作
6.3删除操作
本来是需要使用.METHED方法的,但浏览器一直报405(方法始终为GET),所以尝试了下把控制器的方法改为默认情况,没想到成功了。
@RequestMapping(value = "/user/{id}")
public String delete(@PathVariable("id") Integer id){
userDao.delete(id);
return "redirect:/hello";
}
一团乱码
7.HttpMessageConverter
报文信息转换器,将请求报文转换为Java对象,或将Java对象转换为响应报文。
7.1@RequestBody
RequestBody可以获得请求体,即请求的参数;
@RequestMapping("/testRB")
public String TestRB(@RequestBody String string){
System.out.println("RequestBody: "+string);
return "test";
}
- 这个控制器不能直接访问,必须浏览器提交带有参数的请求
7.2RequestEntity<>
把当前请求的报文复制给该形参;
@RequestMapping("/testRE")
public String TestRE(RequestEntity<String> requestEntity){
System.out.println("RequestHeader: "+requestEntity.getHeaders());
//获取请求头信息
System.out.println("RequestBody: "+requestEntity.getBody());
//获取请求体信息
return "test";
}
- 请求体可以无参数,默认为null;
7.3ResponseBody
将该方法的返回值直接作为响应报文的响应体响应到浏览器。
@RequestMapping("/testRS")
@ResponseBody ///注意声明
public String TestRSE(){
return "HELLO WORLD";
}
7.4SpringMVC处理Json
现在的Spring版本不再需要配置了,只需要添加ResponseBody,即能把数据默认处理成Json。
@ResponseBody处理json的步骤:
a>导入jackson的依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3<version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3<version>
</dependency>
b>在dispatcherServlet-servlet.xml中开启注解驱动
<mvc:annotation-driven />
c>在处理器方法上使用@ResponseBody注解进行标识
d>将Java对象直接作为控制器方法的返回值返回,就会自动转换为Json格式的字符串
@RequestMapping("hello2")
@ResponseBody
public Map<String,Object> Return(){
Map<String,Object> map=new HashMap<>();
List<Integer> list=new ArrayList<>();
list.add(666);list.add(888);
map.put("10001",2100);
map.put("10002","小王");
map.put("10003",list);
return map;
}
浏览器的页面中展示的结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cTdDftvw-1628728815229)(file:///C:\Users\CoolGuy\AppData\Roaming\Tencent\Users\2152843846\QQ\WinTemp\RichOle\69FET1FZ3DCOM[@`7~AYZ7D.png)]
7.5处理ajax
-
前端页面
<script type="text/javascript"> $('t1').click(function(){ $.get($(this).attr('href'),function(data){ alert(data); }); }); </script> ==== js中添加事件
<a href="/crud/hello2" id="t1">点我</a> ====== 超链接
- 控制器Controller
@RequestMapping("hello2") @ResponseBody public Map<String,Object> Return(){ Map<String,Object> map=new HashMap<>(); List<Integer> list=new ArrayList<>(); list.add(666);list.add(888); map.put("10001",2100); map.put("10002","小王"); map.put("10003",list); return map; }
- 浏览器返回
7.6@RestController注解
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解
7.7 ResponseEntity
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文
urn(){
Map<String,Object> map=new HashMap<>();
List list=new ArrayList<>();
list.add(666);list.add(888);
map.put(“10001”,2100);
map.put(“10002”,“小王”);
map.put(“10003”,list);
return map;
}
3. 浏览器返回
### 7.6@RestController注解
@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解
### 7.7 ResponseEntity
ResponseEntity用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览器的响应报文
##