SpringMVC(三)處理器方法形參繫結(繫結陣列、集合)、異常處理器、controller方法返回值

z1340954953發表於2018-06-11

高階引數繫結

* 繫結陣列

當表單提交多個屬性相同的引數,例如,選中的多個CheckBox,提交的是陣列。

<form action="${pageContext.request.contextPath}/insertItem.action" method="post">
 編號:<input type="text" name="item.id" ><br/>
 名稱:<input type="text" name="item.name" ><br/>
 出廠時間:<input type="text" name="item.time" ><br/>
 備註:<input type="text" name="item.remark" ><br/>
顏色:
<input type="checkbox" name="color" value="1">黑色
<input type="checkbox" name="color" value="2">天空藍
<input type="checkbox" name="color" value="3">玫瑰金<br/>
 <input type="submit" value="提交">

對映器方法裡面使用陣列進行接收

* 第一種方式,直接在方法形參裡面,定義一個同名的陣列,接收

@RequestMapping("/insertItem.action")
	public String insertItem(QueryVo queryVo,Integer[] color){
		return "itemList";
	}


*  第二種方法,將陣列封裝到QueryVO中。

public class QueryVo {
	private Item item;
	private Integer[] color;
	public Integer[] getColor() {
		return color;
	}
	public void setColor(Integer[] color) {
		this.color = color;
	}
	public Item getItem() {
		return item;
	}
	public void setItem(Item item) {
		this.item = item;
	}
}

@RequestMapping("/insertItem.action")
	public String insertItem(QueryVo queryVo){
		return "itemList";
	}

* 將表單的資料繫結到List

需求:批量修改商品的資訊

1. 定義pojo

public class QueryVo {
	private Item item;
	private Integer[] color;
	//接受多個商品資訊pojo
	private List<Item> list;
	public List<Item> getList() {
		return list;
	}
	public void setList(List<Item> list) {
		this.list = list;
	}
	public Integer[] getColor() {
		return color;
	}
	public void setColor(Integer[] color) {
		this.color = color;
	}
	public Item getItem() {
		return item;
	}
	public void setItem(Item item) {
		this.item = item;
	}
}

2. 定義介面,這裡需要注意

<form action="${pageContext.request.contextPath}/editItems.action">
	<table cellpadding="0" border="1" cellspacing="0" >
	<thead>
		<tr style="text-align: center;">
			<th>編號</th>
			<th>名稱</th>
			<th>時間</th>
			<th>備註</th>
			<th>操作</th>
		</tr>
	</thead>
	<tbody>
		<c:if test="${not empty list }">
			<c:forEach items="${list }" var="obj" varStatus="s">
				<tr style="text-align: center;">
					<td>
					<input type="text" name="list['${s.index}'].id" value="${obj['id']}">
					</td>
					<td>
					<input type="text" name="list['${s.index}'].name" value="${obj.name }">
					</td>
					<td>
					<input type="text" name="list['${s.index}'].time" value='<fmt:formatDate pattern="yyyyMMdd HH:mm:ss" value="${obj.time }"/>'>
					</td>
					<td>
					<input type="text" name="list['${s.index}'].remark" value="${obj.remark }">
					</td>
					<td><a style="color: red;" href="">修改</a></td>
				</tr>
			</c:forEach>
		</c:if>
		</tbody>
	</table>
	<input type="submit" value="提交">
</form>	

name屬性,定義為list[索引].屬性名的形式

另外,關於jstl裡面foreach元素迭代的補充說明,begin、end、step屬性表示起始序號,結束序號,跳躍步伐

屬性:varStatus = "s"

${s.index} 輸出行號,從0開始

${s.count} 輸出行號,從1開始

${s.first} 判斷是否是集合中的第一項,true/false

${s.last} 判斷是否是集合中的最後一項 true/false

3. 定義對映器方法

@RequestMapping("/editItems.action")
	public String editItems(QueryVo qv){

測試,打個斷點看下


@RequestMapping註解

URL 路徑對映

* 新增在類上,限定對映路徑

@Controller
@RequestMapping("item")
public class ItemController {

之前:http://localhost:8080/工程名/itemList.action

加上類對映限制後,訪問對映方法的路徑改為  http://localhost:8080/工程名/item/itemList.action

* 請求方法限定

一個對映器方法可以處理多個對映路徑,並限制方法訪問型別

限定為get請求

@Controller
@RequestMapping("item")
public class ItemController {
	@RequestMapping(value={"/itemList.action","/itemInfo.action"},method=RequestMethod.GET)
	public String itemList(
			HttpServletRequest request,
			Model model,
			@RequestParam(value="itemId",required=false,defaultValue="")
			Integer id
			){

Controller方法返回值

1. 返回ModelAndView 

2. 返回void

形參上獲取request,response,轉發或者重定向,寫回資料

3. 字串

   3.1 邏輯檢視名,資料仍然封裝到model中

@RequestMapping(value={"/itemList.action","/itemInfo.action"},method=RequestMethod.GET)
	public String itemList(
			HttpServletRequest request,
			Model model,
			@RequestParam(value="itemId",required=false,defaultValue="")
			Integer id
			){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
		List<Item> list = new ArrayList<Item>();
		list.add(new Item(1, "小米1", new Date(), "千元神機!"));
		list.add(new Item(2, "小米2", new Date(), "千元神機!"));
		list.add(new Item(3, "小米3", new Date(), "千元神機!"));
		list.add(new Item(4, "小米4", new Date(), "千元神機!"));
		list.add(new Item(5, "小米5", new Date(), "千元神機!"));
		model.addAttribute("list", list);
		return "itemList";
	}

3.2 Redirect重定向

在Controller方法中重定向到一個新的URL中,進行重定向,請求中攜帶的引數丟失,如果想要攜帶引數適用?進行引數拼接

@RequestMapping("/editItems.action")
	public String editItems(QueryVo qv){
		List<Item>list = qv.getList();
		if(list!=null){
			for(int i =0 ;i<list.size();i++){
				System.out.println(list.get(i).getId());
			}
		}
		return "redirect:itemList.acition?id=1";
	}

3.3 轉發,從一個Controller方法轉發到另一個Controller方法

因為轉發的特點,response和request都是同一個。轉發後的處理器方法中可以獲取前一個處理器方法中獲取到的引數

,如果在請求中的引數名稱和方法中的形參不一致,可以使用註解@Requestparam進行引數繫結

@RequestMapping("/editItems.action")
	public String editItems(Item item){
		//.......
		return "forward:queryItem.action";
	}
	@RequestMapping("/queryItem.action")
	public String queryItem(@RequestParam(value="id")Integer itemId){
		//TODO
		return "";
	}

SpringMVC的異常處理器

系統中的異常分為兩類,預期異常和執行時異常,預期異常可以try catch進行捕獲,執行時異常只能多測試,減少發生。

SpringMVC中的異常解決方案,將dao、service、controller的異常向上丟擲,不進行捕獲,交由SpringMVC的前端控制器,再由前端控制器交給異常處理器統一處理。

自定義異常類:

/**
 * 自定義異常
 * @author zhouy
 *
 */
public class BusiException extends Exception{
	private static final long serialVersionUID = -1175358759985574587L;
	//異常資訊
	private String message;
	public BusiException() {
		super();
	}
	public BusiException(String message){
		super(message);
		this.message = message;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
}

異常處理器:

public class BusinessExceptionHandler implements HandlerExceptionResolver {
	@Override
	public ModelAndView resolveException(
			HttpServletRequest request,
			HttpServletResponse response, Object paramObject,
			Exception exception) {
		String message = "";
		if(exception instanceof BusiException){
			BusiException be = (BusiException) exception;
			message = be.getMessage();
		}else{
			//否則從堆疊中獲取異常資訊
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			exception.printStackTrace(pw);
			message = sw.toString();
		}
		//...處理異常資訊,傳送簡訊。。。
		//跳轉到異常頁面
		ModelAndView mav = new ModelAndView();
		mav.addObject("msg", message);
		mav.setViewName("error");
		return mav;
	}
}

在springMVC.xml中配置全域性異常處理器

<!-- 全域性異常處理器 -->
<bean id="beh" class="cn.bing.exception.BusinessExceptionHandler"></bean>

測試一下:

定義頁面:

<body>
	<h1>出了點小問題!!!!</h1>
	<h2>${msg}</h2>
</body>

修改下controller方法:

@Controller
@RequestMapping("item")
public class ItemController {
	@RequestMapping(value={"/itemList.action","/itemInfo.action"},method=RequestMethod.GET)
	public String itemList(
			HttpServletRequest request,
			Model model,
			@RequestParam(value="itemId",required=false,defaultValue="")
			Integer id
			) throws BusiException{
		if(id!=null&&id==1){
			throw new BusiException("我的業務異常.....");
		}
		int i = 1/0;

啟動web:

1. http://localhost:8081/goldSpringDemo/item/itemList.action?itemId=1  ,頁面出現的 我的業務異常

2. http://localhost:8081/goldSpringDemo/item/itemList.action ,捕獲的是執行時異常

相關文章