Spring MVC中@Controller和@RequestMapping註解使用

@Controller和@RequestMapping註解使用

RequestMapping 註解類型

1)方法級別註解

@RequestMapping(value = "/index/login")
public String login() {
/**
* login代表邏輯視圖名稱,需要根據Spring MVC配置
* 文件中internalResourceViewResolver的前綴和後綴找到對應的物理視圖
*/
return "login";
}

2)類級別註解

@RequestMapping("/index")
public class IndexController {
}

通過 @RequestParam 接收請求參數

@RequestMapping("/register")
/**
* 通過@RequestParam接收請求參數
*/
public String register(@RequestParam String uname,
    @RequestParam String upass, Model model) {
    if ("zhangsan".equals(uname) && "123456".equals(upass)) {
        logger.info("成功");
        return "login"; // 註冊成功,跳轉到 login.jsp
    } else {
        // 在register.jsp頁面上可以使用EL表達式取出model的uname值
        model.addAttribute("uname", uname);
        return "register"; // 返回 register.jsp
    }
}
@RequestMapping("/register")
public String register(@ModelAttribute("user") UserForm user) {
    if ("zhangsan".equals(uname) && "123456".equals(upass)) {
        logger.info("成功");
        return "login"; // 註冊成功,跳轉到 login.jsp
    } else {
        logger.info("失敗");
        // 使用@ModelAttribute("user")與model.addAttribute("user",user)的功能相同
        //register.jsp頁面上可以使用EL表達式${user.uname}取出ModelAttribute的uname值
        return "register"; // 返回 register.jsp
    }
}

Spring MVC應用@Autowired和@Service進行依賴註入

<context:component-scan base-package="service" />

通過 org.springframework.web.bind.annotation.ModelAttribute

註解類型可經常實現以下兩個功能:

1.綁定請求參數到實體對象(表單的命令對象)

@RequestMapping("/register")
public String register(@ModelAttribute("user") UserForm user) {
    if ("zhangsan".equals(uname) && "123456".equals(upass)) {
        logger.info("成功");
        return "login";
    } else {
        logger.info("失敗");
        return "register";
}

在上述代碼中“@ModelAttribute("user")UserForm user”語句的功能有兩個:

將請求參數的輸入封裝到 user 對象中。

創建 UserForm 實例。

以“user”為鍵值存儲在 Model 對象中,和“model.addAttribute("user",user)”語句的功能一樣。如果沒有指定鍵值,即“@ModelAttribute UserForm user”,那麼在創建 UserForm 實例時以“userForm”為鍵值存儲在 Model 對象中,和“model.addAtttribute("userForm", user)”語句的功能一樣。

2.註解一個非請求處理方法 

被 @ModelAttribute 註解的方法將在每次調用該控制器類的請求處理方法前被調用。這種特性可以用來控制登錄權限,當然控制登錄權限的方法有很多,例如攔截器、過濾器等。

攔截器的配置 

讓自定義的攔截器生效需要在 Spring MVC 的配置文件中進行配置,配置示例代碼如下:

<!-- 配置攔截器 -->
<mvc:interceptors>
    <!-- 配置一個全局攔截器,攔截所有請求 -->
    <bean class="interceptor.TestInterceptor" /> 
    <mvc:interceptor>
        <!-- 配置攔截器作用的路徑 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要攔截作用的路徑 -->
        <mvc:exclude-mapping path="" />
        <!-- 定義<mvc:interceptor>元素中,表示匹配指定路徑的請求才進行攔截 -->
        <bean class="interceptor.Interceptor1" />
    </mvc:interceptor>
    <mvc:interceptor>
        <!-- 配置攔截器作用的路徑 -->
        <mvc:mapping path="/gotoTest" />
        <!-- 定義在<mvc: interceptor>元素中,表示匹配指定路徑的請求才進行攔截 -->
        <bean class="interceptor.Interceptor2" />
    </mvc:interceptor>
</mvc:interceptors> 

在上述示例代碼中,<mvc:interceptors> 元素用於配置一組攔截器,其子元素 <bean> 定義的是全局攔截器,即攔截所有的請求。

<mvc:interceptor> 元素中定義的是指定路徑的攔截器,其子元素 <mvc:mapping> 用於配置攔截器作用的路徑,該路徑在其屬性 path 中定義。

如上述示例代碼中,path 的屬性值“/**”表示攔截所有路徑,“/gotoTest”表示攔截所有以“/gotoTest”結尾的路徑。如果在請求路徑中包含不需要攔截的內容,可以通過 <mvc:exclude-mapping> 子元素進行配置。

需要註意的是,<mvc:interceptor> 元素的子元素必須按照 <mvc:mapping…/>、<mvc:exclude-mapping…/>、<bean…/> 的順序配置。

@RequestMapping和Controller方法返回值

@RequestMapping

通過@RequestMapping註解可以定義不同的處理器映射規則。

1. URL路徑映射

@RequestMapping(value="/item") 或 @RequestMapping("/item") –當括號裡有多個屬性時,value=不可以省略。

value的值是數組,可以將多個url映射到同一個方法。

/**
 * 查詢商品列表
 * @return
 */
@RequestMapping(value = { "itemList", "itemListAll" })
public ModelAndView queryItemList() {
    // 查詢商品數據
    List<Item> list = this.itemService.queryItemList(); 
    // 創建ModelAndView,設置邏輯視圖名
    ModelAndView mv = new ModelAndView("itemList"); 
    // 把商品數據放到模型中
    mv.addObject("itemList", list);
    return mv;
}

2. 添加在類上面

在class上添加@RequestMapping(url)指定通用請求前綴,限制此類下的所有方法請求url必須以請求前綴開頭

可以使用此方法對url進行分類管理,如下圖:

此時需要進入queryItemList()方法的請求url為:http://127.0.0.1:8080/api/item/itemList.action

或者

http://127.0.0.1:8080/api/item/itemListAll.action

3.請求方法限定

除瞭可以對url進行設置,還可以限定請求進來的方法。不寫的話默認所有方法都可以。

(1)限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通過POST訪問則報錯:

HTTP Status 405 – Request method 'POST' not supported

例如:

@RequestMapping(value = "itemList",method = RequestMethod.POST)

(2)限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通過GET訪問則報錯:

HTTP Status 405 – Request method 'GET' not supported

(3)GET和POST都可以

@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})

Controller方法返回值

1. 返回ModelAndView –無敵的,帶著數據,返回視圖路徑

controller方法中定義ModelAndView對象並返回,對象中可添加model數據、指定view。

@RequestMapping(value = "/item/itemlist.action")
public ModelAndView itemList(){     
    // 從MySQL中查詢數據
    List<Items> list = itemService.selectItemsList(); 
    // 創建ModelAndView,用來存放數據和視圖
    ModelAndView mav = new ModelAndView();
    // 設置數據到模型中
    mav.addObject("itemList", list); //頁面上循環的是itemList
    // 設置視圖的路徑,需要設置視圖的物理地址
    //mav.setViewName("/WEB-INF/jsp/itemList.jsp");
    mav.setViewName("itemList"); //在springmvc.xml中替換掉默認的視圖解析器 
    return mav;
}

2. 返回void –數據通過形參 Model model 或者 ModelMap model,但是沒辦法return視圖。

如果需要返回視圖得通過request或response。這種比較適合ajax請求,但是給ajax返回數據得json格式數據。

在Controller方法形參上可以定義request和response,使用request或response指定響應結果:

(1)使用request轉發頁面,如下:

request.getRequestDispatcher("頁面路徑").forward(request, response);
request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

(2)可以通過response頁面重定向:

response.sendRedirect("url")
response.sendRedirect("/itemEdit.action");

(3)可以通過response指定響應結果,例如響應json數據如下:

response.getWriter().print("{\"abc\":123}");

代碼:

/**
 * 返回void測試
 *
 * @param request
 * @param response
 * @throws Exception
 */
@RequestMapping("queryItem")
public void queryItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 1 使用request進行轉發
    // request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,
    // response);
 
    // 2 使用response進行重定向到編輯頁面
    // response.sendRedirect("/springmvc-web2/itemEdit.action");
 
    // 3 使用response直接顯示
    response.getWriter().print("{\"abc\":123}");
}

【註意】:改映射@RequestMapping、改方法名、改方法形參、改返回值都需要重啟程序,其他不需要重啟。

3.返回字符串(官方推薦此種方式) –返回視圖路徑,數據通過形參 Model model 或者 ModelMap model

(1)邏輯視圖名

controller方法返回字符串可以指定邏輯視圖名,通過視圖解析器解析為物理視圖地址。

//指定邏輯視圖名,經過視圖解析器解析為jsp物理路徑:/WEB-INF/jsp/itemList.jsp
return "itemList";

示例代碼:

/**
 * 根據id查詢商品,綁定簡單數據類型
 *
 * @param id
 * @param model
 * @return
 */
@RequestMapping("/itemEdit.action")
public String queryItemById(Integer id, ModelMap model) { //不要用int,萬一傳進來一個long
    // 根據id查詢商品數據
    Items item = this.itemService.selectItemsById(id);
 
    // 把商品數據放在模型中
    model.addAttribute("item", item);
 
    return "editItem";
}

(2)Redirect重定向

Contrller方法返回字符串可以重定向到一個url地址。

如下商品修改提交後重定向到商品編輯頁面。

/**
  * 更新商品
  *
  * @param item
  * @return
  */
 @RequestMapping("updateItem")
 public String updateItemById(Items item) {
     // 更新商品
     this.itemService.updateItemById(item);
 
     // 修改商品成功後,重定向到商品編輯頁面
     // 重定向後瀏覽器地址欄變更為重定向的地址,
     // 重定向相當於執行瞭新的request和response,所以之前的請求參數都會丟失
     // 如果要指定請求參數,需要在重定向的url後面添加 ?itemId=1 這樣的請求參數
     return "redirect:/itemEdit.action?itemId=" + item.getId();
 }

(3)forward轉發

Controller方法執行後繼續執行另一個Controller方法

如下商品修改提交後轉向到商品修改頁面,修改商品的id參數可以帶到商品修改方法中。

/**
 * 更新商品
 *
 * @param item
 * @return
 */
@RequestMapping("updateItem")
public String updateItemById2(Items item) {
    // 更新商品
    this.itemService.updateItemById(item);
 
    // 修改商品成功後,重定向到商品編輯頁面
    // 重定向後瀏覽器地址欄變更為重定向的地址,
    // 重定向相當於執行瞭新的request和response,所以之前的請求參數都會丟失
    // 如果要指定請求參數,需要在重定向的url後面添加 ?itemId=1 這樣的請求參數
    // return "redirect:/itemEdit.action?itemId=" + item.getId();
 
    // 修改商品成功後,繼續執行另一個方法
    // 使用轉發的方式實現。轉發後瀏覽器地址欄還是原來的請求地址,
    // 轉發並沒有執行新的request和response,所以之前的請求參數都存在
    return "forward:/itemEdit.action"; 
}

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。 

推薦閱讀: