springboot(四)-SpringMVC

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 >
< html xmlns: th = " http://www.thymeleaf.org " >
< 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
  }
}
仅处理request的header中包含了指定“Refer”请求头和对应值为“ http://www.ifeng.com/ ”的请求;
 
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>
< html lang= "en" xmlns: th = " http://www.thymeleaf.org ">
< 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()+" 方法可以访问 ");
}
}
校验注解
  • @AssertFalse 所注解的元素必须是Boolean类型,且值为false
  • @AssertTrue 所注解的元素必须是Boolean类型,且值为true
  • @DecimalMax 所注解的元素必须是数字,且值小于等于给定的值
  • @DecimalMin 所注解的元素必须是数字,且值大于等于给定的值
  • @Digits 所注解的元素必须是数字,且值必须是指定的位数
  • @Future 所注解的元素必须是将来某个日期
  • @Max 所注解的元素必须是数字,且值小于等于给定的值
  • @Min 所注解的元素必须是数字,且值小于等于给定的值
  • @Range 所注解的元素需在指定范围区间内
  • @NotNull 所注解的元素值不能为null
  • @NotBlank 所注解的元素值有内容
  • @Null 所注解的元素值为null
  • @Past 所注解的元素必须是某个过去的日期
  • @PastOrPresent 所注解的元素必须是过去某个或现在日期
  • @Pattern 所注解的元素必须满足给定的正则表达式
  • @Size 所注解的元素必须是String、集合或数组,且长度大小需保证在给定范围之内
  • @Email 所注解的元素需满足Email格式
问题
为什么注解单个参数不起作用
 
@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串转变为对象。
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值