1.控制类注解
加在控制类上得注解
|
(1)控制器标志
@Controller
(2)类的url前缀,所有方法上都要加上这个,前面必须有
/
@RequestMapping(
"/demo"
)
(3)表示类的所有的方法都是返回json,不加就看方法上加没有加
@ResponseBody
(4)RestController=Controller+
ResponseBody,表示此类的所有方法都是json的返回方法
@RestController
|
示例1 |
@Controller
@RequestMapping
(
"/demo"
)
public class
DemoController {
@ResponseBody
@RequestMapping
(
"/index"
)
public
String main(){
return
"dddd"
;
}
}
|
示例2
|
@Controller
@ResponseBody
@RequestMapping
(
"/demo"
)
public class
DemoController {
}
|
示例3
|
@RestController
@RequestMapping
(
"/demo"
)
public class
DemoController {
}
|
方法注解
|
1.如果可上没有这个注解,这里将是会以json格式输出,否则方法只能返回字符串,表示模板路径
@ResponseBody
@RequestMapping
(
"/index"
)
|
示例
|
@ResponseBody
@RequestMapping
(
"/index"
)
public
String main(HttpServletRequest request){
return
"dddd"
;
}
@RequestMapping
(
"/test"
)
public
String test(HttpServletRequest request){
return
"test/a"
;
}
}
|
2.控制类方法
RequestMapping
映射
|
@RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有“/path”的UR L请求。RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求
|
|
|
RequestMapping
映射
|
使用@RequestMapping 注解映射请求路径
你可以使用@RequestMapping注解来将请求URL映射到整个类上
或某个特定的方法上,即@RequestMapping 既可以定义在类上,
也可以定义方法上
一般来说,类级别的注解负责将一个特定(或符合某种模式)的请求
路径映射到一个控制器上,同时通过方法级别的注解来细化映射,即
根据特定的HTTP请求方法(GET、POST 方法等)、HTTP请求中是
否携带特定参数等条件,将请求映射到匹配的方法
|
RequestMapping
配置方法
|
(1)映射单个URL
@RequestMapping("") 或 @RequestMapping(value="")
(2)映射多个URL,数组表示这多个路径都是指向同一个方法
@RequestMapping({"",""}) 或 @RequestMapping(value={"",""})
|
RequestMapping
映射方式
|
1、标准URL 映射
标准URL 映射是最简单的一种映射,例如:
@RequestMapping("/hello")
或
@RequestMapping({"/hello","/world"})
2、Ant 风格的 URL 映射
Ant 通配符有三种:
![]()
(1)@RequestMapping("/?/hello/")
如/a/hello,/b/hello,/c/hello,
(2)@RequestMapping("/*/hello")
如/aaa/hello,/bvv/hello,/cddd/hello,
(3)@RequestMapping("/**/hello")
如:如/a/c/hello,/b/ff/hello,/c/ggg/hello
3.占位符{}
URL 中可以通过一个或多个 {} 占位符映射
例如:@RequestMapping("/user/{userId}/{userName}/show")
必须通过@PathVariable("") 注解将占位符中的值绑定到方法参数上,注意必须一一对应
eg:
@ResponseBody
@RequestMapping
(value =
"/zw/{userId}/{userName}"
)
public
String zw(HttpServletRequest request,
@PathVariable("userId") Integer user_id,
@PathVariable("userName") String user_name)
{
System.
out
.println(request.getParameter(
"userId"
)+
"----"
);
System.
out
.println(request.getParameter(
"user_id"
)+
"----"
);
if
(user_name==
null
){
System.
out
.println(
"user_name is null"
);
}
return
"userId="
+user_id+
";user_name="
+user_name;
}
url:
注意:
(1)占位符必须有值,如上述
程序都会报错
(2)站位值用request娶不到,必须用
@PathVariable映射
(3)注意占位符的数据类型,如果数据类型错误,也会报错
|
RequestMapping
映射方法
|
在HTTP 请求中最常用的请求方法是 GET、POST,还有其他的
一些方法,如:DELET、PUT、HEAD 等
|
HTML
|
利用ajax的type和headers来传递改变参数
|
HTML
|
<!DOCTYPE
html
>
<
head
>
<
meta
charset=
"UTF-8"
>
<
title
>
Title
</
title
>
<!--
引入外部的
js
文件
-->
<
script
type=
"text/javascript"
src=
"/webjars/jquery/3.2.0/jquery.js"
></
script
>
<
script
>
function
tj
(typeMethod) {
$
.
ajax
({
//
几个参数需要注意一下
type: typeMethod,
//
方法类型
dataType
:
"json"
,
//
预期服务器返回的数据类型
url
:
"/demo/m"
,
//url
data
: {
id
:
1
,
name
:
'jzk'
},
headers:
//header
里面传递数据
{
"Authorization"
:
'1234456'
,
'pwd'
:
'44333333'
},
success
:
function
(result) {
console
.
log
(result);
//
打印服务端返回的数据
(
调试用
)
alert
(result.userId);
},
error
:
function
() {
alert
(
"
异常!
"
);
}
});
}
</
script
>
</
head
>
<
body
>
<
input
οnclick=
"
tj
(
'GET'
)
"
value=
"button-get"
type=
"button"
/><
br
>
<
input
οnclick=
"
tj
(
'POST'
)
"
value=
"button-POST"
type=
"button"
/><
br
>
<
input
οnclick=
"
tj
(
'PUT'
)
"
value=
"button-put"
type=
"button"
/><
br
>
<
input
οnclick=
"
tj
(
'DELETE'
)
"
value=
"button-delete"
type=
"button"
/><
br
>
<
input
οnclick=
"
tj
(
'HEAD'
)
"
value=
"button-head"
type=
"button"
/><
br
>
</
body
>
</
html
>
|
java
|
@ResponseBody
@RequestMapping
(value =
"/m"
,method=RequestMethod.
GET
)
public
User m(HttpServletRequest request){
System.
out
.println(
"get method"
);
//
获得
head
信息
System.
out
.println(
"head.pwd="
+ request.getHeader(
"pwd"
));
System.
out
.println(
"head.Authorization="
+ request.getHeader(
"Authorization"
));
System.
out
.println(request.getParameter(
"name"
));
System.
out
.println(request.getParameter(
"id"
));
User user=
new
User();
user.setUserId(
55555
);
return
user;
}
@ResponseBody
@RequestMapping
(value =
"/m"
,method=RequestMethod.
POST
)
public
User m1(HttpServletRequest request){
//
获得
head
信息
System.
out
.println(
"post method"
);
System.
out
.println(
"head.pwd="
+ request.getHeader(
"pwd"
));
System.
out
.println(
"head.Authorization="
+ request.getHeader(
"Authorization"
));
System.
out
.println(request.getParameter(
"name"
));
System.
out
.println(request.getParameter(
"id"
));
User user=
new
User();
user.setUserId(
13
);
return
user;
}
@ResponseBody
@RequestMapping
(value =
"/m"
,method=RequestMethod.
PUT
)
public
User m2(HttpServletRequest request){
System.
out
.println(
"put method"
);
//
获得
head
信息
System.
out
.println(
"head.pwd="
+ request.getHeader(
"pwd"
));
System.
out
.println(
"head.Authorization="
+ request.getHeader(
"Authorization"
));
System.
out
.println(request.getParameter(
"name"
));
System.
out
.println(request.getParameter(
"id"
));
User user=
new
User();
user.setUserId(
9999
);
return
user;
}
@ResponseBody
@RequestMapping
(value =
"/m"
,method=RequestMethod.
DELETE
)
public
User m3(HttpServletRequest request){
System.
out
.println(
"DELETE method"
);
//
获得
head
信息
System.
out
.println(
"head.pwd="
+ request.getHeader(
"pwd"
));
System.
out
.println(
"head.Authorization="
+ request.getHeader(
"Authorization"
));
System.
out
.println(request.getParameter(
"name"
));
System.
out
.println(request.getParameter(
"id"
));
User user=
new
User();
user.setUserId(
10000
);
return
user;
}
@ResponseBody
@RequestMapping
(value =
"/m"
,method=RequestMethod.
HEAD
)
public
User m4(HttpServletRequest request){
System.
out
.println(
"HEAD method"
);
//
获得
head
信息
System.
out
.println(
"head.pwd="
+ request.getHeader(
"pwd"
));
System.
out
.println(
"head.Authorization="
+ request.getHeader(
"Authorization"
));
System.
out
.println(request.getParameter(
"name"
));
System.
out
.println(request.getParameter(
"id"
));
User user=
new
User();
user.setUserId(
5788
);
return
user;
}
|
consumes、produces 示例
consumes样例
@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {
// implementation omitted
}
方法仅处理request Content-Type为“application/json”类型的请求。
produces的样例:
@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
// implementation omitted
}
方法仅处理request请求中Accept头中包含了”application/json”的请求,同时暗示了返回的内容类型为application/json;
|
params、headers 示例
params样例
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
仅处理请求中包含了名为“myParam”,值为“myValue”的请求;
headers样例
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=
http://www.ifeng.com/")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
// implementation omitted
}
}
|
header信息解读
|
![]() |
4.方法内入参
@RequestParam的使用
@RequestParam
|
表示接收url?a=1&b=2中的数据,
格式:
url里有?id=..的参数,默认是必须有的,否则报错,注意可以传递控制id=
@RequestParam
(name=
"id"
) String xid
设置为不必须的
@RequestParam
(name=
"id"
,required=
false
) String xid
设置默认值
@RequestParam
(name=
"id"
,required=
false
,defaultValue =
"20"
) String xid
逻辑:
@RequestParam
(name=
"id"
) String xid
等价于
String xid=request.getParamer("id")
|
@RequestParam
示例
|
public Users json(
@RequestParam(name=
"id",required=
false,defaultValue =
"20") String xid, HttpServletRequest request){
System.
out.println(
"request xid=="+xid);
System.
out.println(
"request id=="+request.getParameter(
"id"));
}
|
不加
@RequestParam
|
@RequestMapping(
"/t1")
public Users t1(Integer id, HttpServletRequest request){
System.
out.println(
"request origin id=="+id);
System.
out.println(
"request id=="+request.getParameter(
"id"));
Users user=
new Users();
// user.setName("大傻子");
user.setId(
4);
return user;
}
|
说明
|
不加
@RequestParam 也可获得url传递过来的值,因为java会自动解析参数值
但是效率会低些
两者对比的话,加@RequestParam就减少了IO本地class文件解析并缓存配置,但是不加的话就方便了程序员的开发,开发者只需要按照规范命名,就可以少写很多代码
注意post里的参数也取得到和,和get一样
|
@requestBody注解的使用
应用场景
|
@RequestBody需要接的参数是一个string化的json,如果是json对象要报错
@RequestBody,要读取的数据在请求体里,所以要发post请求,还要将Content-Type设置为application/json,如果不是的话要报错
提交方法必须是post
通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。
|
Java
|
@ResponseBody
@RequestMapping(
"/save1")
public Users save1(
@RequestBody Users user){
System.
out.println(user.getName());
//System.out.println(dateFomcat(user.getBirth())+"----------------");
return user;
}
|
html
|
<
script
>
function
tj() {
var
param={
"id":
"1",
"name":
'jzk',
"height":
"345.563"
};
//注意jquery自带的.serialize();是序列化成?id=.&name=dd这类的字符串
var
str=
$(
"#form1").
serialize();
alert(
str);
//jquery.serializejson.js插件功能
param =
$(
"#form1").
serializeJSON();
//表单转json对象
param=
JSON.
stringify(
param);//json字符串
alert(
param);
$
.
ajax
({
//几个参数需要注意一下
type
:
"POST"
,
//方法类型,必须是post
dataType
:
"json"
,
//预期服务器返回的数据类型
//默认的是:Content-Type: application/x-www-form-urlencoded; charset=UTF-8
//两个相等的 headers contentType
// headers : {"Content-Type" : "application/json;charset=utf-8"},
contentType
:
"application/json;charset=utf-8"
,
url
:
"/demo/save1"
,
//url
data
:
param
,
success
:
function
(result) {
console
.
log
(result);
//打印服务端返回的数据(调试用)
alert
(result.
id
);
},
error
:
function
() {
alert
(
"异常!"
);
}
});
}
</
script>
</
head>
<
body>
<
form
id=
"form1">
<
table
border=
"1">
<
tr>
<
td>id</
td>
<
td><
input
type=
"input"
name=
"id"></
td>
</
tr>
<
tr>
<
td>name</
td>
<
td><
input
type=
"input"
name=
"name"></
td>
</
tr>
<
tr>
<
td>height</
td>
<
td><
input
type=
"input"
name=
"height"></
td>
</
tr>
</
table>
</
form>
<
input
type=
"button"
id=
"name"
οnclick=
"
tj()
"
value=
"提交表单">
</
body>
</
html>
|
注意
|
ResponseBody
只能映射到java对象,如果用字符串接收,则无法具体接收到实际值
而是json字符串
这样接收到的是前端传来的json字符串。而不是userName值
@ResponseBody
@RequestMapping(value=
"/sz3")
public Users sz3(
@RequestBody String userName){
System.
out.println(userName);
return new Users();
}
输出:
{"userName":"1","sex":"男"}
这样会报错:
@ResponseBody
@RequestMapping(value=
"/sz3")
public Users sz3(
@RequestBody String userName,
@RequestBody String sex){
System.
out.println(userName);
System.
out.println(sex);
return new Users();
}
|
@
RequestHeader
注解的使用
@RequestHeader
|
获取head里的值
--- value :参数名称
--- required :是否必须,默认为true,表示请求参数中必须包含对应的参数,否则抛出异常。
--- defaultValue:当请求参数缺少或者有请求参数但值为空时,值采用该设置值。
请求头包含若个属性,服务器可根据请求头属性信息获取客户端的信息,通过@RequestHeader既可以将请求头的属性值绑定到处理方法的入参中。
|
java
|
@ResponseBody
@RequestMapping
(value=
"/save2"
)
public
User save1(
@RequestHeader
(
"auth"
) String auth,
@RequestHeader
(
"pwd"
) String pwd,User user){
System.
out
.println(
"auth=="
+auth);
System.
out
.println(
"pwd=="
+pwd);
System.
out
.println(user.getName());
//System.out.println(dateFomcat(user.getBirth())+"----------------");
return
user;
}
|
html |
$
.
ajax
({
//
几个参数需要注意一下
type
:
"POST"
,
//
方法类型
dataType
:
"json"
,
//
预期服务器返回的数据类型
url
:
"/demo/save2"
,
//url
headers
:
//header
里面传递数据
{
"auth"
:
'1234456'
,
'pwd'
:
'44333333'
},
data
:
param
,
success
:
function
(result) {
console
.
log
(result);
//
打印服务端返回的数据
(
调试用
)
alert
(result.
name
);
},
error
:
function
() {
alert
(
"
异常!
"
);
}
});
}
|
其他方法
| request.getHeader("")获得 |
@CookieValue
注解的使用
说明 |
--- value :参数名称
--- required :是否必须,默认为true,表示请求参数中必须包含对应的参数,否则抛出异常。
--- defaultValue:当请求参数缺少或者有请求参数但值为空时,值采用该设置值。
@CookieValue可让处理方法入参绑定某个cookie值。
|
添加cookie
|
@RequestMapping
(value =
"/init2"
)
public
String init1(HttpServletRequest request,HttpServletResponse response){
request.getSession().setAttribute(
"gg"
,
"11111"
);
Cookie cookie=
new
Cookie(
"cook-id"
,
"CookieTestInfo"
);
response.addCookie(cookie);
return
"head"
;
}
|
接收java
|
@RequestMapping("/testCookieValue"
)
public
String testCookieValue(@CookieValue(value = "
cook-id
", required =
true
, defaultValue = "-999"
) String
cookId
) {
System.out.println(
"testCookieValue,
cook-id
:" +
cookId
);
return
SUCCESS;
}
|
其他入参
(1)简单数组
简单类型数组
|
/**
* 前端用ajax提交
* var param={
* "ids":["1","2","3"],
* "name":"将增奎"
* };
* Content-Type: application/x-www-form-urlencoded; charset=UTF-8
*
@param
list
*
@return
*/
@ResponseBody
@RequestMapping(value=
"/sz1")
public List<String> sz1(
@RequestParam(value =
"ids[]", required =
false) List<String> list){
for(String s:list){
System.
out.println(
"ss=="+s);
}
return list;
}
/**
* 前端用ajax提交
* var param={
* "ids":["1","2","3"],
* "name":"将增奎"
* };
* Content-Type: application/x-www-form-urlencoded; charset=UTF-8
*
@return
*/
@ResponseBody
@RequestMapping(value=
"/sz2")
public String[] sz2(
@RequestParam(value =
"ids[]", required =
false) String[] ids){
if(ids==
null){
System.
out.println(
"ids==="+ids);
}
for(String s:ids){
System.
out.println(
"ss=="+s);
}
return ids;
}
|
注意:
|
必须用@RequestParam来注解,用list或者数组来接收都可以,直接用数组或者list接收会报错
用
@RequestBody只能接收到json数组字符串
|
报错
|
public String[] sz2( String[] ids){
if(ids==
null){
System.
out.println(
"ids==="+ids);
}
for(String s:ids){
System.
out.println(
"ss=="+s);
}
return ids;
}
|
(2)复杂对象数组
js
|
function
tj2() {
var
param={
age:[
1,
2,
3,
4]
};
var
userSZ = [];
var
user =
new
Object();
user.
id =
12;
user.
name =
"将增奎";
userSZ.
push(
user);
var
user1 =
new
Object();
user1.
id =
13;
user1.
name =
"大波妹";
userSZ.
push(
user1);
param=
JSON.
stringify(
userSZ);
//或者直接用字符串,注意一定要用\",用'Java映射要出错
param=
"[{
\"
id
\"
:12,
\"
name
\"
:
\"
将增奎
\"
},{
\"
id
\"
:13,
\"
name
\"
:
\"
大波妹
\"
}]";
alert(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/sz4",
//url
data:
param,
contentType:
"application/json;charset=utf-8",
success:
function (result) {
}
|
java
|
@ResponseBody
@RequestMapping(value=
"/sz4")
public Users sz4(
@RequestBody List<Users> list){
for(Users users:list){
System.
out.println(users);
}
return new Users();
}
|
注意
|
java用@RequestBody接收,
用list或者数组都可以 List<Users> list 或者Users[] list
注解用List或者数组出错
public
Users sz4(
List<Users> list){
}
在
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 http传递格式时
springMVC不支持List类型直接转换,需要封装成Object,
public String list(List uList)这种写法是不对的
需要自己写一个类,这个类里面的某个属性是一个List集合
如:
public class UserListForm(
private List uList;
)
|
(3)对象里包含简单数组
js
|
function
tj3() {
var
param={
"id":
1,
"name":
"将增奎",
"likes":[
"足球",
"篮球",
"羽毛球"]
}
param=
JSON.
stringify(
param);
alert(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/sz5",
//url
data:
param,
contentType:
"application/json;charset=utf-8",
success:
function (result) {
}
|
java
|
@ResponseBody
@RequestMapping(value=
"/sz5")
public Users sz5(
@RequestBody Users users){
System.
out.println(
"user"+users);
//list 或者数组都可以
List<String> list=users.getLikes();
for(String like:list){
System.
out.println(like);
}
return users;
}
|
java vo
|
public class Users {
private Integer
id;
private String
name;
@JsonFormat(timezone =
"GMT+8", pattern =
"yyyy-MM-dd")
private Date
birth;
private Boolean
isSex;
private BigDecimal
weight;
private Double
height;
public Float
jb;
private List<String>
likes;
}
|
注意
|
如果对象里包含有数组或者list
用
public Users sz5( Users users){}接收会出错
|
(4)对象里包含对象数组
js
|
function
tj4() {
var
param={
"id":
1,
"name":
"将增奎",
"juzhus":[
{
"shen":
"四川",
"city":
"成都"},
{
"shen":
"四川",
"city":
"简阳"}
]
}
param=
JSON.
stringify(
param);
alert(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/sz9",
//url
data:
param,
contentType:
"application/json;charset=utf-8",
success:
function (result) {
},
error:
function () {
alert(
"异常!");
}
});
}
|
Java
|
@ResponseBody
@RequestMapping(value=
"/sz9")
public Users sz9(
@RequestBody Users users){
System.
out.println(
"=============");
System.
out.println(
"user"+users);
//list 或者数组界都可以
if(users.getJuzhus()!=
null){
List<Address> list = users.getJuzhus();
for (Address a : list) {
System.
out.println(a);
}
}
return users;
}
|
注意
|
前端用json对象传递
后端用去掉
@ResponseBody用普通对象接收,要报错
|
|
|
(5)对象里包含对象
js
|
function
tj5() {
var
param={
"id":
1,
"name":
"将增奎",
"address":{
"shen":
"四川",
"city":
"成都"}
}
param=
JSON.
stringify(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/sz10",
//url
data:
param,
contentType: "application/json;charset=utf-8",
success:
function (result) {
},
error:
function () {
alert(
"异常!");
}
});
}
|
java
|
@ResponseBody
@RequestMapping(value=
"/sz10")
public Users sz10(
@RequestBody Users users){
System.
out.println(
"user"+users);
}
return users;
}
|
注意
|
前端用json对象传递
后端用去掉
@ResponseBody用普通对象接收,要报错
|
6.表单参数提交
html
|
<!DOCTYPE
html>
<
head>
<
meta
charset=
"UTF-8" >
<
title>复杂页面</
title>
<
link
rel=
"stylesheet"
href=
"/css/public.css">
<
script
src=
"/js/public.js"></
script>
<!--
<script src="/js/jquery-3.1.1.min.js"></script>
-->
<
script
src=
"/webjars/jquery/3.2.0/jquery.js"></
script>
<
script
src=
"/js/jquery.serializejson.js"></
script>
<
script
language=
"JavaScript1.2">
function
tj1() {
//直接提交表单
$(
"#form1").
submit();
}
</
script>
</
head>
<
body>
<
form
id=
"form1"
th
:action=
"@{'/demo/form_deal1'}"
method=
"post">
<
table
border=
"1">
<
tr>
<
td>id</
td>
<
td><
input
type=
"input"
name=
"id"></
td>
</
tr>
<
tr>
<
td>name</
td>
<
td><
input
type=
"input"
name=
"name"></
td>
</
tr>
<
tr>
<
td>height</
td>
<
td><
input
type=
"input"
name=
"height"></
td>
</
tr>
<!--
对应后台数组,或者list
-->
<
tr>
<
td>喜欢</
td>
<
td>
<
input
type=
"input"
name=
"likes"
style=
"
width:
80
px
">
<
input
type=
"input"
name=
"likes"
style=
"
width:
80
px
">
</
td>
</
tr>
<
tr>
<
td>居住地</
td>
<
td>
<!--
对应后台数组,或者list<vo>数据类型,这里要使用:
对象名[索引].属性名的数据格式
如果要做动态删除会有麻烦
索引必须要从0开始一次新增,如果有间隔,也会自动生成一个list的vo对象对象,只是里面没有值
-->
<
input
type=
"input"
name=
"juzhus[0].shen"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[0].city"
style=
"
width:
80
px
">市
<
br>
<
input
type=
"input"
name=
"juzhus[1].shen"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[1].city"
style=
"
width:
80
px
">市
<
br>
<
input
type=
"input"
name=
"juzhus[2].shen"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[2].city"
style=
"
width:
80
px
">市
</
td>
</
tr>
<
tr>
<
td>住址</
td>
<
td>
<!--
对应后台类里面的类
-->
<
input
type=
"input"
name=
"address.shen">省-
<
input
type=
"input"
name=
"address.city">市
</
td>
</
tr>
</
table>
</
form>
<
input
type=
"button"
id=
"name"
οnclick=
"
tj1()
"
value=
"form提交">
<
input
type=
"button"
οnclick=
"
tj2()
"
value=
"ajax提交">
</
body>
</
html>
<
script
language=
"JavaScript1.2">
function
tj2() {
var
param=
$(
"#form1").
serialize();
alert(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/form_deal2",
//url
data:
param,
// contentType: "application/json;charset=utf-8",
success:
function (result) {
console.
log(result);
//打印服务端返回的数据(调试用)
var
ret=
JSON.
stringify(result);
alert(
ret);
},
error:
function () {
alert(
"异常!");
}
});
}
</
script>
|
java
|
users
public class Users {
private Integer
id;
private String
name;
@JsonFormat(timezone =
"GMT+8", pattern =
"yyyy-MM-dd")
private Date
birth;
private Boolean
isSex;
private BigDecimal
weight;
private Double
height;
public Float
jb;
private List<String>
likes;
private List<Address>
juzhus;
private Map<String,String>
map;
private Address
address;
}
Address
public class Address {
private String
shen;
private String
city;
}
控制类
@ResponseBody
@RequestMapping(value=
"/form_deal2")
public Users form_deal2( Users users){
System.
out.println(
"=============");
System.
out.println(users);
//list 或者数组界都可以
if(users.getJuzhus()!=
null){
List<Address> list = users.getJuzhus();
for (Address a : list) {
System.
out.println(a);
}
}
return users;
}
|
解释说明
|
var
param=
$(
"#form1").
serialize();
$(
"#form1").
submit();
这两种提交方式都是一样的,都是把表单参数转换成a=..&b=..&c=..
get 和post方式不同,是get会把表单参数挂到url,post放置到header里面
$.
ajax({
data:
可接受
1.json对象
2.json字符串 必须用
contentType
:
"application/json;charset=utf-8",后端用@RequestBody
3.ulr参数
a=..&b=..&c=..
传递json对象只能映射基础的vo对象,对于负责的对象,需要
(1)字符串json
(2)post
(3)
application/json;charset=utf-8
(4)@RequestBody
|
7.表单元素转化成json格式提交
HTML
|
<
form
id=
"form2"
th
:action=
"@{'/demo/form_deal1'}"
method=
"post">
<
table
border=
"1">
<
tr>
<
td>id</
td>
<
td><
input
type=
"input"
name=
"id"></
td>
</
tr>
<
tr>
<
td>name</
td>
<
td><
input
type=
"input"
name=
"name"></
td>
</
tr>
<
tr>
<
td>height</
td>
<
td><
input
type=
"input"
name=
"height"></
td>
</
tr>
<
tr>
<
td>sex</
td>
<
td><
input
type=
"checkbox"
name=
"sex"
value=
"1"></
td>
</
tr>
<
tr>
<
td>inner_emp</
td>
<
td><
input
type=
"checkbox"
name=
"inner_emp"
value=
"true"></
td>
</
tr>
<
tr>
<
td>xueli</
td>
<
td>
<!--
数组要用[]
-->
<
label><
input
type=
"checkbox"
name=
"xueli[]"
value=
"1">大学</
label>
<
label><
input
type=
"checkbox"
name=
"xueli[]"
value=
"2">高中</
label>
<
label><
input
type=
"checkbox"
name=
"xueli[]"
value=
"3">初中</
label>
</
td>
</
tr>
<
tr>
<
td>喜欢</
td>
<
td>
<!--
数组要用[]
-->
<
select
name=
"likes[]"
multiple=
"true">
<
option
value=
"1">篮球</
option>
<
option
value=
"2">足球</
option>
<
option
value=
"3">羽毛球</
option>
</
select>
</
td>
</
tr>
<
tr>
<
td>辈份</
td>
<
td>
<
select
name=
"bf" >
<
option
value=
"1">儿子</
option>
<
option
value=
"2">孙子</
option>
<
option
value=
"3">爸爸</
option>
</
select>
</
td>
</
tr>
<
tr>
<
td>居住地</
td>
<
td>
<!--
数组要用[][对象熟悉]格式
-->
<
input
type=
"input"
name=
"juzhus[][shen]"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[][city]"
style=
"
width:
80
px
">市
<
br>
<
input
type=
"input"
name=
"juzhus[][shen]"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[][city]"
style=
"
width:
80
px
">市
<
br>
<
input
type=
"input"
name=
"juzhus[][shen]"
style=
"
width:
80
px
">省
<
input
type=
"input"
name=
"juzhus[][city]"
style=
"
width:
80
px
">市
</
td>
</
tr>
<
tr>
<
td>住址</
td>
<
td><
input
type=
"input"
name=
"address.shen">省-<
input
type=
"input"
name=
"address.city">市</
td>
</
tr>
</
table>
</
form>
<
script
language=
"JavaScript1.2">
function
tj3() {
//
jquery.serializejson.js函数里
serializeJSON
把表单元素转化成json对象
var
param=
$(
'#form2').
serializeJSON();
param=
JSON.
stringify(
param);
console.
log(
param);
alert(
param);
$.
ajax({
//几个参数需要注意一下
type:
"POST",
//方法类型
dataType:
"json",
//预期服务器返回的数据类型
url:
"/demo/form_deal3",
//url
data:
param,
contentType:
"application/json;charset=utf-8",
success:
function (result) {
console.
log(result);
//打印服务端返回的数据(调试用)
var
ret=
JSON.
stringify(result);
alert(
ret);
},
error:
function () {
alert(
"异常!");
}
});
}
</
script>
|
Java
|
@ResponseBody
@RequestMapping(value=
"/form_deal2")
public Users form_deal2( Users users){
System.
out.println(
"=============");
System.
out.println(users);
//list 或者数组界都可以
if(users.getJuzhus()!=
null){
List<Address> list = users.getJuzhus();
for (Address a : list) {
System.
out.println(a);
}
}
return users;
}
|
说明
|
jquery.serializejson.js是一个表单转化控件
注意对数组的处理
用这种方式可动态的处理列表
|
入参汇总
pojo参数 |
Spring MVC 会按请求参数名和 POJO 属性名进行自动匹 配,自动为该对象填充属性值。支持级联属性。 如:dept.deptId、dept.address.tel 等
|
pojo示例
|
![]() |
Servlet API对象
|
HttpServletRequest,HttpServletResponse HttpSession
|
|
@RequestMapping
(value=
"/init5"
)
public
String save5(HttpServletRequest request,HttpServletResponse response,HttpSession session){
System.
out
.println(
"session id==="
+session.getId());
String uname=(String)session.getAttribute(
"uname"
);
if
(uname==
null
){
System.
out
.println(
"session.uname is null"
);
session.setAttribute(
"uname"
,
"djia"
);
}
else
{
System.
out
.println(
"session.uname=="
+uname);
}
return
"view"
;
}
注意:
1.session可以从request里获得,也可以注入
2.
ServletContext(application)只能从request里获得,不能注入
|
基本变量
|
基本变量和和传入参数完成映射,只要名称一样,就能映射
@RequestMapping
(value=
"/save4"
)
public
String save4(Integer userId,String name,Double weight)
|
@PathVariable
|
url用占位符,对应参数用
@ResponseBody
@RequestMapping
(value =
"/zw/{userId}/{userName}"
)
public
String zw(HttpServletRequest request,
@PathVariable("userId") Integer user_id,
@PathVariable("userName") String user_name)
|
@
RequestHeader
|
获得request http head里的数据
@RequestHeader
(
"auth"
) String auth,
@RequestHeader
(
"pwd")
|
@requestBody
|
获得post方法提交的json字符串数据映射
public Users save1(
@RequestBody Users user)
public void login(
@requestBody String userName,
@requestBody String pwd
)
|
@RequestParam
|
获得url数据
注意post里的参数也取得到和,和get一样
public Users json(
@RequestParam(name=
"id",required=
false,defaultValue =
"20") String xid)
|
@CookieValue
|
获得cookie的数据
@RequestMapping("/testCookieValue"
)
public
String testCookieValue(@CookieValue(value = "
cook-id
", required =
true
, defaultValue = "-999"
) String
cookId
)
|
json对象入参
|
ajax方式提交,可为json对象或者json格式的字符串
|
form表单入参
|
可以直接form提交,也可以
|
数据提交总结
form submit
|
post get 都是以a=..&b=..&c=..参数传递
|
ajax
|
1.json对象 简单数据
2.a=..&b=..&c=.字符串 没有数组集合等
3.json对象转化成字符串,处理负责表单
|
|
|
日期时间处理
Java vo对象
|
最笨办法:每个都加
@JsonFormat(pattern=
"yyyy-MM-dd",timezone=
"GMT+8")
@DateTimeFormat(pattern =
"yyyy-MM-dd")
private Date
birth;
@JsonFormat(pattern=
"yyyy-MM-dd HH:mm:ss",timezone=
"GMT+8")
@DateTimeFormat(pattern =
"yyyy-MM-dd HH:mm:ss")
private Date
create_at;
|
对外json格式化展示
@JsonFormat
|
(1)第一种方式:
在在vo属性数据上统一加,采用
@JsonFormat 标签进行格式化
@JsonFormat(pattern=
"yyyy-MM-dd",timezone=
"GMT+8") 日期
@JsonFormat(pattern=
"yyyy-MM-dd HH:mm:ss",timezone=
"GMT+8") 时间
注意:需要增加timezone="GMT+8",表示北京时间,否则展示会有数据偏移
(2)第二种方法
可在application.properties配置全局默认值
#json日期格式化默认值
spring.jackson.date-format=
yyyy-MM-dd
spring.jackson.time-zone=
GMT+8
在vo时间类型字段,如果是yyyy-MM-dd就不加了,如果是其他的格式,才加
eg:
@JsonFormat
(pattern=
"yyyy-MM-dd HH:mm:ss"
,timezone=
"GMT+8"
)
private
Date
create_at
;
|
html页面展示
|
1.thymeleaf
${#dates.format(create_at, 'yyyy-MM-dd HH:mm:ss')}
2.freemarker
(xb_user_yhq.lose_date?string("yyyy-MM-dd"))!
3.注意:
thymeleaf from表单绑定日期不能用field
正确
<
input
type=
"text"
name=
"birth"
th
:value=
"*{#dates.format(birth, 'yyyy-MM-dd')}"
>
错误
<
input
type=
"text"
th
:field=
"*{#dates.format(birth, 'yyyy-MM-dd')}"
>
|
外部输入
json对象或者表单参数提交
@DateTimeFormat
|
(1)第一种方法:
在在vo属性数据上统一加
@DateTimeFormat(pattern =
"yyyy-MM-dd")
@DateTimeFormat(pattern =
"yyyy-MM-dd HH:mm:ss")
(2)第二种方法
在 application.properties配置全局默认数据转化格式
#输入转化,默认转化为yyyy-MM-dd,特殊的增加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
spring.mvc.date-format
=
yyyy-MM-dd
在vo时间类型字段,如果是yyyy-MM-dd就不加了,如果是其他的格式,才加
eg:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
示例
|
application.properties文件
#默认日期
#json展示,默认转化为yyyy-MM-dd格式,特殊的在字段上增加 @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
spring.jackson.date-format=
yyyy-MM-dd
spring.jackson.time-zone=
GMT+8
#输入转化,默认转化为yyyy-MM-dd,特殊的增加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
spring.mvc.date-format=
yyyy-MM-dd
java代码
//标准的yyy-MM-dd不条件输出和输入,用properties中设置的默认方式
private Date
birth;
//特殊的才标志
@JsonFormat(pattern=
"yyyy-MM-dd HH:mm:ss",timezone=
"GMT+8")
@DateTimeFormat(pattern =
"yyyy-MM-dd HH:mm:ss")
private Date
create_at;
@DateTimeFormat(pattern =
"yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern=
"yyyy-MM-dd HH:mm:ss",timezone=
"GMT+8")
private Date
update_at;
|
注意事项
|
如果再属性文件里配置
#输入转化,默认转化为yyyy-MM-dd,特殊的增加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
spring.mvc.date-format=
yyyy-MM-dd
而且如果通过基本参数接收,都会被截取时间部分
如:
public
List<Emp> listByCreateTime(Date create_at, HttpServletRequest request){
这里接收到的
create_at肯定只有日期部分的,所以要用对象来接收,对象里包含
create_at属性,并标注上
@DateTimeFormat
(pattern =
"yyyy-MM-dd HH:mm:ss"
)
}
|
输入参数最佳方案
|
思路:写cover转化类,动态判断时间,这样就不需要写
DateTimeFormat了
(1)转换类
/**
* 日期格式转换服务 表单字符串日期自动转换成vo里面的date日期
*
@author
jiangzengkui
*
@date
2016年9月1日 下午10:13:32
*
@Description:
*
*/
public class DateConverter
implements Converter<String,Date>{
public static final DateFormat
DF_LONG =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
public static final DateFormat
DF_LONG2 =
new SimpleDateFormat(
"yyyy-MM-dd HH");
public static final DateFormat
DF_LONG3 =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm");
public static final DateFormat
DF_LONG4 =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
public static final DateFormat
DF_SHORT =
new SimpleDateFormat(
"yyyy-MM-dd");
public static final DateFormat
DF_YEAR =
new SimpleDateFormat(
"yyyy");
public static final DateFormat
DF_MONTH =
new SimpleDateFormat(
"yyyy-MM");
/**
* 短类型日期长度
*/
public static final int
SHORT_DATE =
10;
public static final int
SHORT_DATE2 =
13;
public static final int
SHORT_DATE3 =
16;
public static final int
SHORT_DATE4 =
19;
public static final int
YEAR_DATE =
4;
public static final int
MONTH_DATE =
7;
@Override
public Date convert(String text) {
System.
out.println(
"日期类型已执行=======");
//
TODO Auto-generated method stub
if (!StringUtils.
hasText(text)) {
return null;
}
text=text.trim();
try {
if (text.length() <=
YEAR_DATE) {
return (
new java.sql.Date(
DF_YEAR.parse(text).getTime()));
}
else if (text.length() <=
MONTH_DATE) {
return (
new java.sql.Date(
DF_MONTH.parse(text).getTime()));
}
else if (text.length() <=
SHORT_DATE) {
return (
new java.sql.Date(
DF_SHORT.parse(text).getTime()));
}
else if (text.length() <=
SHORT_DATE2) {
return (
new java.sql.Timestamp(
DF_LONG2.parse(text).getTime()));
}
else if (text.length() <=
SHORT_DATE3) {
return (
new java.sql.Timestamp(
DF_LONG3.parse(text).getTime()));
}
else
{
return (
new java.sql.Timestamp(
DF_LONG.parse(text).getTime()));
}
}
catch (ParseException ex) {
IllegalArgumentException iae =
new IllegalArgumentException(
"Could not parse date: " + ex.getMessage());
iae.initCause(ex);
throw iae;
}
}
}
(2)配置注册类
@Configuration
@Import({WebMvcAutoConfiguration.
class})
/**
* ComponentScan不配置好像也没有问题
*/
@ComponentScan(
value =
"com.jyj.mybatisdemo",
includeFilters = {
@ComponentScan.Filter(type = FilterType.
ANNOTATION, value =
Controller.
class)
})
public class WebMvcConfig
implements WebMvcConfigurer {
@Bean
public DateConverter stringToDateConverter() {
return new DateConverter();
}
}
|
json格式null转化为空字符串
所有null都变成
""
|
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.
class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(
false).build();
objectMapper.getSerializerProvider().setNullValueSerializer(
new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(
"");
}
});
return objectMapper;
}
}
|
|
|
|
|
|
|
异常处理
(1)错误页面替代
默认得springboot不友好,可自己定义,除去捕获404,500等错误外,还能捕获freemark,thyleaf等模板的错误,但捕获不了ajax错误
Java代码
|
@Controller
public class MyErrorController
implements ErrorController {
@RequestMapping(
"/error")
public String handleError(HttpServletRequest request){
//获取statusCode:401,404,500
Integer statusCode = (Integer) request.getAttribute(
"javax.servlet.error.status_code");
if(statusCode ==
500){
return
"/error/500";
}
else if(statusCode ==
404){
//对应的是/error/404.html、/error/404.jsp等,文件位于/templates下面
return
"/error/404";
}
else if(statusCode ==
403){
return
"/error/500";
}
else{
return
"/error/500";
}
}
@Override
public String getErrorPath() {
return
"/error";
}
}
|
HTML目录
|
![]() |
http状态码说明
|
2XX 成功
· 200 OK,表示从客户端发来的请求在服务器端被正确处理
· 204 No content,表示请求成功,但响应报文不含实体的主体部分
· 206 Partial Content,进行范围请求
3XX 重定向
· 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
· 302 found,临时性重定向,表示资源临时被分配了新的 URL
· 303 see other,表示资源存在着另一个 URL,应使用 GET 方法丁香获取资源
· 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
· 307 temporary redirect,临时重定向,和302含义相同
4XX 客户端错误
· 400 bad request,请求报文存在语法错误
· 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
· 403 forbidden,表示对请求资源的访问被服务器拒绝
· 404 not found,表示在服务器上没有找到请求的资源
5XX 服务器错误
· 500 internal sever error,表示服务器端在执行请求时发生了错误
· 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
|
(2)全局异常捕获
全局异常可以捕获普通请求和ajax异常,在500等错误捕获权重高于第一种捕获方式,但捕获了不404,模板页面异常,更多的时候结合
第一种方式起来用
Java
|
/**
* 全局异常捕获处理
*/
@RestControllerAdvice
public class ExceptionControllerAdvice {
private static final Logger
logger= LoggerFactory.
getLogger(ExceptionControllerAdvice.
class);
// 捕捉shiro的异常
@ExceptionHandler(ShiroException.
class)
public Result handle401() {
return new Result(
401,
null,
"您没有权限访问!");
}
// 捕捉其他所有异常
@ExceptionHandler(Exception.
class)
public Object globalException(HttpServletRequest request, HandlerMethod handlerMethod, Throwable ex) {
boolean isAjax=isAjax(request);
System.
out.println(
"全局异常拦截:globalException,isAjax:"+isAjax);
if(isAjax){
return new Result(getStatus(request).value(),
null,
"访问出错,无法访问: " );
}
else {
ModelAndView modelAndView =
new ModelAndView();
modelAndView.setViewName(
"/error/500");
//这里需要在templates文件夹下新建一个/error/500.html文件用作错误页面
modelAndView.addObject(
"errorMsg",ex.getMessage());
return modelAndView;
}
}
/**
* 判断是否是Ajax请求
*
*
@param
request
*
@return
*/
public boolean isAjax(HttpServletRequest request) {
return (request.getHeader(
"X-Requested-With") !=
null &&
"XMLHttpRequest".equals(request.getHeader(
"X-Requested-With").toString()));
}
// @ExceptionHandler(Exception.class)
// public Result globalException(HttpServletRequest request, Throwable ex) {
// return new Result(getStatus(request).value(),"访问出错,无法访问: " + ex.getMessage(),null);
// }
/**
* 获取响应状态码
*
@param
request
*
@return
*/
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute(
"javax.servlet.error.status_code");
if (statusCode ==
null) {
return HttpStatus.
INTERNAL_SERVER_ERROR;
}
return HttpStatus.
valueOf(statusCode);
}
/**
* 捕捉404异常,这个方法只在配置
* spring.mvc.throw-exception-if-no-handler-found=true来后起作用
*
*/
@ResponseStatus(HttpStatus.
NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.
class)
public Result handle(HttpServletRequest request,NoHandlerFoundException e) {
return new Result(
404,
null,
"没有【"+request.getMethod()+
"】"+request.getRequestURI()+
"方法可以访问");
}
|
Result
|
public class Result {
private int
code;
private String
msg;
private Object
cont;
public Result() {}
public Result(
int code,Object cont,String msg){
this.
code=code;
this.
cont=cont;
this.
msg=msg;
}
public static Result success(Object cont){
return new Result(
200,cont,
"请求成功");
}
}
|
json返回格式通用封装
VO对象
|
import io.swagger.annotations.
ApiModel;
import io.swagger.annotations.
ApiModelProperty;
@ApiModel(description=
"
接口返回
数
据
")
public class RetVO<
T> {
@ApiModelProperty(value =
"
返回
编码
")
public int
code;
//
返回状态码
200
成功
@ApiModelProperty(value =
"
返回消息
")
private String
msg;
//
返回描述信息
@ApiModelProperty(value =
"
返回
数
据
")
private
T
data;
//
返回内容体
public int getCode()
{
return
code;
}
/**
*
设置
code
并返回对象
*
@param
code
*
@return
*/
public RetVO<
T> setCode(
int code){
this.
code=code;
return this;
}
public String getMsg() {
return
msg;
}
public RetVO<
T> setMsg(String msg){
this.
msg=msg;
return this;
}
public
T getData()
{
return
data;
}
public RetVO<
T> setData(
T data) {
this.
data = data;
return this;
}
}
|
VO工厂 |
public class RetFactory {
//
通用
msg
public final static String
MSG_OK =
"
操作成功
";
public final static String
MSG_ERR =
"
操作失
败
";
//
通用编码,大于
1000
,则用于业务编码
public final static int
CODE_OK=
200;
//
成功
public final static int
CODE_ERR=
400;
//
失败
public final static int
CODE_UNAUTHORIZED=
401;
//
认证失败
public final static int
CODE_FORBIDDEN=
403;
//
表示对请求资源的访问被服务器拒绝
public final static int
CODE_NO_FOUND=
404;
//
没有找到接口
public final static int
CODE_SERVER_ERROR=
500;
//
服务器内部错误
public final static int
CODE_NO_LOGIN=
600;
//
未登陆
public static <
T> RetVO<
T> ok(){
return new RetVO<
T>().setCode(
CODE_OK).setMsg(
MSG_OK);
}
public static <
T> RetVO<
T> ok(String msg){
return new RetVO<
T>().setCode(
CODE_OK).setMsg(msg);
}
public static <
T> RetVO<
T> ok(
T data){
return new RetVO<
T>().setCode(
CODE_OK).setMsg(
MSG_OK).setData(data);
}
public static <
T> RetVO<
T> err(){
return new RetVO<
T>().setCode(
CODE_SERVER_ERROR).setMsg(
MSG_ERR);
}
public static <
T> RetVO<
T> err(String msg){
return new RetVO<
T>().setCode(
CODE_SERVER_ERROR).setMsg(msg);
}
public static <
T> RetVO<
T> err(
int code,String msg){
return new RetVO<
T>().setCode(code).setMsg(msg);
}
public static <
T> RetVO<
T> err(
T data,String msg){
return new RetVO<
T>().setCode(
CODE_SERVER_ERROR).setMsg(msg).setData(data);
}
}
|
应用
|
@RestController
@RequestMapping(
"/test")
@Api(value=
"",tags =
"
测试
接口
")
public class TestController {
@GetMapping(
"/queryUserList")
@ApiOperation(value=
"
查询
用
户
",notes =
"
查询
用
户
")
@ResponseBody
public RetVO<Person> queryUserList() {
try {
//
调用业务层返回用户列表
Person person=
new Person();
person.setId(
10);
person.setName(
"jzk");
return RetFactory.
ok(person);
}
catch (Exception e) {
e.printStackTrace();
return RetFactory.
err(
"
查询
用
户
信息
异
常
");
}
}
@GetMapping(
"/queryUserList2")
@ApiOperation(value=
"
查询
用
户
",notes =
"
查询
用
户
")
@ResponseBody
public RetVO<List<Person>> queryUserList2() {
try {
List<Person> list=
new ArrayList<Person>();
Person person=
new Person();
person.setId(
10);
person.setName(
"jzk");
list.add(person);
Person person1=
new Person();
person1.setId(
10);
person1.setName(
"jzk");
list.add(person);
return RetFactory.
ok(list);
}
、
}
|
注意
|
在RetVO类里,数据对象用
private T
data,比
private
Object
data 更有优势,
如在swagger里可以识别出data里的数据属性
|
输入参数合法性检查
实体类参数校验注解
|
public class Param {
@NotNull(message =
"
性名不能
为
空
")
private String
name;
@Max(value =
10,message =
"
年
纪
不大大于
10")
private Integer
age;
。。。。
}
|
controller注解
|
@Valid 注解到输入参数上
@GetMapping(
"/v2")
@ResponseBody
public RetVO<Param> validateParam2(
@Valid Param param){
System.
out.println(param);
return RetFactory.
ok(param);
}
@GetMapping(
"/v3")
public String validateParam3(
@Valid Param param){
System.
out.println(param);
return
"son/hello";
}
|
单参数校验
|
注意:一定要把
@Validated写在控制类上,否则不起作用。
@RestController
@RequestMapping
(
"/test"
)
@Validated
public class TestController {
@GetMapping(
"/validate")
@ResponseBody
public String validateParam(
@RequestParam(value =
"name", required =
false)
@NotNull(message =
"name
不能
为
空
")
@NotBlank(message =
"name
必
须
有
值
")
String name,
@RequestParam(value =
"age", required =
false)
@Max(value =
99, message =
"
不能大于
99
岁
") Integer age
){
System.
out.println(name);
return
"dddd";
}
}
|
|
|
统一异常处理
|
/**
*
全局异常捕获处理
*/
@RestControllerAdvice
public class ExceptionControllerAdvice {
private static final Logger
logger= LoggerFactory.
getLogger(ExceptionControllerAdvice.
class);
//
捕捉
shiro
的异常
@ExceptionHandler(ShiroException.
class)
public RetVO handle401() {
return RetFactory.
err(
401,
"
您没
有
权
限
访问
");
}
/**
*
捕捉Vo类入参校验异常
*
@param
ex
*
@return
*/
@ExceptionHandler(BindException.
class
)
public
Object handleBindGetException(HttpServletRequest request,BindException ex){
System.
out
.println(
"-------:"
+ex.getMessage());
BindingResult defaultMsg = ex.getBindingResult();
List<FieldError> errlist=defaultMsg.getFieldErrors();
String errs=
""
;
for
(FieldError err:errlist){
errs+=
"["
+err.getField()+
"]"
+err.getDefaultMessage()+
";"
;
}
if
(errs==
null
)errs=
""
;
if
(errs.length()!=0)errs=errs.substring(0,errs.length()-1);
errs=
"
输
入
参数错误
:"
+errs;
if
(isAjax(request)){
return
RetFactory.
err
(500,errs);
}
else
{
ModelAndView modelAndView =
new
ModelAndView();
modelAndView.setViewName(
"/error/500"
);
//
这里需要在
templates
文件夹下新建一个
/error/500.html
文件用作错误页面
modelAndView.addObject(
"errorMsg"
,errs);
return
modelAndView;
}
}
/**
*
捕捉单个参数入参校验异常,其实也可以不写,用Exception异常处理
*
@param
ex
*
@return
*/
@ExceptionHandler(ConstraintViolationException.
class
)
public
Object handleConstraintViolationException(HttpServletRequest request,ConstraintViolationException ex){
System.
out
.println(
"-------:"
+ex.getMessage());
System.
out
.println(
"-----isAjax--:"
+isAjax(request));
String errs=ex.getMessage();
if
(isAjax(request)){
return
RetFactory.
err
(500,errs);
}
else
{
ModelAndView modelAndView =
new
ModelAndView();
modelAndView.setViewName(
"/error/500"
);
//
这里需要在
templates
文件夹下新建一个
/error/500.html
文件用作错误页面
modelAndView.addObject(
"errorMsg"
,errs);
return
modelAndView;
}
}
//
捕捉其他所有异常
@ExceptionHandler(Exception.
class)
public Object globalException(HttpServletRequest request, HandlerMethod handlerMethod, Throwable ex) {
boolean isAjax=isAjax(request);
System.
out.println(
"
全局
异
常
拦
截:
globalException,isAjax:"+isAjax);
System.
out.println(ex.getMessage());
if(isAjax){
return RetFactory.
err(getStatus(request).value(),
"
访问
出
错
,无法
访问
: ");
//new Result(getStatus(request).value(), null,"
访问出错,无法访问
: " );
}
else {
ModelAndView modelAndView =
new ModelAndView();
modelAndView.setViewName(
"/error/500");
//
这里需要在
templates
文件夹下新建一个
/error/500.html
文件用作错误页面
modelAndView.addObject(
"errorMsg",ex.getMessage());
return modelAndView;
}
}
/**
*
判断是否是
Ajax
请求
*
*
@param
request
*
@return
*/
public boolean isAjax(HttpServletRequest request) {
return (request.getHeader(
"X-Requested-With") !=
null &&
"XMLHttpRequest".equals(request.getHeader(
"X-Requested-With").toString()));
}
// @ExceptionHandler(Exception.class)
// public Result globalException(HttpServletRequest request, Throwable ex) {
// return new Result(getStatus(request).value(),"
访问出错,无法访问
: " + ex.getMessage(),null);
// }
/**
*
获取响应状态码
*
@param
request
*
@return
*/
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute(
"javax.servlet.error.status_code");
if (statusCode ==
null) {
return HttpStatus.
INTERNAL_SERVER_ERROR;
}
return HttpStatus.
valueOf(statusCode);
}
/**
*
捕捉
404
异常
,
这个方法只在配置
* spring.mvc.throw-exception-if-no-handler-found=true
来后起作用
*
*/
@ResponseStatus(HttpStatus.
NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.
class)
public RetVO handle(HttpServletRequest request,NoHandlerFoundException e) {
return RetFactory.
err(
404,
"
没
有【
"+request.getMethod()+
"
】
"+request.getRequestURI()+
"
方法可以
访问
");
//new Result(404,null,"
没有【
"+request.getMethod()+"
】
"+request.getRequestURI()+"
方法可以访问
");
}
}
|
校验注解
|
|
问题
|
为什么注解单个参数不起作用
@GetMapping(
"/validate")
@ResponseBody
@Validated
public String validateParam(
@RequestParam(value =
"name", required =
false)
@NotNull(message =
"name
不能
为
空
")
@NotBlank(message =
"name
必
须
有
值
")
String name,
@RequestParam(value =
"age", required =
false)
@Max(value =
99, message =
"
不能大于
99
岁
") Integer age
){
System.
out.println(name);
return
"dddd";
}
|
|
|
知识点:
1、HttpServletRequest对象的Content-Type属性,一般情况下,Content-Type的值有以下两种:
Content-Type
|
含义
|
application/x-www-form-urlencoded;charser=utf-8
|
请求参数以form表单的形式提交
|
application/json;charset=utf-8
|
请求参数以json传的形式提交
|
Content-TYpe为application/x-www-form-urlencoded;charser=utf-8是jquery ajax、post等方法的默认行为,大多数的业务,采用这种方式就可以满足我们的需求。
本次请求传递的是json传,所以
2、jquery的JSON.stringify函数的含义:它会将前端参数转变为json传
后端开发人员需要了解:contentType: "application/json; charset=utf-8"
@RequestBody的含义:将json串转变为对象。