SpringMVC-03

1 验证
服务端验证
JSR 303 是java6中的一个子规范,叫 bean validator ,主要就是针对javabean中的字段进行校验
官方的参考实现是 hibernate validator ,springmvc 中用的就是 hibernate validator

   1) 导包 
	    这里以4.3.1.Final 为例
			  hibernate-validator-4.3.1.Final.jar
			  jboss-logging-3.1.0.CR2.jar
			  validation-api-1.0.0.GA.jar

 2) 配置文件
				<mvc:annotation-driven validator="validator"  />

			  <bean id="validator"  class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
				 	<property name="providerClass"  value="org.hibernate.validator.HibernateValidator" />   
				 	<property name="validationMessageSource" ref="validationMessageSource" />  
			  </bean>

				<bean id="validationMessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" >
					 	<property name="basename" value="classpath:validationMessageSource" /> <!-- validationMessageSource是资源文件的名称,注意不要加扩展名(properties) -->
					 	<property name="fileEncodings" value="utf-8" />
					 	<property name="cacheSeconds" value="30" />
				</bean>

 3) 建立资源文件 validationMessageSource.properties 内容如下:
			  name.not.empty=名字不能为空
				age.not.inrange=年龄超出范围
				phone.not.correct=电话不正确
				phone.not.empty=电话不能为空
				email.not.empty=邮箱不能为空


	 4) 在实体类上,编写校验规则 ,可以把规则直接写在字段上,也可以写在get方法上
				public class UserInfo {
					private int id;
					
					@NotNull(message="用户名不能为null")  
					@NotEmpty(message="{name.not.empty}")  
					private String userName;
					
					private String password;
					private String school;
					
					@NotEmpty(message="{phone.not.empty}") 
					@Pattern(regexp="^1\\d{10}$",message="{phone.not.correct}") 
					private String phone;
					
					@NotEmpty(message="{email.not.empty}") 
					@Email(message="邮箱格式不正确")
					private String email;
					
					@Range(max=200,min=1,message="{age.not.inrange}")
					private int age;
					...		
				}

	 5) Action 中
				@RequestMapping(value="/user_add",method=RequestMethod.POST)
				public String addUser( Model m,@ModelAttribute("user") @Validated UserInfo user,BindingResult bResult){  
					//证明有错误(校验失败)
					if(bResult.hasErrors()){
						List<ObjectError> errorList= bResult.getAllErrors();
						for(ObjectError e:errorList){
							System.out.println(e.getDefaultMessage());  //输出错误信息
						}
						
						m.addAttribute("errorList",errorList); //把错误信息传到前台
					}
					else{
						dao.addUser(user);
					}
					return "user_add"; 
				}

	 6) 前台
				 	<c:forEach var="e" items="${errorList}">
				  	${e.defaultMessage } <br />
				  </c:forEach>
		 
				 	<hr />
		      <form action="user_add" method="post">
		        用户信息
		        	<hr>
				    	账号:<input type="text" name="userName" value="${user.userName}"  />  <br />
				    	密码:<input type="text" name="password" value="${user.password}" />  <br />
				    	学校:<input type="text" name="school"  value="${user.school}" />  <br />
				    	年龄:<input type="text" name="age"  value="${user.age}" />   <br />
				    	手机:<input type="text" name="phone"  value="${user.phone}" />  <br />
				    	邮箱:<input type="text" name="email"  value="${user.email}" /> <br />
		    	
		    			<input type="submit" value="提交" />	
		    			${msg }
		    	</form> 

					//自由显示错误信息
			   <x:form  action="user_add" method="post"  modelAttribute="user" >
			   		<x:errors path="*" />  <!-- 用 * 这样的方式是把所有的错误信息都输出 -->
			   		<hr />
			   		
				   	账号:<x:input path="userName" /> <x:errors path="userName" /> <br />
				   	密码:<x:input path="password" />  <x:errors path="password" /> <br />
				   	学校:<x:input path="school" />  <x:errors path="school" /> <br />
				   	年龄:<x:input path="age" />  <x:errors path="age" /> <br />
				   	手机:<x:input path="phone" />  <x:errors path="phone" /> <br />
				   	邮箱:<x:input path="email" />  <x:errors path="email" /> <br />
				   	
				   	<input type="submit" value="提交" />
			   </x:form>
		 
		    测试:http://localhost:8080/springmvc-03/user_add
		     			 
  			 	@RequestMapping(value="/user_add",method=RequestMethod.GET)
					public String gotoAddUser(Model m, @ModelAttribute("user") UserInfo user){
						return "user_add";  
					}

        关于分组校验 
          问题: 当一个实体类被多个业务方法使用,且它们的校验规则不同时怎么办
          
          可以指定校验分组 (分组就是一个接口)
          
          定义两个接口 (多少都行 )  IVG1, IVG2 ,空接口就行 (IVG1:interface,validator,goroup)

          在实体类上,指定验证属于哪个分组
          		// 电话属于第一组
							@NotEmpty(message="{phone.not.empty}",groups={IVG1.class}) 
							@Pattern(regexp="^1\\d{10}$",message="{phone.not.correct}",groups={IVG1.class})  //用正则表达式
							private String phone;
							
							// 邮箱属于第二组 
							@NotEmpty(message="{email.not.empty}",groups={IVG2.class}) 
							@Email(message="邮箱格式不正确" ,groups={IVG2.class})
							private String email;
													   
					在业务方法上,指定校验的时候要用哪个分组
					 public String addUser( Model m,@ModelAttribute("user") @Validated(value=IVG1.class) UserInfo user,BindingResult bResult)  

2 资源文件的引入
在配置文件中 springmvc-config.xml :
<mvc:resources location="/css/" mapping=“css/" />
<mvc:resources location="/images/" mapping="images/
” />

	 也可以把它们统一的放在同一个文件夹下 例如:放在 reources 文件夹下
			<mvc:resources location="/reources/" mapping="reources/**" /> 
			login.jsp:  
	     		 <link rel="stylesheet" type="text/css" href="reources/css/style.css">
		       <p>我是登陆页面</p>
		   		 <img  src="reources/image/3.png">

3 文件上传
1) 在配置文件中加入配置


//字节
//文件上传的临时目录

	2)页面 
	    <form action="admin_add" method="post" enctype="multipart/form-data" >  //注意 enctype的取值必须 multipart/form-data
	    	账号:<input type="text" name="adminName" />
	    	密码:<input type="text" name="password" />
	    	学校:<input type="text" name="school" />
	    	头像:<input type="file" name="photo" />
	    	<input type="submit" value="提交" />	
	    </form>

	3)控制层                 
	                                                             
			public String addAdminWithPhoto(AdminInfo admin, MultipartFile photo,HttpServletRequest request) throws IllegalStateException, IOException{	
					System.out.println(admin);
					
					System.out.println("上传文件的mime类型:"+ photo.getContentType());  
					System.out.println("上传的表单项的名称"+photo.getName()); 
					System.out.println("上传的文件名:"+ photo.getOriginalFilename());
					System.out.println("上传文件的大小"+photo.getSize());  
					
					
					String path= request.getServletContext().getRealPath("/upload_files");  
					String fileName=photo.getOriginalFilename();
					File targetFile=new File(path,fileName);
					
					photo.transferTo(targetFile); 
					
					//调用dao层,添加用户信息 略
					
					return "admin_add"; 	
			}

		附 多文件上传 
				@RequestMapping("/admin_add")
				public String addAdminWithPhoto(AdminInfo admin, @RequestParam("photo") MultipartFile[] photo, HttpServletRequest request) throws Exception {
			
					String path = request.getServletContext().getRealPath("/upload_files");
					for (MultipartFile f : photo) {
						if (!f.isEmpty()) {  
							String fileName = f.getOriginalFilename();
							File targetFile = new File(path, fileName);
							f.transferTo(targetFile);
						}
					}
					
				  //...调用dao层保存用户信息.略
			
					request.setAttribute("msg", "文件上传成功");
					return "admin_add";
				}  
				
	    <form action="admin_add" method="post" enctype="multipart/form-data" >
	    	账号:<input type="text" name="adminName" />
	    	密码:<input type="text" name="password" />
	    	学校:<input type="text" name="school" />
	    	头像:<input type="file" name="photo" />
	    	头像:<input type="file" name="photo" />
	    	头像:<input type="file" name="photo" />
	    	头像:<input type="file" name="photo" />
	    	<input type="submit" value="提交" />	
	    	
	    	${msg }
	    </form>
			测试:若是文件名字相当则会覆盖。

4 Ajax 与 json 数据处理

例一 
	 ajax_test.jsp:
			<script type="text/javascript">
				$(function(){
					$("#btn1").click(function(){
						$.ajax({
							url:"ajax_getadmin",
							type:"post",
							async:false,
							cache:false,
							data:{adminId:$("#adminId").val()},
							dataType:"json",
							success:function(admin){
								alert(admin.id);
								alert(admin.adminName);
								alert(admin.school);
							}
						});
					});
				});
			</script>
	    <input type="text" id="adminId" >
		<button id="btn">测试</button>
			
			@RequestMapping("/ajax_getadmin")
			public void test(HttpServletRequest request,HttpServletResponse response) throws IOException{
				String adminId=request.getParameter("adminId"); 
				System.out.println("adminId="+adminId);
				
				AdminInfo admin=dao.getAdminById(Integer.parseInt(adminId));
				
				response.setContentType("text/html;charset=utf-8");
				PrintWriter out=response.getWriter();
				
				//out.print("测试数据");   

				out.print( "{\"id\":\"90\",\"adminName\":\"admin\",\"school\":\"123\"}");  
	
			}


例二 使用 @ResponseBody 返回实体类对象
	 导包 (注意版本问题,spring 3 以前的需要换包,但是写法不换)
		  jackson-annotations-2.4.4.jar
      jackson-core-2.4.4.jar
      jackson-databind-2.4.4.jar
      
      

     ajax_test.jsp:
	     	$(function(){
					$("#btn1").click(function(){
						$.ajax({
							url:"ajax_getadmin_new",
							type:"post",
							async:false,
							cache:false,
							data:{adminId:$("#adminId").val()},
							dataType:"json",
							success:function(admin){
								alert(admin.id);
								alert(admin.adminName);
								alert(admin.note);
								alert(admin.password);
							}
						});
					});
				});
				
		 AdminAction:
				@RequestMapping("/ajax_getadmin_new")
				@ResponseBody  public AdminInfo getAdmin(int adminId){
					AdminInfo admin=dao.getAdminById(adminId);
					return admin;
				}


例三 返回列表 
		<script type="text/javascript">
			$(function(){
				$("#btn1").click(function(){
					$.ajax({
						url:"ajax_get_alladmin",
						type:"post",
						async:false,
						cache:false,
						dataType:"json",
						success:function(adminList){
							$.each(adminList,function(key,admin){
								var trStr="<tr><td>"+admin.id+"</td><td>"+admin.adminName+"</td><td>"+admin.password+"</td></tr>"; 
								$("#table1").append(trStr);
							});
						}
					});
				});
			});
		</script>
		
		 <button id="btn1">查询全部</button>

  	<table  border="1" width="400" id="table1">
  	</table>
  	
		@ResponseBody  @RequestMapping("/ajax_get_alladmin")
		public List<AdminInfo> getAllAdmin(){
			return dao.getAllAdmin();
		}

5 RESTful 风格
REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的
HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席

		 长期以来,软件研究主要关注软件设计的分类、设计方法的演化,很少客观地评估不同的设计选择对系统行为的影响。
		 而相反地,网络研究主要关注系统之间通信行为的细节、如何改进特定通信机制的表现,常常忽视了一个事实,
		 那就是改变应用程序的互动风格比改变互动协议,对整体表现有更大的影响。我这篇文章的写作目的,就是想在符合架构原理的前提下,
		 理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构
		 
		 REST,即Representational State Transfer的缩写。我对这个词组的翻译是"表现层状态转化"。  
		 如果一个架构符合REST原则,就称它为RESTful架构
		 
		 关于 Representational State Transfer (表现层状态转化) 的理解
		 1)REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。
		 		网络上的一个具体信息,可以用一个URI(统一资源定位符)指向它
   2) Representation 表现层
     "资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。
     比如,文本可以用txt格式表现,也可以用HTML格式、XML格式
     URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的 因为这个后缀名表示格式,属于 "表现层" 
     范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,
     这两个字段才是对"表现层"的描述。
   3) State Transfer 状态转化
				HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,
				必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
				客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:
				  GET、POST、PUT、DELETE。它们分别对应四种基本操作:
				  GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
				  
		综合上面的解释,我们总结一下什么是RESTful架构:

  (1)每一个URI代表一种资源;

  (2)客户端和服务器之间,传递这种资源的某种表现层;

  (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

      例如: 查看用户信息
      
	      传统的: 
	      	 http://loclahost:8080/shop/UserAction?id=10&flag=update 
	      RESTful风格的:
	      	 http://loclahost:8080/shop/user/10    ==> RESTful 风格
	         http://www.douban.com/photos/album/49432287/  这是豆瓣网上的
       
       
      
    例子 
   		随便某个页面:
        	<a href="test_admin?id=10&flag=del" >删除用户</a>
        
        上面的超链接,用rest风格 
         <a href="test_admin/10/delete" >删除用户</a>
        
        AdminAction:
        	@RequestMapping("/test_admin/{id}/{flag}")
					public String testAdmin(@PathVariable("id") int idAAA,@PathVariable("flag") String flagAAA){
						System.out.println(idAAA);
						System.out.println(flagAAA);
						
						return "success";	
					}
					
				测试:http://localhost:8080/admin-springmvc/test_admin/10/del  可以访问到success页面。
				      若是 http://localhost:8080/admin-springmvc/test_admin/10 就会报404 错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值