SpringMVC学习笔记(1)
SpringMVC学习笔记(1)
一、环境搭建
导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
配置web.xml
<!--注册DispatcherServlet SpringMVC的核心:请求分发器。前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</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>
<!--启动级别。数字越小 启动越早-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--注册characterEncodingFilter 解决中文乱码问题-->
<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>
- 在SpringMVC中
- / 只会匹配所有请求,不会匹配jsp页面。
- /* 匹配所有请求,包括jsp页面。
配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!--自动扫描包,让指定包下的注解生效,交给IOC容器统一管理-->
<context:component-scan base-package="com.hzj.controller"/>
<!--让springMVC不再处理静态资源 .html .css .js .mp3 .mp4-->
<mvc:default-servlet-handler/>
<!--开启注解驱动 相当于添加了处理映射器 和 处理器适配器-->
<mvc:annotation-driven/>
<!--添加视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
出现404的原因:部署的项目中没有lib目录,没有相关jar包。在部署的web项目中的WEB-INF下添加lib目录并添加相关jar包。
二、常用注解
RequestMapping
- RequestMapping注解用于应宿舍url到控制器类或者一个特定的处理程序方法。可以用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
- 只注解在方法上面
@Controller
public class HelloController {
@RequestMapping("/test1")
public String hello(Model model){
model.addAttribute("msg","test1");
return "test";
}
}
访问路径:http://localhost:8080/项目名/test1
- 同时注解类与方法
@Controller
@RequestMapping("/admin")
public class HelloController {
@RequestMapping("/test2")
public String hello(Model model){
model.addAttribute("msg","hello springmvc annotation!");
return "test";
}
}
访问路径:http://localhost:8080/项目名/admin/test1
* 需要先指定类的路径再指定方法的路径
RequestParam
用于表单和后台的名字不一样
作用:把请求中指定的参数给控制器中的形参赋值。
属性:
value:请求参数中的名称
required:请求参数中是否必须提供此参数。默认值:true,代表必须提供,如果不提供将会 报错。
示例:
@RequestMapping("/g1")
public String getParam1(@RequestParam("name")String username, String password) {
System.out.println(username + ":" + password);
return "test";
}
RequestBody
作用:用于获取请求体内容。直接得到的是 key=value&key=value...结构的数据。
get请求方式不适用
属性:
required:是否必须有请求体。默认值是true。
当取值为true时,get请求方式会报错。
如果取值为false,get请求得到的是null。
示例:
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "test";
}
输出结果:
username=admin&password=123456
PathVariable
作用:
用于绑定url中的占位符。例如,请求url中 /delete/{id}
,这个{id}
就是url占位符。
url支持占位符是spring3.0之后加入的。是springmvc支持rest风格url的一个重要标识。
属性:
value:用于指定url中占位符的名称。
required:是否必须提供占位符。
示例:
@GetMapping("/testPathVariable/{name}")
public String testPathVariable(@PathVariable String name){
System.out.println(name);
return "test";
}
RequestHeader
作用:用于获取请求消息头(不常用)
属性:
value:提供消息头名称
required:是否必须有此消息头
示例:
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader("Accept") String header) {
System.out.println(header);
return "test";
}
输出结果:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
CookieValue
作用:用于把指定cookie名称的值传入控制器方法的参数
属性:
value:指定cookie的名称
required:是否必须有此cookie
示例:
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String cookieValue){
System.out.println(cookieValue);
return "test";
}
输出结果
D1EBADDC5CA4C7F20D9064966939081F
ModelAttribute
作用:
该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。
应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:
我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
示例:
表单提交数据:username = 张三 , password = 123456 ,没有提交日期
- 有返回值的写法:
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
System.out.println("testModelAttribute执行了");
System.out.println(user);
return "test";
}
@ModelAttribute
public User showUser(String username){
System.out.println("showUser执行了");
User user = new User();
user.setUsername(username);
user.setPassword("123");
user.setDate(new Date());
return user;
}
输出结果:
howUser执行了
testModelAttribute执行了
User(username=张三, password=123456, date=Wed Apr 14 15:04:00 CST 2021)
- 没有返回值的写法
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("user") User user) {
System.out.println("testModelAttribute执行了");
System.out.println(user);
return "test";
}
@ModelAttribute
public void showUser(String username, Map<String,User> map) {
System.out.println("showUser执行了");
User user = new User();
user.setUsername(username);
user.setPassword("123");
user.setDate(new Date());
map.put("user",user);
}
输出结果一样
RequestAttribute
作用:获取HTTP的请求(request)对象属性值,用来传递给控制器的参数。
属性:用于要获取的属性名称
示例:
@GetMapping("/goto")
public String gotoPage(HttpServletRequest request) {
request.setAttribute("msg", "哈哈");
request.setAttribute("code", 200);
return "forward:/success";
}
@ResponseBody
@RequestMapping("/success")
public Map<String, Object> success(@RequestAttribute("msg") String msg,
@RequestAttribute("code") Integer code) {
Map<String, Object> map = new HashMap<>();
map.put("msg", msg);
map.put("code", code);
return map;
}
浏览器显示:
SessionAttribute
作用: 用于多次执行控制器之间方法间的参数共享
属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型
示例:
@Controller
@RequestMapping("/anno")
@SessionAttributes(value = {"msg"}) //把 msg = 哈哈 存到Session域中
public class AnnotationController {
@RequestMapping("/testSessionAttribute")
public String testSessionAttribute(Model model){
//底层存到Request域对象中
//设置值
model.addAttribute("msg","哈哈");
return "test";
}
@RequestMapping("/getSessionAttribute")
public String getSessionAttribute(Model model){
//获取值
Object msg = model.getAttribute("msg");
System.out.println(msg);
return "test";
}
}
三、Controller及RestFul风格
控制器Controller
-
控制器复杂提供访问应用程序的行为,通常通过接口定义或者注解定义两种方法实现。
-
控制器负责解析用户的氢气并将其转换为一个模型
-
在SpringMVC中,一个控制器类可以包含多个方法
-
在SpringMVC中,对于Controller的配置方式有很多种
实现方式:
实现Controller接口
Controller是一个接口, 在 org.springframework.web.servlet.mvc
包下,接口中只有一个方法
//实现该接口的类获得控制器功能
@FunctionalInterface
public interface Controller {
//处理请求并且返回一个ModelAndView对象
@Nullable
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
- 实现Controller定义控制器是较老的办法
- 缺点:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较打麻烦
使用注解@Controller
@Controller
注解类型是用于声明Spring类的实例是一个控制器。- Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到控制器,需要在配置文件中声明组件扫描。
- 被这个注解的类中的所有的方法,如果返回值是String,并且有具体的页面可以跳转,那么就会被视图解析器解析。
<!--自动扫描包,让指定包下的注解生效,交给IOC容器统一管理-->
<context:component-scan base-package="com.hzj.controller"/>
RESTful风格
概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这种风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
功能
-
资源:互联网所有的事物都可以被抽象为资源
-
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
-
分别对应 添加、删除、修改、查询。
传统方式操作资源:通过不同的参数来实现不同的效果。方法单一,post和get
使用Restful操作资源:可以通过不同的请求方式来实现不同的效果。如下,请求地址一样,但是功能可以不同。
- http://127.0.0.3/item/1 查询,GET
- http://127.0.0.3/item 新增,POST
- http://127.0.0.3/item 更新,PUT
- http://127.0.0.3/item/1 删除,DELETE
测试
- 新建一个RestfulController
@Controller
public class RestfulController {
}
- 使用
@PathVariable
注解,让方法参数的值对应绑定到一个URI模板变量上。
@RequestMapping("/test1/{a}/{b}")
public String test1(@PathVariable int a, @PathVariable int b, Model model) {
int sum = a + b;
model.addAttribute("msg", "结果为:" + sum);
return "hello";
}
使用method属性指定请求类型
所有的地址栏请求默认都会是HTTP GET类型的
需要添加隐藏域 name指定为_method, value改成PUT或者DELETE才能发送PUT或者DELETE请求
<form action="/user" method="post">
<input type="hidden" name="_method" value="put">
<input type="submit" value="put请求"><br>
</form>
<form action="/user" method="post">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="delete请求"><br>
</form>
方法级别的注解体变体有如下几个:
@GetMappin
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping