SpringMVC-02

1 参数绑定与值的传递
页面请求发起的时候,如何把数据传给 Action , 在 Action 中如何把模型数据进行传递

	1) 在Action 的方法的形参上,可以使用如下的形参  
		  HttpServletRequest 
		  HttpServletResponse
		  HttpSession 

		  Model //接口  interface org.springframework.ui.Model
		  ModelMap //  org.springframework.ui.ModelMap extends java.util.LinkedHashMap
		  Map<String,Object>  //普通的Map也可以
		  
		  不能传 ServletContext 对象, 可以用 request.getServletContext() 这个方法得到 
		  
			例子 用户登录,登录以后转到 main.jsp , 并显示出用户信息 (模型数据)
			  登录页: WebRoot下的 login.jsp:
			    <form action="login" method="post" >
					    账号:	<input type="text" name="userName" />
					    密码: <input type="text" name="password" />
				    	<input type="submit" value="登录"/>
			    </form>		  
		  
				Action
				@RequestMapping(value="/login")   
				public String login(HttpServletRequest request,Model model,Map<String,Object> map,ModelMap modelMap){
					String userName=request.getParameter("userName");
					String password=request.getParameter("password");
				
			    	UserInfo user=dao.getLoginUser(userName,password);
			      //request.setAttribute("user", user);
			    	model.addAttribute("user",user); 
			    	
			    	map.put("map_msg", "用户登录成功,用map传的消息");
			    	modelMap.addAttribute("modelmap_msg","这是用modelmap传的信息");
			    	
					return "main"; 	//=WEB-INF/jsp/main.jsp	
				}
	
		    main.jsp   
			    用户信息:
			    <hr />
				    账号:  ${user.userName }
				    密码:  ${user.password }
				   	学校:  ${user.school }
			   	<hr />
		   		  用map传的信息: ${map_msg }
		    	<hr />  
		   		  用 modelMap传的信息: ${modelmap_msg }	  
			  
	2) 可以使用简单类型 
	 	 			比如上面的登录功能可以写成 
					@RequestMapping(value="/login")
					public String login(String userName,String password,Model model){
						UserInfo user=dao.getLoginUser(userName,password);
						System.out.println(userName+":"+password);
						
						model.addAttribute("user",user); 
						return "main"; 
					}  
		  
		 例子 
				@RequestMapping(value="/test")
				public void test  
				(
						String userName,
				    @RequestParam("password") String pwd,
				    @RequestParam(value="age",required=true ) int age,  
				    @RequestParam(value="school",defaultValue="初中毕业") String school  
				)
				{
					System.out.println("userName="+userName);
					System.out.println("password="+pwd);
					System.out.println("age="+age);
					System.out.println("school="+school);
				}
		
		访问这个方法 		
		 	http://localhost:8080/springmvc-01/test?userName=admin&password=987&age=987&school=huaixia			  
		  
		  
	3) 可以使用pojo类型 (bean)			  
		 添加功能:
		      	创建 web-root 下的 user_add.jsp:
		        <form action="user_add" method="post" >
						    账号:	<input type="text" name="userName" />
						    密码: <input type="text" name="password" />
						    备注: <input type="text" name="note" />
						    学校: <input type="text" name="school" />
					    	<input type="submit" value="提交"/>
				    </form>
		    		${msg }
		    		
			    	UserAction:
					  @RequestMapping(value="/user_add")
						public String addUser(UserInfo user,Model m){
							System.out.println(user);
							dao.addUser(user);
							m.addAttribute("msg", "用户添加成功");
							return "user_add";  
						}		  
					  
				    这里有中文乱码问题	  
		        可以用乱码的过滤器处理
	  					<filter>
								    <filter-name>CharacterEncodingFilter</filter-name>
								    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
								    <init-param>
								        <param-name>encoding</param-name>
				       					<param-value>utf-8</param-value>
				   					</init-param>
							</filter>
							<filter-mapping>
							      <filter-name>CharacterEncodingFilter</filter-name>
							      <url-pattern>杠*</url-pattern>
							</filter-mapping>
					  
	         要注意,上面的过滤器,只有请求是post的方式时才可以
	  
           要想让get请求和post请求的编码处理方式一样 ,在 tomcat 安装目录下: conf/server.xml    
           加上 
   					useBodyEncodingForURI="true" 
    				<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"  useBodyEncodingForURI="true"  />  //加上这句,注意true两边要有双引号	  
			  
     关于日期类型的处理
        1 在UserInfo中加一个日期类型的字段  private Date birthday; 
        2 数据库里也可以加入 datetime 类型的 birthday
           
        在用户添加页面 user_add.jsp ,再加一个输入框 
          生日:<input type="text" name="birthday" /> 
         
        然后运行,添加用户,输入生日  2005-10-25  提交,发现出现了400错误 
        原因就是因为springmvc不知道怎么处理(我们输入的)日期格式

      处理方法 
        方式一  在实体类 UserInfo 上加日期格式化注解 
					  @DateTimeFormat(pattern="yyyy-MM-dd")   //简单,有效,可以传空值
						private Date birthday; 
						
			  
			  方式二 在控制器 UserAction 中添加一段日期处理代码
		      @InitBinder
					public void initBinder(WebDataBinder binder){
						SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
						dateFormat.setLenient(false);
						binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));  //这里的true这个参数,表示可传入空值
					}

					这种方式的控制粒度更细一些(因为若是在实体类中加,若是这个实体类使用的多,那格式需求就不一样,所以有时候就不合适了)			  
		  
		  
		  
	4) 可以使用包装类型的 pojo			  
		  
		 例子:
 					public class UserInfoCustom {
						UserInfo user; //用户信息
						private String petName;  //宠物的名字
						private String petAddress;  //宠物的家
					}
		   user_add.jsp:
		    <form action="user_add" method="get">
		       用户信息
			        <hr>
				    	账号:<input type="text" name="user.userName" />
				    	密码:<input type="text" name="user.password" />
				    	学校:<input type="text" name="user.school" />
				    	生日:<input type="text" name="user.birthday" />  <br>
		     	 宠物信息 	
		          <hr>
				    	宠物名:<input type="text" name="petName" />
				    	宠物家:<input type="text" name="petAddress" />
			    	<input type="submit" value="提交" />	
			    	${msg }
		    </form>			  
		  
		   //控制层 UserAction:
				@RequestMapping(value="/user_add")
				public String addUser(UserInfoCustom userPet,Model m ){  //这就是包装的 pojo
					System.out.println(userPet);  
					//....进行数据库操作 
					m.addAttribute("msg", "用户添加成功");
					return "user_add"; 
				}		  
		  
		  
		  
	5) 数组类型  比如批量删除		
		  userlist.jsp
		  	<form action="delete_all" method="post">
			    <table border="1" width="500">
			    	<c:forEach  var="user" items="${userList}" >
			    		<tr>
			    			<td><input type="checkbox" name="ids" value="${user.id }"> </td>
			    			<td>${user.id }</td>
			    			<td>${user.userName }</td>
			    			<td>${user.password }</td>
			    			<td>${user.school }</td>
			    			<td> <a href="update_user?id=${user.id }" >修改</a></td>
			    		</tr>
			    	</c:forEach>
			    </table>
			    
			    <input type="submit" value="删除所选" />  
		    </form>			  
		  
		   
		    @RequestMapping("/delete_all")
		    public String deleteUsers(Integer [] ids){  
		    	for(int id:ids){
		    		System.out.println(id);
		    		dao.delUserById(id);  
		    	}
		    	return "forward:search_all_user"; 
		    }
		    
	6) List类型 (比如批量更新)			    			  
		  
			 (1) 建一个类 
		       public class UserInfoListCustom {
		       		private List<UserInfo> userList;  
		       		... get  set  ...
		       }
	     
	  	 (2) Action 中
			    @RequestMapping("/update_all")
			    public String updateAllUser(UserInfoListCustom ul ){
			    	
			    	List<UserInfo> userList=ul.getUserList();
			    	for(UserInfo u:userList){
			    		System.out.println(u);
			    		dao.updateUser(u); 
			    	}	
			    	return "forward:search_all_user";  
			    }
			  (3)  user_manage.jsp
			     <form action="update_all" method="post">
					    <table border="1" width="500">
					    	<c:forEach  var="user" items="${userList}" varStatus="st" >
					    		<tr>                     
					    			<td><input type="text" name="userList[${st.index }].id" value="${user.id }" /> </td>
					    			<td><input type="text" name="userList[${st.index }].userName" value="${user.userName }" /> </td>
					    			<td><input type="text" name="userList[${st.index }].password" value="${user.password }" /></td>
					    			<td><input type="text" name="userList[${st.index }].school" value="${user.school }" /></td>
					    		</tr>
					    	</c:forEach>
					    </table>
				    
				      <input type="submit" value="批量修改" />  
			     </form>	  

2 数据的回显

    <form action="user_add" method="get">
    	账号:<input type="text" name="userName" value="${user.userName}"  />  
    	密码:<input type="text" name="password" value="${user.password}" />
    	学校:<input type="text" name="school"  value="${user.school}" />
    	
    	<input type="submit" value="提交" />	
    	${msg }
    </form>		  
		  
		  
	例一 可以用 Model 回传数据
			@RequestMapping(value="/user_add")
			public String addUser(UserInfo user,Model m ){
				dao.addUser(user);
				m.addAttribute("user",user);   //用这样的方式回传数据
				m.addAttribute("msg", "用户添加成功");
				return "user_add"; 
			}			  
				  
		  
		  
  例二 可以用 @ModelAttribute("user") 这样的方式回传数据
			@RequestMapping(value="/user_add")
			public String addUser(@ModelAttribute("user") UserInfo user){
				dao.addUser(user);
				user.setUserName("这是改过后的名称");  
				return "user_add"; 
			}			  
				  
  例三 对于普通类型的参数 (也是用model回传)
			@RequestMapping(value="/login")
			public String login( String userName,String password,Model model){   
				 UserInfo user=dao.getLoginUser(userName,password);
				 //...数据库查询
				 model.addAttribute("userName",userName);
				 model.addAttribute("password",password);
				 model.addAttribute("msg" ,"登录失败");			 
				return "login"; 
			}
			login.jsp
			  <form action="login" method="post" >
			  账号:	<input type="text" name="userName"  value="${userName}" />
			  密码: <input type="text" name="password" value="${password }" />
			  	<input type="submit" value="登录"/>
			  </form>
				${msg}			  
			  
		  
 例四  使用Spring提供的标签   	 
    user_add.jsp 
       <%@ taglib uri="http://www.springframework.org/tags/form" prefix="x" %>
		   <x:form  action="user_add" method="post" >
			   	账号:<x:input path="userName" />   
			   	密码:<x:input path="password" />
			   	学校:<x:input path="school" />
			   	<input type="submit" value="提交" />
		   </x:form>
   
		   如果这时直接访问这个页面,将出错 
		     No WebApplicationContext found: no ContextLoaderListener registered
     
    	 因为没有初始化Spring环境 ,要在web.xml中加入相关的配置 
		     初始化 spring 环境
			    <context-param>	
				  	<param-name>contextConfigLocation</param-name>	
				  	<param-value>classpath:springmvc-config.xml</param-value>	
				  </context-param>
				  <listener>	
				  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
				  </listener>	
		
				  // 这是把所有的请求交给 spring 核心控制器 处理
			    <servlet>
				  	<servlet-name>SpringAAA</servlet-name>
				  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
				  	<init-param>
				  		<param-name>contextConfigLocation</param-name>
				  		<param-value>classpath*:springmvc-config.xml</param-value>
				  	</init-param>
				  </servlet>
				  <servlet-mapping>
				  	<servlet-name>SpringAAA</servlet-name>
				  	<url-pattern>/</url-pattern>
				  </servlet-mapping>
							    
		    再运行 
		       Neither BindingResult nor plain target object for bean name 'command' available as request attribute

        要在表单属性上加上  commandName="user" 或  modelAttribute="user" 如下:
    
        <x:form  action="user_add" method="post"  modelAttribute="user" >
  
		    再运行 
		      nor plain target object for bean name 'user' available as request attribute

		    要如下处理,先写一个方法,通过这个方法转到目标页面
	
					@RequestMapping(value="/user_add",method=RequestMethod.POST)
					public String addUser(@ModelAttribute("user") UserInfo user){
						dao.addUser(user);
						user.setUserName("这是改过后的名称");
						return "user_add"; 
					}
					
					@RequestMapping(value="/user_add",method=RequestMethod.GET)						
					public String gotoAddUser(@ModelAttribute("user") UserInfo user){
						return "user_add"; 
					}
		
				测试:访问:http://localhost:8080/SpringMVC-04/user/add_user

3 异常处理
1) 在action中进行处理 (局部)

	@ExceptionHandler(value=Exception.class)
    public String exceptionProccess(Exception ex,HttpServletRequest request){
    	request.setAttribute("ex", ex);
    	return "error_process"; 
    }			  
		  
  	error_process.jsp
	    <h1>对不起,出错了</h1>
		  ${ex.message }			  
		  
		以后这个action中的任何方法执行如果发生异常,就会转到这个方法 ( exceptionProccess() ) 上  
		  
		例子:自定义异常类 
				public class MyException extends Exception
				{
					private String msg;
					public MyException(String msg){
						super(msg); //把异常信息传给父类的构造函数
						this.msg=msg;
					}
					
					public void showErrorMsg(){
						System.err.println(new Date()+":"+this.msg);
						System.out.println("日记已记录...");
					}
				}			  
		  
		 UserAction:	      
			  @ExceptionHandler(value=MyException.class)
		    public String exceptionProccess(MyException ex,HttpServletRequest request){
		    	request.setAttribute("ex", ex);
		    	ex.showErrorMsg();
		    	return "error_process"; 
		    }
   
				@RequestMapping(value="/login")
				public String login( String userName,String password,Model model) throws MyException{
					 UserInfo user=dao.getLoginUser(userName,password);
					 
					 if(!"周杰伦".equals(userName)){
						 throw new MyException("登录的人物不是周杰伦");
					 }
					 model.addAttribute("userName",userName);
					 model.addAttribute("password",password);

					return "login"; 
				}			  
		  
2) 全局异常处理	

	    在配置文件 springmvc-config.xml 中加上 
			 <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
         <property name="exceptionMappings">     
             <props>     
            	   <prop key="cat.beans.MyException">error_process_1</prop>   //注意,这里的 error_process_1 是受前缀和后缀影响的
                 <prop key="java.lang.Exception">error_process_2</prop>     
                 <prop key="java.lang.SQLException">error_process_3</prop>     
             </props>     
         </property>     
     	</bean>   
	    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
				<property name="prefix" value="/" />
				<property name="suffix" value=".jsp" />
			</bean>		
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值