SpringMVC中的控制器

1、对请求提交方式的定义

@RequestMapping 请求映射
属性:
value,表示所匹配请求的URI
method,表示请求的方式:
get请求: RequestMethod.GET
post请求: RequestMethod.POST

推荐使用Resful风格的GetMapping("/xxx")PostMapping("xxx")

1
2
@RequestMapping(value="/doSome",method= RequestMethod.GET)
public ModelAndView doSome(){}

2、处理器的请求参数

处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序员可在方法内直接使用。
➢ HttpServletRequest
➢ HttpServletResponse
➢ HttpSession
➢ 请求中所携带的请求参数

1、逐个参数接收

保证请求参数名与该请求处理方法的参数名相同。

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 保证请求参数名与该请求处理方法的参数名相同。
* 框架接收请求参数
* 1、使用request对象接收请求参数
* 2、springmvc框架通过DispatcherServlet 调用myController中的doSome()
* 并按名称对应,把接收到的参数赋值给形参,框架会提供类型自动转换功能
* @param name
* @param age
* @return
*/
@RequestMapping(value = "/other.do",method = RequestMethod.POST)
public ModelAndView doOther(String name,Integer age){}

400错误码:客户端错误,表示提交请求时出现了错误

2、解决中文乱码

提交请求参数时,get方式没有乱码,post方式出现中文乱码。
使用框架提供的过滤器解决乱码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- 注册过滤器,解决post请求的乱码问题-->
<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>
<!-- 强制请求对象(HttpServletRequest)使用encoding编码值-->
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<!-- 强制响应对象(HttpServletResponse)使用encoding编码值-->
<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>

3、@RequestParam校正请求参数

若请求URL 所携带的参数名称与处理方法中指定的参数名不相同时,则需在处理方法参数前,添加一个注解@RequestParam(“请求参数名”),指定请求URL 所携带参数的名称。

4、对象参数接收

将处理器方法的参数定义为一个对象,只要保证请求参数名与这个对象的属性同名即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Student {
private String name;
private Integer age;

public Student() {
}

public Student(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;
}
}
1
2
3
4
5
6
7
8
9
@RequestMapping(value = "/other.do",method = RequestMethod.POST)
public ModelAndView doOther(Student student){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("student",student);
// 指定视图 框架对视图执行forward操作
modelAndView.setViewName("show");
// 返回modelAndView
return modelAndView;
}
1
2
3
4
5
6
7
8
9
10
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>show.jsp</title>
</head>
<body>
<p>name:${student.name}</p>
<p>age:${student.age}</p>
</body>
</html>

3、处理器方法的返回值

1、返回ModelAndView

处理器方法处理完后,需要跳转到其他资源,并且要在跳转的资源之间传递数据。

2、返回String

视图跳转,不传递数据。

1
2
3
4
5
6
7
8
9
@Controller
public class MyController {
@RequestMapping(value = "/returnView.do")
public String doRetyrnView(String name,Integer age) {
// show 逻辑视图名称。项目中配置了视图解析器
// 框架对视图进行forward转发操作
return "show";
}
}

3、返回void

不能表示数据,也不能表示视图。
在处理ajax的时候,可以使用void返回值。通过HttpServletResponse输出数据,响应ajax请求。
ajax请求服务端返回的就是数据,与视图无关。

step1:服务端向浏览器传回的是JSON 数据,需要使用一个工具类将字符串包装为JSON 格式,所以需要导入JSON 的依赖。

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>

step2:引入jquery

step3:发起ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index.jsp</title>
<script type="text/javascript" src="js/jquery-3.4.1.js"></script>
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
// alert("button click")
$.ajax({
url:"returnVoid-ajax.do",
data:{
name:"zyz",
age:21
},
type:"post",
dataType:"json",
// resp是服务器端返回的json格式的字符串
// jquery会把json字符串转化为json对象,赋值给形参
success:function(resp){
alert("name:"+resp.name+" age:"+resp.age);
}
})
})
})
</script>
</head>
<body>
<button id="btn">发起ajax请求</button>
</body>

step4:响应ajax请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RequestMapping(value = "/returnVoid-ajax.do")
public void doReturnVoidAjax(HttpServletResponse resp, String name, Integer age) throws Exception {
System.out.println("name:" + name);
System.out.println("age:" + age);
// 处理ajax请求 使用json数据格式
Student student = new Student(name, age);
// 将数据转换为json格式
String studentJson="";
if (student != null) {
ObjectMapper objectMapper = new ObjectMapper();
studentJson= objectMapper.writeValueAsString(student);
System.out.println("student的json格式:"+studentJson);
}
// resp输出数据到页面,响应ajax请求
resp.setContentType("application/json;charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.print(studentJson);
writer.flush();
writer.close();
}

4、返回Object

处理器返回的对象不是作为逻辑视图出现的,而是作为直接在页面显示的数据出现。
可以使用对象表示数据,响应ajax请求。
将对象类型转换为json类型 以及 将结果数据输出到页面,springmvc框架都可以自动帮你完成:

step1:
在pom.xml中引入Jackson相关依赖,Jackson工具库用于将Object转换为Json。

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>

step2:

在springmvc.xml配置文件中添加注解驱动。
将Object 数据转化为JSON 数据,需要由消息转换器HttpMessageConverter 完成。而转换器的开启,需要由<mvc:annotation-driven/>来完成。
SpringMVC 使用消息转换器实现请求数据和对象,处理器方法返回对象和响应输出之间的自动转换

当Spring 容器进行初始化过程中,在<mvc:annotation-driven/>处创建注解驱动时,默认创建了八个HttpMessageConverter 对象。也就是说,我们注册<mvc:annotation-driven/>,就是为了让容器为我们创建HttpMessageConverter 对象。

1
2
<!--注解驱动-->
<mvc:annotation-driven/>

step3:

修改处理器方法:

1
2
3
4
5
6
7
8
9
10
/**
* 使用框架来处理ajax请求
* @return Student
*/
@RequestMapping(value = "/returnStudent.do")
@ResponseBody // 处理器返回对象转换为json后,通过HttpServletResponse输出给浏览器
public Student doReturnStudentAjax(){
Student student = new Student("zyz", 19);
return student;// 框架会将obj转为json格式
}

从页面发起ajax请求:

1
2
3
4
5
6
7
8
9
10
11
12
$("#btn02").click(function(){
$.ajax({
url:"returnStudent.do",
type:"post",
dataType:"json",
// resp是服务器端返回的json格式的字符串
// jquery会把json字符串转化为json对象,赋值给形参
success:function(resp){
alert("name:"+resp.name+" age:"+resp.age);
}
})
})

处理流程:

1、框架会把处理器返回的Student类型的数据,调用框架中的ArrayList<HttpMessageConverter>中每个类的canWrite()方法,检查哪个HttpMessageConverter接口的类能处理Student类型的数据—-MappingJackson2HttpMessageConverter
2、调用实现类中的Write()方法,将student对象转换为json字符串
3、调用@ResponseBody把转换好的json数据输出到浏览器,ajax处理完成

返回List集合:

1
2
3
4
5
6
7
8
9
10
11
12
@RequestMapping(value = "/returnStudents.do")
@ResponseBody
public List<Student> doReturnStudentAjax() {
List<Student> students = new ArrayList<>();
Student student1 = new Student("张伟1", 19);
Student student2 = new Student("张伟2", 20);
Student student3 = new Student("张伟3", 21);
students.add(student1);
students.add(student2);
students.add(student3);
return students;
}
1
2
3
4
5
6
7
8
9
10
11
12
$("#btn03").click(function(){
$.ajax({
url:"returnStudents.do",
type:"post",
dataType:"json",
success:function(resp){
$.each(resp,function(i,stu) {
alert(stu.name+" "+stu.age);
})
}
})
});

返回String

String表示数据,不是视图。

1
2
3
4
5
@RequestMapping(value="/returnString.do", produces="text/plain;charset=utf-8")
@ResponseBody
public String doReturnStringAjax(){
return "返回的字符串~";
}
1
2
3
4
5
6
7
8
9
$("#btn04").click(function () {
$.ajax({
url:"returnString.do",
type:"post",
success:function (resp) {
alert(resp);
}
})
});

4、解读url-pattern标签

1
2
3
4
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

意思是将所有以.do结尾的请求交给中央调度器(框架)处理。
但是,当提交一些静态资源,例如图片,html页面,js文件的请求时,服务器也会响应。
因为tomcat本身就能处理一些未映射的静态资源的访问。

将所有请求都交给框架处理:

1
2
3
4
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

处理方式一:转发给服务器处理

1
2
3
<!-- 处理静态资源
框架会创建控制器对象DefaultServletHttpRequestHandler把接收到的请求转发给tomcat来处理静态资源-->
<mvc:default-servlet-handler />

处理方式二:框架自己处理

将静态资源集中存放到一个文件夹中

1
2
3
4
5
<!--  处理静态资源方式二
创建 ResourceHttpServletHandler处理器对象 让这个对象去处理静态资源的请求 不依赖于tomcat
mapping:访问静态资源的uri 使用通配符 **
location:静态资源在项目中的位置-->
<mvc:resources mapping="/static/**" location="/static/"/>

5、绝对地址和相对地址

绝对地址
带有协议的地址,在互联网上唯一的

相对地址
没有协议开头的,不能独立使用,需要一个参考地址。通过参考地址+相对地址本身才能指定资源。

在jsp,html 中使用的地址,都是前端页面中的地址,都是相对地址。

在页面中访问地址不加 ” / “ ,访问的是当前页面地址加上链接地址。使用base标签固定参考地址