1. 程式人生 > >SpringMVC框架(1)之(1.3 註解開發&Controller方法返回值)

SpringMVC框架(1)之(1.3 註解開發&Controller方法返回值)

一、 註解開發基礎:

1. @RequestMapping 註解(在Controller類上或方法上,用於指定 url和請求方式):
1. 設定方法對應的URL(一個方法對應一個URL);
2. 設定請求的根路徑;(eg:http:// localhost:8080/project/book/deleteBook)
3. 限制請求方式: GET/POST
@RequestMapping(value="/editItems",method=RequestMethod.GET/POST)

2. @RequestParam 註解(在方法的引數上,用於引數繫結):
如果 request請求引數與 Controller方法中的形參名一致,介面卡自動進行引數繫結;
如果不一致,使用@RequestParam 註解 value屬性

指明請求引數名;required屬性 預設為 true,若沒有引數則報錯;defaultValue屬性 設定預設值;(即item_id=1)(eg:下 3.1 ItemsController.java
public void editItems(HttpServletRequest request,HttpServletResponse response, @RequestParam(value=“item_id”,required=true,defaultValue=“1”) Integer id ) throws Exception);
3. @ModelAttribute 註解(資料回顯;① 可用於方法的引數上,用於引數繫結,表示將請求的 POJO資料放到 model中; ② 用於方法上,將公用的取資料的方法返回值傳到頁面,不需要在每個 Controller方法中通過 Model傳資料。):

1.需求:表單提交出現錯誤,重新回到表單,使用者填寫的資料再次回顯在頁面;
① 簡單型別資料回顯: 形參-Model;
② POJO型別資料回顯:
        方法一:Model(eg:model.addAttribute"item",itemsCustom);)
        方法二:使用註解 @ModelAttribute(value=“item”),作用:將請求的POJO資料放入到 Model中進行回顯,value指明 JSP頁面用於顯示時所用的 key
如果形參名與 JSP頁面中的 key相同,@ModelAttribute註解可以省略;

2.需求:按照類別查詢(eg:3. itemsList.jsp 頁面中新增類別顯示)。
@ModelAttribute(value=“item”) 將方法返回值傳到頁面,將公用的取資料的方法返回值傳到頁面
優點:不需要用在每個 Controller方法中通過Model傳資料
[email protected] 註解:(用於Controller中方法的引數上,表示請求型別是 JSON格式資料;如果不是 JSON格式資料,則無需說明)將請求的 JSON資料轉成 JAVA物件;
4’[email protected]註解:(在 Ajax時,用於Controller中相應的方法上,方法可返回 POJO物件和 List集合; 用在方法的返回型別引數前,表示返回即響應 JSON格式資料;)將 JAVA物件轉成 JSON資料輸出;
eg:

//請求 JSON,響應 JSON
@RequestMapping("/requestJson")
	public @ResponseBody ItemsCustom requestJson(@RequestBody ItemsCustom itemsCustom)throws Exception{
		return itemsCustom;
	}
//請求 Key/Value,響應 JSON
	@RequestMapping("/responseJson")
	public @ResponseBody ItemsCustom responseJson(ItemsCustom itemsCustom)throws Exception{
		return itemsCustom;
	}

二、 Controller方法返回值:

1. ModelAndView

2. 返回字串:(如果Controller返回jsp頁面,方法返回值為字串,則為最終的邏輯檢視名,模型資料填充在 Model model)(eg:3.1 ItemsController.java中
① public String editItems(Model model) throws Exception;
model.addAttribute(“item”,itemsCustom);
③ return “editItems”;
);

3.返回 void(如果使用request轉向頁面,指定完整路徑)
① public void editItems( HttpServletRequest request,HttpServletResponse response ,Integer id) throws Exception;(此處用 Integer包裝類,不用 int,因為 int無法傳空值,若用 int則傳空值時會報錯;)
request.setAttribute(“item”,itemsCustom);
③ request.getRequestDispatcher("/WEB-INF/jsp/editItems.jsp").forward(request,response);

4.redirect 重定向(方法返回值String “redirect:url”)
① public String editItems(Model model) throws Exception;
return “redirect:queryItems.action”;

5.forward 轉發(方法返回值String “forward:url”)
① public String editItems(Model model) throws Exception;
return “forward:queryItems.action”;

三、 引數繫結過程:

早期SpringMVC是使用PropertyEditor屬性編輯器進行引數繫結(僅支援字串傳入);後期使用Convert轉換器進行引數繫結(支援任意資料型別轉換);
介面卡 ——>Handler(以方法為單位進行編寫,方法形參);

預設支援的引數型別:
HttPServletRequest、HttpServletResponse、HttpSession、Model

 

需求:商品資訊修改

1. 操作流程:

1.在商品列表頁面中點選修改按鈕;
2.開啟商品修改頁面,顯示當前商品資訊;
    (根據商品 ID查詢)
3.修改商品資訊,點選提交;
    (更新商品資訊)

【1. mapper:】 使用逆向工程生成(ItemsMapper.xml、ItemsMapper.java);
【2. service:】
【3. controller:】
【4. jsp:】

 

【2. service:】
2.1 ItemsService.java
(介面:更新商品資訊方法中:id:要修改的商品的 id、itemsCustom:要修改的商品;)

public interface ItemsService{
	//查詢所有商品
	public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;
	//根據ID查詢商品
	public ItemsCustom findItemsById(int id)throws Exception;
	//更新商品資訊
	public void updateItems(Integer id,ItemsCustom itemsCustom)throws Exception;
}

2.2 ItemsServiceImpl.java
(查詢所有商品的方法是在 itemsCustomMapper中; 根據ID查詢商品、更新商品資訊兩個方法是在 itemsMapper.java(逆向工程自動生成的方法)中,所以也要注入 itemsMapper; 根據ID查詢商品的方法中 itemsMapper.selectByPrimaryKey返回的是 Items型別,方法本身要返回的是 ItemsCustom型別:可以強轉,但當需要能查詢其他相關資訊時,強轉不適合,所以:先new、再呼叫方法將 items屬性的值 copy到 itemsCustom中;)

public class ItemsServiceImpl implements ItemsService{
	@Autowired 
	private ItemsCustomMapper itemsCustomMapper;
	@Autowired 
	private ItemsMapper itemsMapper;

	public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)throws Exception{
		return itemsCustomMapper.findItemsList(itemsQueryVo); //查詢所有商品
	}
	public ItemsCustom findItemsById(int id)throws Exception{
		Items items=itemsMapper.selectByPrimaryKey(id);
		//需求:能查詢其他相關資訊,強轉不適合;所以:先new、再將items屬性的值copy到itemsCustom中
	    ItemsCustom itemsCustom=new ItemsCustom();
	    BeanUtils.copyProperties(items,itemsCustom);
		return itemsCustom;
	}
	public void updateItems(Integer id,ItemsCustom itemsCustom)throws Exception{
		//寫業務程式碼:如希望對關鍵業務資料進行非空校驗.引數要傳一個id值(是希望能修改的商品的id)
		if(id=null){
			//拋異常,提示呼叫介面的使用者,id不能為空
		}
		itemsMapper.updateByPrimaryKey(itemsCustom);
	}
}

itemsCustom.java

public class ItemsCustom extends Items{
}

 

【3. controller:】
3.1 ItemsController.java
(通過@RequestMapping註解的 url請求modelAndView.setViewName("?")中的 ?;jsp頁面拿到modelAndView .addObject (“item”,itemsCustom)中的 item;)

@Controller
@RequestMapping("/items")
public class ItemsController{
	@Autowired
	private ItemsService itemsService;

	@RequestMapping("/queryItems")
	public ModelAndView queryItems() throws Exception{
		//呼叫service查詢出的商品,要用到itemsService
		List<ItemsCustom> itemList=itemsService.findItemsList();
		ModelAndView modelAndView=new ModelAndView();
		modelAndView.addObject("items",itemsList);//jsp頁面拿到items
		modelAndView.setViewName("itemsList");
		return modelAndView;
	}
	/* @RequestMapping(value="/editItems",method=RequestMethod.GET)
	public ModelAndView editItems() throws Exception{
		//通過id查詢商品
		ItemsCustom itemsCustom=itemsService.findItemById(1);
		ModelAndView modelAndView=new ModelAndView();
		modelAndView.addObject("item",itemsCustom);//jsp頁面拿到item
		modelAndView.setViewName("editItems");
		return modelAndView;
	}*/
	/* @RequestMapping(value="/editItems",method=RequestMethod.GET)
	public String editItems(Model model) throws Exception{
		//通過id查詢商品
		ItemsCustom itemsCustom=itemsService.findItemById(1);
		model.addAttribute("item",itemsCustom);
		return "editItems";
	}*/
	/* @RequestMapping(value="/editItems",method=RequestMethod.GET)
	public void editItems(HttpServletRequest request,HttpServletResponse response,
		@RequestParam(value="item_id",required=true,defaultValue="1")
		Integer id) throws Exception{
		//通過id查詢商品
		ItemsCustom itemsCustom=itemsService.findItemById(id);
		request.setAttribute("item",itemsCustom);
		// 如果使用request轉向頁面,要指定完整路徑
		request.getRequestDispatcher("/WEB-INF/jsp/editItems.jsp").forward(request,response);
	} */
	/* @RequestMapping(value="/editItems",method=RequestMethod.GET)
	public String editItems(Model model) throws Exception{
		return "redirect:queryItems.action"; //重定向
		//return "forward:queryItems.action"; //轉發
	}  */
}

 

【4. jsp:】
4.1 itemsList.jsp
(查詢到 items,遍歷出來;再根據 item.id 修改;)

<body>
    <table width="100%" border="1">
       <tr><td>商品名稱</td><td>商品價格</td><td>商品描述</td><td>操作</td></tr>
       <c:forEach items="${items}" var="item">
          <tr><td>${item.name}</td><td>${item.price}</td><td>${item.detail}</td>
              <td>
                <a href="${pageContext.request.contextPath}/items/editItems.action?id=${item.id}">修改</a>
              </td>
          </tr>
       </c:forEach>
    </table>
</body>

4.2 editItems.jsp

<body>
  <form action="">
  <table>
     <tr><td>商品名稱:</td>
         <td><input type="text" name="name" value="${item.name}"></td></tr>
     <tr><td>商品價格:</td>
         <td><input type="text" name="name" value="${item.price}"></td></tr>
     <tr><td>商品描述:</td>
         <td><input type="text" name="name" value="${item.detail}"></td></tr>
     <tr><td colspan="2" align="center"><input type="submit" value="提交"/></td></tr>
  </table>
  </form>
</body>

 

3. @ModelAttribute註解(資料回顯;在方法的引數上,用於引數繫結,表示將請求的 POJO資料放到 model中):
簡單型別資料回顯:1. ItemsController.java 中 public String editItemsSubmit()方法中將 id新增到 model中(model.addAttribute(“id”,id)); 2. editItems.jsp 中 hidden隱藏域中 value="$ {id}" 得到 id。但頁面顯示的其他欄位name、price、createtime、detail(如value=" $ {item.detail}")等一開始是從 public String editItems()方法的 model中得到的,是 item,所以要想從一開始進入此頁面 id也顯示,則隱藏域中 value="$ {item.id}";若想 jsp頁面隱藏域顯示 value="$ {id}",則 public String editItems()方法中將 id新增到 model(即model.addAttribute(“id”,id); )
POJO型別資料回顯:方法一:1. ItemsController.java 中 public String editItemsSubmit()方法中將 itemsCustom新增到 model中(即model.addAttribute(“item”,itemsCustom),key為 item,value為 itemsCustom) 方法二:1. ItemsController.java 中 public String editItemsSubmit()方法中直接將引數 ItemsCustom itemsCustom改為 ItemsCustom item,直接新增 @ModelAttribute 註解(表示將此形參 item新增到Model中),再註釋掉 /* model.addAttribute(“item”,itemsCustom); */;
若將 1. ItemsController.java 中 public String editItemsSubmit()方法中引數(ItemsCustom item)改為(ItemsCustom itemsCustom)且去掉@ModelAttribute註解; public String editItems()方法中 model.addAttribute(“item”,itemsCustom)改為 model.addAttribute(“itemsCustom”,itemsCustom);
2. editItems.jsp 中 value="$ {item.xx}“改為 value=”$ {itemsCustom.xx}"

1. ItemsController.java

@Controller
@RequestMapping("/items")
public class ItemsController{
	@Autowired
	private ItemsService itemsService;
		
	@ModelAttribute(value="itemsType") //表示將itemsType新增到model中
	public Map<String,String> getItemsType(){
		Map<String,String> itemsType=new HashMap<String,String>();
		itemsType.put("001","數碼");
		itemsType.put("002","服裝");
		return itemsType;
	}	
	@RequestMapping(value="/editItems",method=RequestMethod.GET)
	public String editItems(Model model,Integer id) throws Exception{
		model.addAttribute("id",id);
		ItemsCustom itemsCustom=itemsService.findItemById(id);
		/*model.addAttribute("item",itemsCustom);*/
		model.addAttribute("itemsCustom",itemsCustom);
		return "editItems";
	}

	@RequestMapping(value="/editItemsSubmit")
	public String editItemsSubmit(Model model,Integer id,
	/*ItemsCustom itemsCustom*/ 
	/*@ModelAttribute(value="item") ItemsCustom item*/
	ItemsCustom itemsCustom) throws Exception{
		model.addAttribute("id",id);
		// model.addAttribute("item",itemsCustom);
		return "editItems";
	}  
}

2. editItems.jsp

<body>
  <form action="${pageContext.request.contextPath}/items/editItemsSubmit.action" method="post">
  <input type="hidden" name="id" value="${id}"/>
  <table>
     <tr><td>商品名稱:</td>
         <td><input type="text" name="name" value="${item/itemsCustom.name}"></td></tr>
     <tr><td>商品價格:</td>
         <td><input type="text" name="price" value="${item/itemsCustom.price}"></td></tr>
     <tr><td>訂購日期:</td>
         <td><input type="text" name="createtime" value="<fmt:formatDate value='${item/itemsCustom.createtime}' pattern="yyyy-MM-dd"/>"></td></tr>
     <tr><td>商品描述:</td>
         <td><input type="text" name="detail" value="${item/itemsCustom.detail}"></td></tr>
     <tr><td colspan="2" align="center"><input type="submit" value="提交"/></td></tr>
  </table>
  </form>
</body>

 

3. itemsList.jsp 頁面中新增查詢按鈕,以及下拉框,點選下拉框時內容顯示類別;1. ItemsController.java 類中新增 public Map<String,String> getItemsType() 方法,方法上新增 @ModelAttribute(value=“itemsType”) 註解,value指明 key;)
3. itemsList.jsp

<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<body>
    <table width="100%" border="1">
    <tr><td><input type="button" value="查詢"/></td>
	    <td colspan="3">
		    <select>
			    <c:forEach items="${itemsType}" var="itemsType">
			    	<option value="${itemsType.key}">${itemsType.value}</option>
			    </c:forEach>
		    </select>
	    </td></tr>
       <tr><td>商品名稱</td><td>商品價格</td><td>訂購日期</td><td>商品描述</td><td>操作</td></tr>
       <c:forEach items="${items}" var="item">
          <tr><td>${item.name}</td>
              <td>${item.price}</td>
              <td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd"/></td>
              <td>${item.detail}</td>
              <td>
                <a href="${pageContext.request.contextPath}/items/editItems.action?id=${item.id}">修改</a>
              </td>
          </tr>
       </c:forEach>
    </table>
</body>