[华为云在线课程][SpringMVC入门][四][处理器详解][学习笔记]
1.@RequestMapping注解使用细节
这个注解标记一个接口,是接口开发中使用最多的注解之一。
1.1.请求URL
标记请求URL只需要在相应方法上添加该注解就可以了
package org.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MyController3 {
@RequestMapping("/hello3")
public ModelAndView hello() {
return new ModelAndView("hello3");
}
}
这里@RequestMapping("/hello3")表示当请求地址为/hello3时,这个方法被触发。其中,地址可以是多个,就是可以多个地址映射到同一个方法。
package org.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MyController3 {
@RequestMapping("/hello3")
public ModelAndView hello3() {
return new ModelAndView("hello3");
}
@RequestMapping({"/hello2","/hello"})
public ModelAndView hello2() {
return new ModelAndView("hello");
}
}
这个配置表示请求地址为/hello2和/hello都可以访问到这个方法。
1.2.请求窄化
同一个项目中会存在多个接口,例如订单相关的接口都是/order/xxx格式,用户相关的接口都是/user/xxx格式。为了方便处理,这里的前缀可以统一在Controller上处理。
package org.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/hello")
public class MyController4 {
@RequestMapping("/hello3")
public ModelAndView hello3() {
return new ModelAndView("hello3");
}
}
在类上加了@RequestMapping注解之后,此时,要想访问到hello,地址就应该是/hello/hello3。
1.3.请求方法限定
默认情况下,使用@RequestMapping注解定义好的方法,可以被GET请求访问到,也可以被POST请求访问到,但是DELETE和PUT请求不能访问到。
我们也可以指定具体的访问方法:
package org.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class MyController3 {
@RequestMapping(value = "/hello3",method = RequestMethod.GET)
public ModelAndView hello3() {
return new ModelAndView("hello3");
}
@RequestMapping(value = {"/hello2","/hello"},method = RequestMethod.POST)
public ModelAndView hello2() {
return new ModelAndView("hello");
}
}
通过@RequestMapping注解,指定了/hello3接口只能被GET请求访问到,/hello2和/hello只能被POST请求访问到,强行访问就会报错:
hello3进行GET请求
hello3进行POST请求
hello进行GET请求
hello进行POST请求
限定的方法也可以有多个:
@RequestMapping(value = {"/hello2","/hello"},method = {RequestMethod.GET,RequestMethod.POST,
RequestMethod.DELETE,RequestMethod.PUT})
public ModelAndView hello2() {
return new ModelAndView("hello");
}
经过这个配置后,接口就可以被GET,POST,PUT,DELETE访问到了。但是,由于JSP只支持GET,POST以及HEAD,所以这个测试,不能使用JSP做页面模板。可以将视图换成其他的,或者返回JSON。
2.Controller中接口方法各种返回值类型
2.1.返回ModelAndView
如果是前后端不分离的开发,大部分情况下,返回ModelAndView,即数据加视图:
@Controller
public class MyController3 {
@RequestMapping(value = "/hello3",method = RequestMethod.GET)
public ModelAndView hello3() {
ModelAndView modelAndView = new ModelAndView("hello3");
modelAndView.addObject("username", "helloolleh");
return modelAndView;
}
}
在Model中放入我们的数据,然后在ModelAndView中指定视图名称
2.2.返回Void
没有返回值,并不一定真的没有返回值,只是方法的返回值为void,我们可以通过其他方式给前端返回。实际上,这种方式也可以理解为Servlet中的那一套。
需要注意的是,由于默认Maven项目中没有Servlet,需要额外添加一个依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
通过HttpServletRequest做服务端跳转
@RequestMapping("/hello")
public void hello(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//服务器端跳转
request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request,response);
}
通过HttpServletResponse做重定向
@RequestMapping("/hello2")
public void hello2(HttpServletRequest request,HttpServletResponse response)
throws IOException{
response.sendRedirect("/WEB-INF/hello.jsp");
}
也可以自己手动指定响应头实现重定向:
@RequestMapping("/hello3")
public void hello3(HttpServletRequest request,HttpServletResponse response)
throws IOException{
response.setStatus(200);
response.addHeader("Location", "/WEB-INF/hello.jsp");
}
通过HttpServletResponse做出响应
@RequestMapping("/hello4")
public void hello4(HttpServletRequest request,HttpServletResponse response)
throws IOException{
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("hello requestmapping hello4");
writer.flush();
writer.close();
}
这种方式既可以返回JSON,又可以返回普通字符串。
2.3.返回字符串
- 返回逻辑视图名
前面的ModelAndView可以拆分为两部分,Model和View,在SpringMVC中,Model我们可以直接在参数中指定,然后返回值是逻辑视图名:
@RequestMapping("/hello5")
public String hello5(Model model) {
//这是数据模型
model.addAttribute("name", "hello hello5");
//去查找一个名为hello的视图
return "hello";
}
- 服务端跳转
@RequestMapping("/hello5")
public String hello5() {
return "forward:/WEB-INF/jsp/hello.jsp";
}
forward后面跟上跳转的路径
- 客户端跳转
@RequestMapping("/hello5")
public String hello5() {
return "redirect:/hello2";
}
将会跳转到localhost:8080/hello2。本质上就是浏览器重定向。
- 真的返回一个字符串
上面三个返回的字符串,都有有特殊含义的,如果一定要返回一个字符串,需要额外添加一个注意:@ResponseBody,这个注解表示当前方法的返回值就是要展示出来返回值,没有特殊含义。
@RequestMapping("/hello5")
@ResponseBody
public String hello5() {
return "redirect:/hello2";
}
页面直接返回了redirect:/hello2。这里如果想单纯返回一个中文字符串,要在@RequestMapping中添加produces属性来解决乱码问题:
@RequestMapping(value = "/hello5",produces = "text/html;charset=utf-8")
@ResponseBody
public String hello5() {
return "Java程序设计指南";
}
3.参数绑定
3.1.默认支持的参数类型
默认支持的参数类型,就是可以直接写在@RequestMapping所注解的方法中的参数类型,一共有四类:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model/ModelMap
在请求的方法中,默认参数就是这几个,如果在方法中刚好需要这几个参数,那么可以把这几个参数加入到方法中。
3.2.简单数据类型
Integer,Boolean,Double等这些简单数据类型也支持。例如添加一本书:
首先,在/WEB-INF/jsp/目录下创建addbook.jsp,作为图书添加页面:
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 6:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图书添加页面</title>
</head>
<body>
<form action="/doAdd" method="post">
<table>
<tr>
<td>书名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>作者:</td>
<td><input type="text" name="author"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="number" name="price"></td>
</tr>
<tr>
<td>是否上架:</td>
<td>
<input type="radio" value="true" name="ispublic">是
<input type="radio" value="false" name="ispublic">否
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="添加">
</td>
</tr>
</table>
</form>
</body>
</html>
然后创建控制器,控制器提供两个功能,访问jsp页面和提供添加接口:
package org.example.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BookController {
@RequestMapping("/book")
public String addBook() {
return "addbook";
}
@RequestMapping(value = "/doAdd", method = RequestMethod.POST)
@ResponseBody
public void doAdd(String name, String author, Double price, Boolean ispublic) {
System.out.println(name);
System.out.println(author);
System.out.println(price);
System.out.println(ispublic);
}
}
注意,由于doAdd方法确定不想返回任何值,所以需要给该方法添加@ResponseBody注解,表示方法不去查找相关视图。另外,POST请求上传的中文会有乱码问题,所以需要在web.xml中再额外添加一个编码过滤器:
<!--编码过滤器,解决中文乱码问题-->
<filter>
<filter-name>encoding</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最后,浏览器输入http://localhost:8080/book,就可以执行添加操作,服务端会打印出来相应的日志。
在上面的绑定中,有个要求,表单中字段的name属性要和接口中的变量名一一对应才能映射成功,否则服务端无法接收前端传来的数据。有些特殊情况,服务端的接口变量名可能和前端不一致,这时可以通过@RequestParam注解来解决。这个注解的功能有三个方面:
- 给变量取别名
- 设置变量是否必填
- 给变量设置默认值
@RequestMapping(value = "/doAdd", method = RequestMethod.POST)
@ResponseBody
public void doAdd(@RequestParam("name") String bookname, String author, Double price, Boolean ispublic) {
System.out.println(bookname);
System.out.println(author);
System.out.println(price);
System.out.println(ispublic);
}
注解中的"name"表示给bookname这个变量取得别名,也就是说bookname将接收前端传来的name这个变量的值。在这个注解中,还可以添加required属性和defaultValue属性
@RequestMapping(value = "/doAdd", method = RequestMethod.POST)
@ResponseBody
public void doAdd(@RequestParam(value = "name", required = true, defaultValue = "你好啊世界") String bookname,
String author, Double price, Boolean ispublic) {
System.out.println(bookname);
System.out.println(author);
System.out.println(price);
System.out.println(ispublic);
}
required属性默认为true,只要添加了@RequestParam注解,这个参数默认必填,不填会报400错误,如果这个参数不是必填,可以手动将required设置false。但是,如果同时设置defaultValue,这时候前端不传该参数到后端,即使required属性为true,也不会报错。
3.3.实体类
参数也可以是实体类。实际开发中,大部分情况下都是实体类。改用一个Book对象来接收前端传来的数据:
package org.example.model;
public class Book {
private String name;
private String author;
private Double price;
private Boolean ispublic;
public Book() {
}
public Book(String name, String author, Double price, Boolean ispublic) {
this.name = name;
this.author = author;
this.price = price;
this.ispublic = ispublic;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Boolean getIspublic() {
return ispublic;
}
public void setIspublic(Boolean ispublic) {
this.ispublic = ispublic;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
", ispublic=" + ispublic +
'}';
}
}
服务端接收数据方式如下:
@RequestMapping(value = "/doAdd", method = RequestMethod.POST)
@ResponseBody
public void doAdd(Book book) {
System.out.println(book);//Book{name='Java指南', author='某人', price=100.0, ispublic=true}
}
前端页面传值和上面的写法是一样的,直接写上属性名就行了,不需要写book对象名。
如果碰到对象里面还有对象的情况,比如Book对象中还有一个Author对象:
package org.example.model;
public class Book {
private String name;
private Double price;
private Boolean ispublic;
private Author author;
public Book() {
}
public Book(String name, Double price, Boolean ispublic, Author author) {
this.name = name;
this.price = price;
this.ispublic = ispublic;
this.author = author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Boolean getIspublic() {
return ispublic;
}
public void setIspublic(Boolean ispublic) {
this.ispublic = ispublic;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", ispublic=" + ispublic +
", author=" + author +
'}';
}
}
package org.example.model;
public class Author {
private String name;
private Integer age;
public Author() {
}
public Author(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Author{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
前端要更改写法:
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 6:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图书添加页面</title>
</head>
<body>
<form action="/doAdd" method="post">
<table>
<tr>
<td>书名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>作者名字:</td>
<td><input type="text" name="author.name"></td>
</tr>
<tr>
<td>作者年龄:</td>
<td><input type="number" name="author.age"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="number" name="price"></td>
</tr>
<tr>
<td>是否上架:</td>
<td>
<input type="radio" value="true" name="ispublic">是
<input type="radio" value="false" name="ispublic">否
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="添加">
</td>
</tr>
</table>
</form>
</body>
</html>
这样后端直接用Book对象就能接收到所有数据。
@RequestMapping(value = "/doAdd", method = RequestMethod.POST)
@ResponseBody
public void doAdd(Book book) {
System.out.println(book);//Book{name='Java指南', price=200.0, ispublic=true, author=Author{name='某人', age=100}}
}
3.4.自定义参数绑定
前面这些转换都是系统自动进行的,仅限于基本数据类型。特殊的数据类型系统无法自动转换,例如日期。前端传一个日期到后端,后端不是用字符串接收,而是使用一个Date对象接收,这时就会出现参数类型转换失败。这时需要我们手动定义参数类型转换器,将日期字符串手动转为Date对象。
package org.example.controller.utils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class DateConverter implements Converter<String, Date> {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date convert(String source) {
try {
return simpleDateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
在自定义的参数类型转换器中,将一个String转为Date对象,同时,将这个转换器注册为Bean。
在SpringMVC配置文件中,配置Bean使其生效
<mvc:annotation-driven conversion-service="conversionService"/>
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"
id="conversionService">
<property name="converters">
<set>
<ref bean="dateConverter"/>
</set>
</property>
</bean>
package org.example.model;
import java.util.Date;
public class Book {
private String name;
private Double price;
private Author author;
private Date publishDate;
public Book() {
}
public Book(String name, Double price, Author author, Date publishDate) {
this.name = name;
this.price = price;
this.author = author;
this.publishDate = publishDate;
}
public Date getPublishDate() {
return publishDate;
}
public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", author=" + author +
", publishDate=" + publishDate +
'}';
}
}
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 6:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图书添加页面</title>
</head>
<body>
<form action="/doAdd" method="post">
<table>
<tr>
<td>书名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>作者名字:</td>
<td><input type="text" name="author.name"></td>
</tr>
<tr>
<td>作者年龄:</td>
<td><input type="number" name="author.age"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="number" name="price"></td>
</tr>
<tr>
<td>出版时间:</td>
<td><input type="date" name="publishDate"></td>
</tr>
<tr>
<td><input type="submit" value="添加"></td>
</tr>
<%--<tr>
<td>是否上架:</td>
<td>
<input type="radio" value="true" name="ispublic">是
<input type="radio" value="false" name="ispublic">否
</td>
</tr>--%>
<%--<tr>
<td colspan="2">
<input type="submit" value="添加">
</td>
</tr>--%>
</table>
</form>
</body>
</html>
@RequestMapping(value = "/doAdd", method = RequestMethod.POST,produces = "text/html;charset=utf-8")
@ResponseBody
public String doAdd(Book book) {
return book.toString();//Book{name='Java指南', price=200.0, author=Author{name='某人', age=100}, publishDate=Sun Jul 17 00:00:00 CST 2022}
}
配置完成后,在服务端可以接收前端传来的日期参数。
3.5.集合类的参数
- String数组
String数组可以直接用数组去接收,前端传递的时候,数组的传递其实就是多个相同的key,一般用在checkbox。比如在前端页面增加爱好:
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 6:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>图书添加页面</title>
</head>
<body>
<form action="/doAdd" method="post">
<table>
<tr>
<td>书名:</td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>作者名字:</td>
<td><input type="text" name="author.name"></td>
</tr>
<tr>
<td>作者年龄:</td>
<td><input type="number" name="author.age"></td>
</tr>
<tr>
<td>价格:</td>
<td><input type="number" name="price"></td>
</tr>
<tr>
<td>出版时间:</td>
<td><input type="date" name="publishDate"></td>
</tr>
<tr>
<td>是否上架:</td>
<td>
<input type="radio" value="true" name="ispublic">是
<input type="radio" value="false" name="ispublic">否
</td>
</tr>
<tr>
<td>爱好:</td>
<td>
<input type="checkbox" name="favorites" value="吃饭">吃饭
<input type="checkbox" name="favorites" value="睡觉">睡觉
<input type="checkbox" name="favorites" value="看电视">看电视
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="添加">
</td>
</tr>
</table>
</form>
</body>
</html>
package org.example.model;
import java.util.Arrays;
import java.util.Date;
public class Book {
private String name;
private Double price;
private Author author;
private Date publishDate;
private String[] favorites;
public Book() {
}
public Book(String name, Double price, Author author, Date publishDate, String[] favorites) {
this.name = name;
this.price = price;
this.author = author;
this.publishDate = publishDate;
this.favorites = favorites;
}
public Date getPublishDate() {
return publishDate;
}
public void setPublishDate(Date publishDate) {
this.publishDate = publishDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
public String[] getFavorites() {
return favorites;
}
public void setFavorites(String[] favorites) {
this.favorites = favorites;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
", author=" + author +
", publishDate=" + publishDate +
", favorites=" + Arrays.toString(favorites) +
'}';
}
}
在服务端用一个数组去接收favorites对象:
@RequestMapping(value = "/doAdd", method = RequestMethod.POST, produces = "text/html;charset=utf-8")
@ResponseBody
public void doAdd(Book book, String[] favorites) {
System.out.println(Arrays.toString(favorites));
System.out.println(book);
/*
* [吃饭, 睡觉]
Book{name='Java指南', price=200.0, author=Author{name='某人', age=100}, publishDate=Sun Jul 17 00:00:00 CST 2022, favorites=[吃饭, 睡觉]}
* */
}
注意,前端传来的数组对象,服务端不可以使用List集合去接收。
- List集合
如果需要使用List集合接收前端传来的数据,List集合本身需要放在一个封装对象中,这时List中可以是基本数据类型,也可以是对象。例如一个班级类,班级有多个学生:
package org.example.model;
import java.util.List;
public class MyClassroom {
private Integer id;
private List<Student> students;
public MyClassroom() {
}
public MyClassroom(Integer id, List<Student> students) {
this.id = id;
this.students = students;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "MyClassroom{" +
"id=" + id +
", students=" + students +
'}';
}
}
package org.example.model;
public class Student {
private Integer id;
private String name;
public Student() {
}
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
添加班级的时候可以传递多个Student,前端页面如下:
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 19:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加班级学生</title>
</head>
<body>
<form action="/addClass" method="post">
<table>
<tr>
<td>班级号:</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>学生号:</td>
<td><input type="text" name="students[0].id"></td>
</tr>
<tr>
<td>学生名:</td>
<td><input type="text" name="students[0].name"></td>
</tr>
<tr>
<td>学生号:</td>
<td><input type="text" name="students[1].id"></td>
</tr>
<tr>
<td>学生名:</td>
<td><input type="text" name="students[1].name"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
服务端直接接收数据即可:
package org.example.controller;
import org.example.model.MyClassroom;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ClassController {
@RequestMapping("/class")
public String addClass() {
return "addClass";
}
@RequestMapping("/addClass")
@ResponseBody
public void addClass(MyClassroom myClassroom) {
System.out.println(myClassroom);//MyClassroom{id=1, students=[Student{id=1, name='hello'}, Student{id=2, name='world'}]}
}
}
- Map
相对于实体类而言,Map是一种比较灵活的方案,但Map的维护性比较差,一般不推荐使用。
例如给班级类添加其他属性信息:
package org.example.model;
import java.util.List;
import java.util.Map;
public class MyClassroomMap {
private Integer id;
private List<Student> students;
private Map<String,Object> info;
public MyClassroomMap() {
}
public MyClassroomMap(Integer id, List<Student> students, Map<String, Object> info) {
this.id = id;
this.students = students;
this.info = info;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public Map<String, Object> getInfo() {
return info;
}
public void setInfo(Map<String, Object> info) {
this.info = info;
}
@Override
public String toString() {
return "MyClassroomMap{" +
"id=" + id +
", students=" + students +
", info=" + info +
'}';
}
}
在前端,通过以下方式给这个Map赋值。
<%--
Created by IntelliJ IDEA.
User: John
Date: 2022/7/17/0017
Time: 19:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加班级学生Map</title>
</head>
<body>
<form action="/addClassMap" method="post">
<table>
<tr>
<td>班级号:</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td>班级名称:</td>
<td><input type="text" name="info['name']"></td>
</tr>
<tr>
<td>班级位置:</td>
<td><input type="text" name="info['pos']"></td>
</tr>
<tr>
<td>学生号:</td>
<td><input type="text" name="students[0].id"></td>
</tr>
<tr>
<td>学生名:</td>
<td><input type="text" name="students[0].name"></td>
</tr>
<tr>
<td>学生号:</td>
<td><input type="text" name="students[1].id"></td>
</tr>
<tr>
<td>学生名:</td>
<td><input type="text" name="students[1].name"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
</body>
</html>
服务端代码:
package org.example.controller;
import org.example.model.MyClassroom;
import org.example.model.MyClassroomMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ClassControllerMap {
@RequestMapping("/classmap")
public String addClass() {
return "addClassMap";
}
@RequestMapping("/addClassMap")
@ResponseBody
public void addClass(MyClassroomMap myClassroom) {
System.out.println(myClassroom);//MyClassroomMap{id=1, students=[Student{id=1, name='hello'}, Student{id=2, name='你好啊'}], info={name=班级名称1, pos=班级位置1}}
}
}
- 点赞
- 收藏
- 关注作者
评论(0)