Java学习笔记-Day71 SpringMVC 框架(三)
一、SpringMVC的部分注解
1、请求映射注解
Spring4.3+中引进了 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping,来帮助简化常用的HTTP方法的映射,并更好地表达被注解方法的语义。
请求映射注解 | 说明 |
---|---|
@RequestMapping | 通用的请求处理 |
@GetMapping | 处理 HTTP GET 请求 |
@PostMapping | 处理 HTTP POST 请求 |
@PutMapping | 处理 HTTP PUT 请求 |
@DeleteMapping | 处理 HTTP DELETE 请求 |
@PatchMapping | 处理 HTTP PATCH 请求 |
@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。@GetMapping在Spring4.0后出现。
可以在@GetMapping注解中写多个地址。
@GetMapping(value= {
"t1","t2","t3"})
public String sayHi() {
return "hello";
}
@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。
2、@RequestParam
@RequestParam:用于将请求参数区数据映射到功能处理方法的参数上。
@RequestMapping(value = "query.do")
public String queryByName(@RequestParam(value="name",required=true,defaultValue="") String name) {
System.out.println("name :" + name);
return "query";
}
value:参数名字,即入参的请求参数名字,如name表示请求的参数区中的名字为name的参数的值将传入。
required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报400错误码。如果设置了required=true,同时提供defaultValue的话,此时不传递参数,方法也能正常执行,这时参数的值就是默认值。如果设置了required=true,但是没有defaultValue的话,此时如果没有传递参数过来 ,方法不能正常执行,必须要传递参数name才可以。
defaultValue:默认值,表示如果请求中没有同名参数时的默认值,默认值可以是SpEL表达式。

3、@PathVariable
@PathVariable:用于将请求URL中的模板变量映射到功能处理方法的参数上。
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@GetMapping(value="api/user/{userid}")
public User queryUser(@PathVariable(name="userid") int userid) {
User user = new User(userid,"小口袋",20,30);
return user;
}
}
4、@RequestMapping
@RequestMapping注解在类前或者方法前。@RequestMapping没有指明请求方法,默认post和get都能访问。@RequestMapping在Spring4.3后出现。
若指定consumes为application/json,则服务器仅处理Content-Type为application/json类型的请求。
@RestController // ajax请求
public class UsersController {
@RequestMapping(value = "/user", method = RequestMethod.POST, consumes="application/json")
public void addUser(@RequestBody Users users) {
System.out.println(users);
}
}
若指定produces为application/json,则会响应类型为application/json的数据。
@RestController // ajax请求
public class UsersController {
@RequestMapping(value = "/user", method = RequestMethod.GET, produces="application/json")
public User getUser() {
User user = new User(1,"tom");
return user;
}
}
5、@RequestHeader
@RequestHeader用于将请求的头信息区数据映射到功能处理方法的参数上。通过Request Headers中的键获取对应的值。
通过在网页上按F12键 -> Application -> Storage -> Cookies,可以查看当前网页的Cookie。
@Controller
public class HeaderTestController {
@GetMapping("ctc3")
public String ctc3(@RequestHeader(value="Accept") String accpet) {
System.out.println("accpet="+accpet);
return "ctc3";
}
}
6、@CookieValue
@CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上。可以使用@CookieValue将本地存储的cookie读取到控制器的方法中,其参数类型可以是String,也可以是一个cookie对象。
通过在网页上按F12键 -> Application -> Storage -> Cookies,可以查看当前网页的Cookie。
@Controller
public class CookieTestController {
@GetMapping("ctc1")
public String ctc1(@CookieValue(value="JSESSIONID") String JSESSIONID) {
System.out.println("ctc1 JSESSIONID="+JSESSIONID);
return "ctc1";
}
@GetMapping("ctc2")
public String ctc2(@CookieValue(value="JSESSIONID") Cookie JSESSIONID) {
System.out.println("ctc2 JSESSIONID="+JSESSIONID);
return "ctc2";
}
}
Eclipse控制台输出的结果:
二、中文乱码处理
(1)RestController中的请求,且返回的数据类型为字符串,当响应的字符串有中文时,中文会变成乱码,需要使用produces。
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // ajax请求
public class QuestionController {
@GetMapping(value="hello",produces="application/json;charset=utf-8")
public String sayHello(String name) {
return "Hello"+name;
}
}
在浏览器地址栏输入: http://localhost:8080/项目名/hello?name=小明
(2)表单提交的过程中,post请求会出现中文乱码,需要在web.xml中配置Spring的编码过滤器CharacterEncodngFilter。
<!-- spring提供的characterEncodingFilter配置 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 给 CharacterEncodingFilter类的对象进行初始化的赋值 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 响应编码的设置true -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<!-- 过滤器对哪些资源进行过滤 -->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
三、RestFul风格
前提:网络应用程序,分为前端和后端两个部分,前端设备层出不穷(PC,Phone,Pad等等),必须有一种统一的机制,方便不同的前端设备与后端进行通信。这导致API构架的流行, Restful API是目前比较成熟的一套互联网应用程序的API设计理论。例如:IOS开发终端和服务器交互目前都是通过restful API的形式。IOS终端列出需要的API接口,服务端实现这些接口,中间通过http(https)协议通信来交互。
rest(Representational State Transfer)是表示性状态转换,它可以用来设计web services的框架,可以被不同的客户端调用。其核心思想是:使用HTTP(HTTPS)协议来实现调用,而不是CORBA、RPC 或者 SOAP等负责的机制。
在Restful设计中,可以做好如下约定:
创建资源 | 使用 HTTP POST |
---|---|
获取资源 | 使用 HTTP GET |
更新资源 | 使用 HTTP PUT |
删除资源 | 使用 HTTP DELETE |
依据上述原则,定义 REST API 接口 :
请求方式 | 请求路径 | 功能 |
---|---|---|
GET | /api/emp | 返回员工列表。 |
GET | /api/emp/1 | 返回员工编号为1的员工对象。 |
POST | /api/emp | 增加一个员工,参数为Emp对象JSON格式。 |
PUT | /api/emp/1 | 更新员工,参数empno为1,json格式的员工。 |
DELETE | /api/emp/1 | 删除编号为1的员工对象。 |
DELETE | /api/emp/ | 删除所有员工。 |
案例:UserController.java
package com.etc.ws.controller;
import java.util.Arrays;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@GetMapping(value="api/user/{userid}")
public User queryUser(@PathVariable(name="userid") int userid) {
User user = new User(userid,"小口袋",20,30);
return user;
}
@GetMapping(value="api/user")
public List<User> queryUsers() {
User user1 = new User(12,"小",20,30);
User user2 = new User(13,"口",10,20);
User user3 = new User(14,"袋",20,30);
return Arrays.asList(user1,user2,user3);
}
@RequestMapping(method = RequestMethod.GET,value="api/user1")
public List<User> getUsers() {
User user1 = new User(12,"大",20,30);
User user2 = new User(13,"白",10,20);
User user3 = new User(14,"菜",20,30);
return Arrays.asList(user1,user2,user3);
}
@GetMapping(value="api/user/{userid}/{username}")
public User queryUser(@PathVariable(name="userid") int userid,@PathVariable(name="username") String username) {
User user = new User(userid,username,20,30);
return user;
}
@PostMapping(value="apis/user1")
public User addUser(User user) {
System.out.println("user="+user);
return user;
}
@PostMapping(value="apis/user2")
public User addUsers(@RequestBody User user) {
System.out.println("user="+user);
return user;
}
}
四、控制器的测试
控制器写完后要做好测试。
1、测试工具PostMan
(1)通过参数params进行测试。
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@PostMapping(value="apis/user1")
public User addUser(User user) {
System.out.println("user="+user);
return user;
}
}
(2)通过请求体的x-www-form-urlencoded进行测试。urlencoded方法相当于原始表单的post提交。
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@PostMapping(value="apis/user1")
public User addUser(User user) {
System.out.println("user="+user);
return user;
}
}
(3)通过请求体的raw进行测试,选择 json(application/json),传递数据为json格式的字符串。控制器中的@RequestBody注解主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据);
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@PostMapping(value="apis/user2")
public User addUsers(@RequestBody User user) {
System.out.println("user="+user);
return user;
}
}
2、JSP页面测试
(1)表单的post提交。
restform.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post" action="apis/user1">
<input type="text" id="userid" name="userid" value="12"/><br/>
<input type="text" id="username" name="username" value="baidu"/><br/>
<input type="text" id="create_website_num" name="create_website_num" value="2"/><br/>
<input type="text" id="website_access_num" name="website_access_num" value="102"/><br/>
<input type="submit"/>
</form>
</body>
</html>
- UserController.java
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@PostMapping(value="apis/user1")
public User addUser(User user) {
System.out.println("user="+user);
return user;
}
}
(2)表单通过ajax的提交json格式的数据。
- restajaxform.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form>
<input type="text" id="userid" name="userid" value="12"/><br/>
<input type="text" id="username" name="username" value="baidu"/><br/>
<input type="text" id="create_website_num" name="create_website_num" value="2"/><br/>
<input type="text" id="website_access_num" name="website_access_num" value="102"/><br/>
<input type="button" id="btn" value="提交"/>
</form>
<script src="js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$("#btn").click(function(){
$.ajax({
url:'apis/user2',
type:'post',
contentType:'application/json',
data:JSON.stringify({
'userid':$('#userid').val(),
'username':$('#username').val(),
'create_website_num':$('#create_website_num').val(),
'website_access_num':$('#website_access_num').val()
}),
success:function(res){
console.log(res);
}
});
});
});
</script>
</body>
</html>
- UserController.java
package com.etc.ws.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.etc.ws.entity.User;
@RestController
public class UserController {
@PostMapping(value="apis/user2")
public User addUsers(@RequestBody User user) {
System.out.println("user="+user);
return user;
}
}