1.请求参数的绑定
绑定机制: 表单提交的数据都是k=v格式的 username=jack&password=123
SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的 要求:提交表单的name和参数的名称是相同的
支持的数据类型 基本数据类型和字符串类型 实体类型(JavaBean) 集合数据类型(List、map集合等) 基本数据类型和字符串类型 提交表单的name和参数的名称是相同的,区分大小写
实体类型(JavaBean) 要求提交表单的name和JavaBean中的属性名称需要一致 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性
给集合属性数据封装 list[index].属性名 map['key'].属性名 注意:如果请求参数是中文,可以在web.xml中配置Spring提供的字符集过滤器来解决中文乱码问题
如果对象的属性中有Date类型,页面输入参数格式是 2019/1/1 可以自动参数绑定,如果页面输入参数格式是 2019-1-1 则无法绑定,需要使用自定义类型转换器来解决.
表单提交的任何数据类型全部都是字符串类型,但是后台定义Integer类型,数据也可以封装上,说明Spring框架内部会默认进行数据类型转换。 如果想自定义数据类型转换,可以实现Converter的接口
1.创建日期转换类
//把字符串转换日期
public class StringToDateConverter implements Converter<String,Date>{
public Date convert(String source) {
// 判断
if(source == null){
throw new RuntimeException("请您传入数据");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
// 把字符串转换日期
return df.parse(source);
} catch (Exception e) {
throw new RuntimeException("数据类型转换出现错误");
}
}
}
2.修改springmvc.xml
<!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.qf.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!-- 开启SpringMVC框架注解的支持 -->
<mvc:annotation-driven conversion-service="conversionService"/>
可以看到这种方法很麻烦,另一种方法:只需要在实体类中的Date类型的属性上加:@DateTimeFormat(pattern = "yyyy-MM-dd") 即可
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
2.常用注解
RequestParam注解 作用:把请求中的指定名称的参数传递给控制器中的形参赋值 属性 value:请求参数中的名称 required:请求参数中是否必须提供此参数,默认值是true,必须提供
PathVariable注解 作用:拥有绑定url中的占位符的。url中有/delete/{id},{id}就是占位符 属性 value:指定url中的占位符名称
Jsp如下:
<%--
Created by IntelliJ IDEA.
User: 86156
Date: 2021/10/19
Time: 9:50
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<center>
<a href="user/test1?id=438">点我啊1</a><br><hr>
<a href="user/test2/12138">点我啊2</a><br><hr>
<a href="user/test3">点我啊3 !</a><br><hr>
<a href="user/test4">点我啊4</a><br><hr>
</center>
</body>
</html>
Controller如下:
@org.springframework.stereotype.Controller
@RequestMapping("user")
public class Controller {
@RequestMapping("test1")
//常用注解1 RequestParam 获取url穿的值
public void test1(@RequestParam("id") Integer ids) {
System.out.println(ids);
}
//常用注解2
// Restful风格的URL
//请求路径一样,可以根据不同的请求方式去执行后台的不同方法
//restful风格的URL优点
//结构清晰
//符合标准
//易于理解
//扩展方便
@RequestMapping("test2/{id}")
public void test2(@PathVariable("id") Integer id) {
System.out.println(id);
}
}
Restful风格的URL 请求路径一样,可以根据不同的请求方式去执行后台的不同方法 restful风格的URL优点 结构清晰 符合标准 易于理解 扩展方便
3.不常用注解
RequestHeader注解 作用:获取指定请求头的值 属性 value:请求头的名称
CookieValue注解 作用:用于获取指定cookie的名称的值 属性 value:cookie的名称
JSP页面如上
Controller如下:
//注解3 不常用
@RequestMapping("test3")
public void test3(@RequestHeader("host") String host){
System.out.println(host);
}
//注解4 不常用
@RequestMapping("test4")
public void test4(@CookieValue("JSESSIONID") String jid){
System.out.println(jid);
}
分别点击四个连接 控制台输出的内容
4.响应数据和结果视图
返回值分类
返回字符串:String Controller方法返回字符串可以指定逻辑视图的名称,根据视图解析器为物理视图的地址。 应用时可以设置参数类型为Model,使用Model对象调用addAttribute方法来存储数据。
返回值是void 如果控制器的方法返回值编写成void,执行程序报404的异常,默认查找JSP页面没有找到。 应用时可以设置参数类型为HttpServletRequest和HttpServletResponse,使用转发或者重定向来跳转页面
返回值是ModelAndView对象 ModelAndView对象是Spring提供的一个对象,可以调用addObject方法来保存数据以及调用setViewName方法来跳转页面.
使用forward关键字进行请求转发 return "forward:转发的JSP路径"
使用redirect关键字进行重定向(默认会把项目路径加上) return "redirect:重定向的JSP路径"
4.1首先先建两个jsp页面,再webapp下面建reg.jsp,在web下建student文件夹下面建index.jsp
<%--
Created by IntelliJ IDEA.
User: 86156
Date: 2021/10/18
Time: 16:38
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<center>
<%-- 随随便便写了个表单,向大家演示出来就ok啦--%>
<form method="get" action="student/reg"><br>
姓名: <input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
<%-- 集合的话,直接给下标怼上赋值--%>
车1:<input type="text" name="list[0].cname"><br>
车2:<input type="text" name="map['first'].cname"><br>
生日:<input type="date" name="birthday"><br>
<input type="submit" name="提交" value="提交"><br>
</form>
</center>
</body>
</html>
<html>
<head>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
</head>
<body>
<h2>Hello World!</h2>
${student.name}<br>
${student.password}<br>
${student.list[0].cname}<br>
${student.map['first'].cname}<br>
${student.birthday}<br>
${student}
</body>
</html>
4.2 实体类
4.2.1 Car类
package com.coffee.entity;
import lombok.Data;
@Data
public class Car {
private String cname;
}
4.2.2 Student类(因为浏览器返回的时间格式和咱们后端的不太一样,所以这里需要定义一下,不定义的话会出现400错误哦)
package com.coffee.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
public class Student implements Serializable {
private String name;
private String password;
private List<Car> list;
private Map<String,Car> map;
//有时间的话一定要加这个注解
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}
4.3 Controller控制器
4.3.1 使用model参数相应视图
@org.springframework.stereotype.Controller
@RequestMapping("/student")
public class Controller {
@RequestMapping(value = "/reg", produces = "text/html;charset=UTF-8")
public String reg(Model model,Student student) {
model.addAttribute("student",student);
return "/index.jsp";
}
}
4.3.2 使用ModelAndView返回值类型
@org.springframework.stereotype.Controller
@RequestMapping("/student")
public class Controller {
@RequestMapping(value = "/reg", produces = "text/html;charset=UTF-8")
public ModelAndView reg(Student student) {
ModelAndView modelAndView = new ModelAndView();
// 存入值
modelAndView.addObject("student",student);
// 设置跳转页面
modelAndView.setViewName("/index.jsp");
return modelAndView;
}
}
4.3.3 加入HttpServletRequsert 和 HttpServletResponse 通过他们的对象来进行转发和重定向实现跳转功能
@org.springframework.stereotype.Controller
@RequestMapping("/student")
public class Controller {
@RequestMapping(value = "/reg", produces = "text/html;charset=UTF-8")
public void reg(HttpServletRequest request, HttpServletResponse response,Student student) {
request.setAttribute("student",student);
try {
request.getRequestDispatcher("/index.jsp").forward(request,response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.3.4 使用String
@org.springframework.stereotype.Controller
@RequestMapping("/student")
public class Controller {
@RequestMapping(value = "/reg", produces = "text/html;charset=UTF-8")
public String reg(Student student) {
return "/index.jsp";
}
}
@org.springframework.stereotype.Controller
@RequestMapping("/student")
public class Controller {
@RequestMapping(value = "/reg", produces = "text/html;charset=UTF-8")
public String reg(Student student) {
//转发
return "forward:/index.jsp";
//重定向 因为我这个是传值的所以用重定向不合适
//return "redirect:/index.jsp"
}
}
5.SpringMVC中ajax的使用
@RequestBody和@ResponseBody一般用于ajax中获取请求json类型的数据和返回响应json类型的数据
@RequestBody :用于获取请求体json的数据(注意:GET方式请求不可以) ajax中设置请求参数为json类型:contentType :application/json
@ResponseBody:用于响应json数据 前提是需要提前导入json的jar包依赖
1.DispatcherServlet会拦截到所有的资源的问题
导致静态资源(img、css、js)也会被拦截到,从而 不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置:
<!--前端控制器,哪些静态资源不拦截(springmvc.xml中)-->
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<!-- 设置html静态页面不拦截(web.xml中) -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- 设置所有静态资源不被拦截(springmvc.xml中),等同于上面的两个配置-->
<mvc:default-servlet-handler/>
2.在pom.xml中导入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
3.编写html/jsp页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<form>
ID:<input type="text" name="id" id="id"><br>
姓名:<input type="text" name="name" id="name"><br>
年龄:<input type="text" name="age" id="age"><br>
<input type="button" onclick="login()" value="提交"><br>
</form>
</center>
</body>
<!--导入jQuery库-->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.5.1.min.js"></script>
<script type="application/javascript">
function login() {
var $id = $("#id").val();
var $name = $("#name").val();
var $age = $("#age").val();
//测试能否能获取到输入框的数据
alert($id+"***"+$name+"***"+$age);
var student = $("form").serialize();
$.ajax({
type: "POST",
url: "student/login",
data: student,
success: function(backData){
//当成功返回数据的时候, 在弹框输出
alert(backData.id+"姓名:"+backData.name+"年龄:"+backData.age);
}
});
// 这是get和post方法
// $.get("student/login",student,
// function (backData) {
// alert("我是我");
// alert(backData.id+"姓名:"+backData.name+"年龄:"+backData.age);
// })
// $.post("student/login",student,
// function (backData) {
// alert("我是我");
// alert(backData.id+"姓名:"+backData.name+"年龄:"+backData.age);
// })
}
</script>
</html>
4.在Controller中添加方法
package com.coffee.controller;
import com.coffee.entity.Student;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//注意注解
@RestController
@RequestMapping("student")
public class Control {
@RequestMapping("login")
// 传入对象参数,mvc会将前端获取的数据自动封装
public Student myTest(Student student){
System.out.println(student);
Student student1 = new Student();
student1.setId(student.getId());
student1.setName(student.getName());
student1.setAge(student.getAge());
//控制台打印出 表示后端已经收到前端传送的数据了
System.out.println(student1);
return student1;
}
}
结果如下
控制台可以输出
最后前端界面第二次弹框
6.Json介绍
常用的Json框架:Jackson FastJson Gson
JavaBean序列化转换为Json格式,性能:Jackson > FastJson > Gson > Json-lib
Jackson常用注解
@JsonIgnore : 指定属性不返回
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh",timezone = "GMT+8") : 格式指定日期属性
@JsonProperty("别名") : 给属性指定别名
package com.coffee.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Data
public class Student implements Serializable {
@JsonIgnore//隐藏此属性
@JsonProperty("姓名")//起别名
private String name;
@JsonProperty("密码")
private String password;
@JsonProperty("车1")
private List<Car> list;
@JsonProperty("车2")
private Map<String,Car> map;
//Json日期格式
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;
}