控制器參數(shù)(Parameter)

2018-12-24 22:46 更新

WebMVC模塊不但讓編寫控制器變得非常簡單,處理請求參數(shù)也變得更加容易!WebMVC會根據(jù)控制器方法參數(shù)或類成員的注解配置,自動轉(zhuǎn)換與方法參數(shù)或類成員對應的數(shù)據(jù)類型,參數(shù)的綁定涉及以下注解:

基本參數(shù)注解
  • @RequestParam:綁定請求中的參數(shù);

  • @RequestHeader:綁定請求頭中的參數(shù)變量;

  • @CookieVariable:綁定Cookie中的參數(shù)變量;

上面三個注解擁有相同的參數(shù):

value:參數(shù)名稱,若未指定則默認采用方法參數(shù)變量名;

prefix:參數(shù)名稱前綴,默認為"";

defaultValue:指定參數(shù)的默認值,默認為"";

示例代碼:

    @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í)行結果:

    控制臺輸出:
    AuthType: BASIC
    IsLogin: false

    瀏覽器輸出:
    Hi, webmvc, UserName: ymper, Age: 18
特別的參數(shù)注解
  • @PathVariable:綁定請求映射中的路徑參數(shù)變量;

    value:參數(shù)名稱,若未指定則默認采用方法參數(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í)行結果:

    Hi, webmvc, Age: 20, Sex: F
    

    注意:基于路徑的參數(shù)變量必須是連續(xù)的,如:

    • 正確:/path/{name}/{age}

    • 錯誤:/path/{name}/age/{sex}

  • @ModelBind:值對象參數(shù)綁定注解;

    prefix:綁定的參數(shù)名稱前綴,可選參數(shù),默認為"";

    示例代碼:

    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í)行結果:

    Hi, webmvc, Age: 20, Sex: F
    
  • @ParameterEscape:控制器方法參數(shù)轉(zhuǎn)義注解;

    可以通過WebMVC模塊配置參數(shù)parameter_escape_order設定是在控制器方法參數(shù)執(zhí)行驗證之前還是之后執(zhí)行參數(shù)轉(zhuǎn)義動作,參數(shù)取值范圍為beforeafter,默認為after即參數(shù)驗證之后進行轉(zhuǎn)義;

    scope:字符串參數(shù)轉(zhuǎn)義范圍,默認為Type.EscapeScope.DEFAULT;

    • 取值范圍包括:JAVA, JS, HTML, XML, SQL, CSV, DEFAULT;
    • 默認值DEFAULT,它完成了對SQL和HTML兩項轉(zhuǎn)義;

    skiped:通知父級注解當前方法或參數(shù)的轉(zhuǎn)義操作將被忽略,默認為false;

    processor:自定義字符串參數(shù)轉(zhuǎn)義處理器;

    • 可以通過IParameterEscapeProcessor接口實現(xiàn)自定義的轉(zhuǎn)義邏輯;
    • 默認實現(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í)行結果相同)
    
    @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í)行結果:(控制臺輸出)

    Content: &lt;p&gt;content$&lt;br&gt;&lt;script&gt;alert(&quot;hello&quot;);&lt;/script&gt;&lt;/p&gt;
    Desc: <script>alert("hello");</script>
    

    示例一說明:

    • 由于控制器類被聲明了@ParameterEscape注解,代表整個控制器類中所有的請求參數(shù)都需要被轉(zhuǎn)義,因此參數(shù)content的內(nèi)容被成功轉(zhuǎn)義;
    • 由于參數(shù)desc聲明的@ParameterEscape注解中skiped值被設置為true,表示跳過上級設置,因此參數(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í)行結果:(控制臺輸出)

    Content: <p>content$<br><script>alert("hello");</script></p>
    Desc: &lt;script&gt;alert(&quot;hello&quot;);&lt;/script&gt;
    

    示例二說明:

    • 雖然控制器類被聲明了@ParameterEscape注解,但控制器方法通過skiped設置跳過轉(zhuǎn)義,這表示被聲明的方法參數(shù)內(nèi)容不進行轉(zhuǎn)義操作,因此參數(shù)content的內(nèi)容未被轉(zhuǎn)義;
    • 由于參數(shù)desc聲明了@ParameterEscape注解,表示該參數(shù)需要轉(zhuǎn)義,因此參數(shù)內(nèi)容被成功轉(zhuǎn)義;

    注意:當控制器類和方法都聲明了@ParameterEscape注解時,則類上聲明的注解將視為無效;

非單例控制器的特殊用法

單例控制器與非單例控制器的區(qū)別:

  • 單例控制器類在WebMVC模塊初始化時就已經(jīng)實例化;
  • 非單例控制器類則是在每次接收到請求時都將創(chuà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í)行結果:

Hi, YMPer, Content: Welcome!

注意:在單例模式下,WebMVC模塊將忽略為控制器類成員賦值,同時也建議在單例模式下不要使用成員變量做為參數(shù),在并發(fā)多線程環(huán)境下會發(fā)生意想不到的問題!!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號