@RequestParam:綁定請(qǐng)求中的參數(shù);
@RequestHeader:綁定請(qǐng)求頭中的參數(shù)變量;
@CookieVariable:綁定Cookie中的參數(shù)變量;
上面三個(gè)注解擁有相同的參數(shù):
value:參數(shù)名稱,若未指定則默認(rèn)采用方法參數(shù)變量名;
prefix:參數(shù)名稱前綴,默認(rèn)為"";
defaultValue:指定參數(shù)的默認(rèn)值,默認(rèn)為"";
示例代碼:
@Controller @RequestMapping("/demo") public class DemoController { @RequestMapping("/param") public IView testParam(@RequestParam String name, @RequestParam(defaultValue = "18") Integer age, @RequestParam(value = "name", prefix = "user") String username, @RequestHeader(defaultValue = "BASIC") String authType, @CookieVariable(defaultValue = "false") Boolean isLogin) { System.out.println("AuthType: " + authType); System.out.println("IsLogin: " + isLogin); return View.textView("Hi, " + name + ", UserName: " + username + ", Age: " + age); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/param?name=webmvc&user.name=ymper
執(zhí)行結(jié)果:
控制臺(tái)輸出: AuthType: BASIC IsLogin: false 瀏覽器輸出: Hi, webmvc, UserName: ymper, Age: 18
@PathVariable:綁定請(qǐng)求映射中的路徑參數(shù)變量;
value:參數(shù)名稱,若未指定則默認(rèn)采用方法參數(shù)變量名;
示例代碼:
@Controller @RequestMapping("/demo") public class DemoController { @RequestMapping("/path/{name}/{age}") public IView testPath(@PathVariable String name, @PathVariable(value = "age") Integer age, @RequestParam(prefix = "user") String sex) { return View.textView("Hi, " + name + ", Age: " + age + ", Sex: " + sex); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/path/webmvc/20?user.sex=F
執(zhí)行結(jié)果:
Hi, webmvc, Age: 20, Sex: F
注意:基于路徑的參數(shù)變量必須是連續(xù)的,如:
正確:/path/{name}/{age}
錯(cuò)誤:/path/{name}/age/{sex}
@ModelBind:值對(duì)象參數(shù)綁定注解;
prefix:綁定的參數(shù)名稱前綴,可選參數(shù),默認(rèn)為"";
示例代碼:
public class DemoVO { @PathVariable private String name; @RequestParam private String sex; @RequestParam(prefix = "ext") private Integer age; // 省略Get和Set方法 } @Controller @RequestMapping("/demo") public class DemoController { @RequestMapping("/bind/{demo.name}") public IView testBind(@ModelBind(prefix = "demo") DemoVO vo) { String _str = "Hi, " + vo.getName() + ", Age: " + vo.getAge() + ", Sex: " + vo.getSex(); return View.textView(_str); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/bind/webmvc?demo.sex=F&demo.ext.age=20
執(zhí)行結(jié)果:
Hi, webmvc, Age: 20, Sex: F
@ParameterEscape:控制器方法參數(shù)轉(zhuǎn)義注解;
可以通過WebMVC模塊配置參數(shù)parameter_escape_order
設(shè)定是在控制器方法參數(shù)執(zhí)行驗(yàn)證之前還是之后執(zhí)行參數(shù)轉(zhuǎn)義動(dòng)作,參數(shù)取值范圍為before
或after
,默認(rèn)為after
即參數(shù)驗(yàn)證之后進(jìn)行轉(zhuǎn)義;
scope:字符串參數(shù)轉(zhuǎn)義范圍,默認(rèn)為Type.EscapeScope.DEFAULT;
- 取值范圍包括:JAVA, JS, HTML, XML, SQL, CSV, DEFAULT;
- 默認(rèn)值DEFAULT,它完成了對(duì)SQL和HTML兩項(xiàng)轉(zhuǎn)義;
skiped:通知父級(jí)注解當(dāng)前方法或參數(shù)的轉(zhuǎn)義操作將被忽略,默認(rèn)為false;
processor:自定義字符串參數(shù)轉(zhuǎn)義處理器;
- 可以通過IParameterEscapeProcessor接口實(shí)現(xiàn)自定義的轉(zhuǎn)義邏輯;
- 默認(rèn)實(shí)現(xiàn)為DefaultParameterEscapeProcessor;
示例代碼一:
@Controller @RequestMapping("/demo") @ParameterEscape public class DemoController { @RequestMapping("/escape") public IView testEscape(@RequestParam String content, @ParameterEscape(skiped = true) @RequestParam String desc) { System.out.println("Content: " + content); System.out.println("Desc: " + desc); return View.nullView(); } } // 或者:(兩段代碼執(zhí)行結(jié)果相同) @Controller @RequestMapping("/demo") public class DemoController { @RequestMapping("/escape") @ParameterEscape public IView testEscape(@RequestParam String content, @ParameterEscape(skiped = true) @RequestParam String desc) { System.out.println("Content: " + content); System.out.println("Desc: " + desc); return View.nullView(); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/escape?content=<p>content$<br><script>alert("hello");</script></p>&desc=<script>alert("hello");</script>
執(zhí)行結(jié)果:(控制臺(tái)輸出)
Content: <p>content$<br><script>alert("hello");</script></p> Desc: <script>alert("hello");</script>
示例一說明:
- 由于控制器類被聲明了@ParameterEscape注解,代表整個(gè)控制器類中所有的請(qǐng)求參數(shù)都需要被轉(zhuǎn)義,因此參數(shù)content的內(nèi)容被成功轉(zhuǎn)義;
- 由于參數(shù)desc聲明的@ParameterEscape注解中skiped值被設(shè)置為true,表示跳過上級(jí)設(shè)置,因此參數(shù)內(nèi)容未被轉(zhuǎn)義;
示例代碼二:
@Controller @RequestMapping("/demo") @ParameterEscape public class DemoController { @RequestMapping("/escape2") @ParameterEscape(skiped = true) public IView testEscape2(@RequestParam String content, @ParameterEscape @RequestParam String desc) { System.out.println("Content: " + content); System.out.println("Desc: " + desc); return View.nullView(); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/escape2?content=<p>content$<br><script>alert("hello");</script></p>&desc=<script>alert("hello");</script>
執(zhí)行結(jié)果:(控制臺(tái)輸出)
Content: <p>content$<br><script>alert("hello");</script></p> Desc: <script>alert("hello");</script>
示例二說明:
- 雖然控制器類被聲明了@ParameterEscape注解,但控制器方法通過skiped設(shè)置跳過轉(zhuǎn)義,這表示被聲明的方法參數(shù)內(nèi)容不進(jìn)行轉(zhuǎn)義操作,因此參數(shù)content的內(nèi)容未被轉(zhuǎn)義;
- 由于參數(shù)desc聲明了@ParameterEscape注解,表示該參數(shù)需要轉(zhuǎn)義,因此參數(shù)內(nèi)容被成功轉(zhuǎn)義;
注意:當(dāng)控制器類和方法都聲明了@ParameterEscape注解時(shí),則類上聲明的注解將視為無效;
單例控制器與非單例控制器的區(qū)別:
基于以上描述,非單例控制器是可以通過類成員來接收請(qǐng)求參數(shù),示例代碼如下:
@Controller(singleton = false) @RequestMapping("/demo") public class DemoController { @RequestParam private String content; @RequestMapping("/sayHi") public IView sayHi(@RequestParam String name) { return View.textView("Hi, " + name + ", Content: " + content); } }
通過瀏覽器訪問URL測試:
http://localhost:8080/demo/sayHi?name=YMPer&content=Welcome!
此示例代碼的執(zhí)行結(jié)果:
Hi, YMPer, Content: Welcome!
注意:在單例模式下,WebMVC模塊將忽略為控制器類成員賦值,同時(shí)也建議在單例模式下不要使用成員變量做為參數(shù),在并發(fā)多線程環(huán)境下會(huì)發(fā)生意想不到的問題??!
更多建議: