Spring MVC - 高級參數綁定,服務端校驗,數據回線,異常處理

本文详细介绍了SpringMVC中的高级参数绑定技术,包括POJO包装类、数组、List和Map的绑定方法,并深入探讨了服务端校验的具体实现及数据回显和异常处理的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.高级参数绑定

   1.1 包装类型pojo来接收查询条件参数
  分析:页面传参数的特点 :复杂,多样性;
  规则:页面 参数和controller方法参数定义:<input name="属性1.属性" /> 和 包装类中的属性1一样;

           例如:

             (1) 客户信息包装类

 

package cn.labelnet.ssm.po;

/**
 * 客户信息包装类
 * @author yuan
 *
 */
public class FClientCustomVo {
	
	//别名
	private String uname;

	//客户信息
	private FClient client;

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public FClient getClient() {
		return client;
	}

	public void setClient(FClient client) {
		this.client = client;
	}
	

}

           (2)controller 

	@RequestMapping(value = "/editClientIfofour")
	public String editClientIfofour(FClientCustomVo fcvo)  throws Exception{
		
		//业务开发
		
	
		return "/success.jsp";
	}
	

           (3)jsp

                    在这里可以发现 :客户姓名的 input标签name值为 包装类属性.属性 

	<form method="post" action="${pageContext.request.contextPath}/clients/editClientIfofour.action" enctype="">
<!-- 
		<input type="file" value="上傳圖片 :" name=""><br>  -->
		
	客户姓名:	<input type="text"  name="client.username" /><br> <br> 
		
	别名 :	<input type="text"  name="uname"> <br> <br> 
		<input type="submit" value="提交">
          

	</form>

     1.2 数组绑定
  关键:将页面的多选操作,传数组操作
  规则:controller的方法参数定义为 数组 :Integer [] ids; 

                  name值一样为 controller的数组名;
	         <input type="checkbox"  name="ids" />


    1.3 list绑定
        需求:需要批量提交数据的时候,讲提交的数据绑定到List<pojo> 中
比如:成绩的录入,多门课程成绩提交
使用List接收页面提交的批量数据,通过pojo接收,在包装类pojo中,定义list<pojo>属性;
参数定义 :pojo属性 itemlist list;

                规则:


               实例:

               (1)list作为参数时,需要将其封装在包装类中使用

/**
 * 客户信息包装类
 * @author yuan
 *
 */
public class FClientCustomVo {
	
	//别名
	private String uname;

	//客户信息
	private FClient client;

	
	//list类型
	private List<FClient> clients;
	
	public List<FClient> getClients() {
		return clients;
	}

	public void setClients(List<FClient> clients) {
		this.clients = clients;
	}

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public FClient getClient() {
		return client;
	}

	public void setClient(FClient client) {
		this.client = client;
	}
	

}

        (2)controller :还是包装类

	@RequestMapping(value = "/editClientIfofour")
	public String editClientIfofour(FClientCustomVo fcvo)  throws Exception{
		
		//业务开发
		
	
		return "/success.jsp";
	}
	

      (3)jsp页面中表单 的name值 规则为 :

 <c:forEach items="${itemList}" var="item" varStaus="status" >
		      <input name=" list[${status.index}].name" value="" />
			  <input name=" list[${status.index}].age" value="" />
		  </c:forEach>

     1.4 map绑定

   在包装类中定义map对象,并添加get、set方法,action使用包装对象接收 ;

           (1)包装类实现

	public classs QueryVo{
		   private Map<String,Object>  itemsinfo=new HashMap<String,Object>();
           //get、set
		   
		}

          (2)页面定义:
   
<input name="itemsinfo['name']" value="" />
		   <input name="itemsinfo['age']" value="" />

2.服务端校验

         通常使用较多的是前端校验,比如页面js校验。对于安全要求较高的建议在服务端进行校验;

         2.1 服务端校验 ?
     控制层 controller :校验页面请求的参数的合法性,在控制层校验,不区分客户端(浏览器,手机客户端,远程调用等);
业务层 service : 主要校验关键业务参数,仅限于service接口中使用的参数;
持久层 dao :一般是不校验的;

故,重视业务层的开发,校验比较多;


        2.2 springmvc校验开发

                  springmvc使用hibernate的校验框架validation,但和hibernate没有任何关系;

                  思路:
                  页面提交请求参数,请求到controller方法中,使用validation进行校验,如果校验出错,讲错误信息展示到页面;

                 示例 :需求:添加校验,比如注册日期是否为空的校验;   

                (1)导入 jar 包

     免积分下载 :    http://download.youkuaiyun.com/detail/lablenet/9394974

                (2)配置校验器

 在SpringMvc.xml 中实现配置 校验器 :

  <!-- 校验器 -->
	    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
	        
	        <!-- 配置hibernate校验器 -->
	        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
	        <!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如过不指定默认使用classpath下的ValidationMessages.properties -->
            <property name="validationMessageSource" ref="messageSource"></property>
            	        
	    </bean>
	    
	    <!-- 校验错误信息配置文件-->
	    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
	        <!-- 资源文件名 -->
	        <property name="basenames">
	           <list>
	              <value>classpath:CustomValidationMessage</value>
	           </list>
	        </property> 
	        <!-- 资源文件编码格式 -->
	        <property name="fileEncodings" value="utf-8"></property>
	         <!-- 对资源文件内容缓存时间,单位秒 -->
	        <property name="cacheSeconds" value="120"></property>
	    </bean>
	    

              


(3)注入到适配器中

 <!-- 配置自定义参数映射 -->
		 <mvc:annotation-driven conversion-service="conversionService" validator="validator"></mvc:annotation-driven>
		

(4)添加pojo校验规则

public class FClient {

	 private Integer id;
	 //校验名称在1~30之间,message是提示的错误显示信息
	 @Size(min=1,max=30,message="{item.name.length.error}",groups={ValidatedGroup1.class})
	 private String username;
	 
	 private String client_certificate_no;
	 
	 @NotNull(message="{item.born_date.isNull}")
	 private Date born_date;
	 private String family_register_address;
}

(5)配置校验提示信息

                           CustomValidationMessage.properties 配置校验提示信息 :

item.name.length.error=\u59D3\u540D\u957F\u5EA6\u4E0D\u591F1~30
item.born_date.isNull=\u8BF7\u8F93\u5165\u4F60\u7684\u751F\u65E5

(6)捕获校验信息
  在需要校验的pojo前边添加@Validated,在需要校验的pojo后边添加BindingResult bindingResult接收出错信息;
  注意:@Validated和BindingResult bindingResult 是配对出现的,并且形参顺序固定的;
  

                         示例 :

	/**
	 * 使用@ModelAtt
	 * @param m
	 * @param id
	 * @param fc
	 * @param binResult
	 * @return
	 * @throws Exception 
	 */
	
	@RequestMapping("editClientUpdateone")
	public String editClientUpdateone(Model m,Integer id,@ModelAttribute("custom") @Validated(value={ValidatedGroup1.class}) FClient fc ,BindingResult binResult)  throws Exception{

		int i=1/0;
		
		if(binResult.hasErrors()){
			List<ObjectError> errors = binResult.getAllErrors();
			for (ObjectError objectError : errors) {
				System.out.println(objectError.getDefaultMessage());
			}
			m.addAttribute("errorlist", errors);
			return "editClientIfo.action";
		}
		
		fc.setCreate_date(new Date());
			String result = fcService.updateClientIfo(id, fc);
			System.out.println(result);
		return "/success.jsp";
	}
	



(7)将错误信息传到页面上

                           使用Model参数实现 :

if(binResult.hasErrors()){
			List<ObjectError> errors = binResult.getAllErrors();
			for (ObjectError objectError : errors) {
				System.out.println(objectError.getDefaultMessage());
			}
			m.addAttribute("errorlist", errors);
			return "editClientIfo.action";
		}



(8)分组校验
           在pojo中定义校验规则,而pojo是被多个controller所共有,当不同的controller方法对同一个pojo进行校验,但是每个controller方法需要不同的校验;
  解决:定义多个校验分组,其实是一个java接口,分组中定义了那些规则;

                         定义一个接口 ,可以没有任何方法定义;

                         示例 :

                          validationGroup1接口 :

public interface ValidatedGroup1 {

	/**
	 * 校验分组 1
	 * 
	 */
	
}

                      设置分组 :

public String editClientUpdateone(Model m,Integer id,@ModelAttribute("custom") @Validated(value={ValidatedGroup1.class}) FClient fc ,BindingResult binResult)

                      pojo 设置分组 :

 @Size(min=1,max=30,message="{item.name.length.error}",groups={ValidatedGroup1.class})
	 private String username;

3.数据回显

 什么是数据回显?
 提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面;
 pojo数据回显方法:
   (1)springmvc默认对pojo数据进行回显;
  pojo数据传入controller方法后,springmvc自动将pojo数据放到request域中,key等于pojo类型的首字母小写;
  使用@ModelAttribute("")指定pojo回显到页面在request中的key;

public String editClientUpdateone(Model m,Integer id,@ModelAttribute("custom") @Validated(value={ValidatedGroup1.class}) FClient fc ,BindingResult binResult)  throws Exception{


  
   (2)@ModelAttribute("") 还可以表示将方法的返回值放在request中的key中
    例如:
 
	
	//将方法的返回值放在request中的key中
	@ModelAttribute("itemsType")
	public Map<String,String> getItemTypes(){
		Map<String,String> map=new HashMap<String, String>();
		map.put("101","黄金");
		map.put("102","白银");
		return map;
	}


注解的方法的返回值就可以获得到了,页面上就可以使用了;
 
   (3)最简单的回显方式
         不使用注解,使用model讲需要提交的pojo回显到页面;
model.addAttribute("");
         
简单类型的数据回显,只能使用model实现;


4.异常处理

                   预期异常:通过捕获
 运行时异常:通过测试,减少dao,service,controller的异常;
 思路: 

                             
 dao,service,controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交给异常处理器进行异常处理;
 
 (1) 自定义异常类
  针对预期的异常,需要在程序中抛出此类的异常,继承Exception

package cn.labelnet.ssm.controller.exception;


/**
 * 自定义异常类
 * TODO
 * 作者:原明卓
 * 时间:2016年1月7日 下午4:36:10
 * 工程:SpringMvcMybatis1Demo
 */
public class CustomException extends Exception {
	
	private String msg;
	
	public CustomException(String msg) {
      super(msg);
      this.msg=msg;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
	
}



  
  (2) 全局异常处理器
   思路:实现 HandlerExceptionResolver
解析出异常类型;
如果该异常类型是系统自定义的异常,直接取出异常信息并展示;
如果该异常类型不是自定义的异常,则构造一个自定义的异常类型信息;
       

package cn.labelnet.ssm.controller.exception;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

/**
 * 全局异常处理器
 * TODO
 * 作者:原明卓
 * 时间:2016年1月7日 下午4:40:18
 * 工程:SpringMvcMybatis1Demo
 */
public class CustomExceptionResover implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception ex) {
//		解析出异常类型;
//		如果该异常类型是系统自定义的异常,直接取出异常信息并展示;
//		如果该异常类型不是自定义的异常,则构造一个自定义的异常类型信息;
		
		CustomException customException=null;
		if(ex instanceof CustomException){
			//是自定义异常类
			customException=(CustomException) ex;
		}else{
			customException=new CustomException("未知错误:"+ex.getMessage());
		}
		String msg=customException.getMsg();
		ModelAndView andView = new ModelAndView();
		andView.addObject("msg", msg);
		andView.setViewName("/error.jsp");
		return andView;
	}

}


 (3) SpringMvc 配置使用
    只要实现了HandlerExceptionResolver接口就是全局处理器,只需要配置class就可以了;

 <!-- 配置全局异常处理类 -->
	    <bean class="cn.labelnet.ssm.controller.exception.CustomExceptionResover"></bean>
	    


 ( 4)测试
         如果与业务功能相关的异常,建议在service中抛出异常。
与业务功能没有关系的异常,建议在controller中抛出异常;

5.Demo免积分下载

    http://download.youkuaiyun.com/detail/lablenet/9394984

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值