Spring 注解学习手札(二) 控制层梳理.docx_第1页
Spring 注解学习手札(二) 控制层梳理.docx_第2页
Spring 注解学习手札(二) 控制层梳理.docx_第3页
Spring 注解学习手札(二) 控制层梳理.docx_第4页
Spring 注解学习手札(二) 控制层梳理.docx_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

言归正传,研究一下注解下的控制层。我习惯于使用JSTL展示页面,因此需要在原lib基础上增加jstl.jar和standard.jar,详细lib依赖如下:引用aopalliance-1.0.jarcommons-logging-1.1.1.jarlog4j-1.2.15.jarspring-beans-2.5.6.jarspring-context-2.5.6.jarspring-context-support-2.5.6.jarspring-core-2.5.6.jarspring-tx-2.5.6.jarspring-web-2.5.6.jarspring-webmvc-2.5.6.jarstandard.jarjstl.jar上一篇文中,我们定义了控制器AccountController:AccountController.javaJava代码1. /*2. *2010-1-233. */4. packageorg.zlex.spring.controller;5. 6. importjavax.servlet.http.HttpServletRequest;7. importjavax.servlet.http.HttpServletResponse;8. 9. importorg.springframework.beans.factory.annotation.Autowired;10. importorg.springframework.stereotype.Controller;11. importorg.springframework.web.bind.ServletRequestUtils;12. importorg.springframework.web.bind.annotation.RequestMapping;13. importorg.springframework.web.bind.annotation.RequestMethod;14. importorg.zlex.spring.service.AccountService;15. 16. /*17. *18. *author梁栋19. *version1.020. *since1.021. */22. Controller23. RequestMapping(/account.do)24. publicclassAccountController25. 26. Autowired27. privateAccountServiceaccountService;28. 29. RequestMapping(method=RequestMethod.GET)30. publicvoidhello(HttpServletRequestrequest,HttpServletResponseresponse)31. throwsException32. 33. Stringusername=ServletRequestUtils.getRequiredStringParameter(34. request,username);35. Stringpassword=ServletRequestUtils.getRequiredStringParameter(36. request,password);37. System.out.println(accountService.verify(username,password);38. 39. 先说注解RequestMapping这里使用注解RequestMapping(method = RequestMethod.GET)指定这个方法为get请求时调用。同样,我们可以使用注解RequestMapping(method = RequestMethod.POST)指定该方法接受post请求。Java代码1. Controller2. RequestMapping(/account.do)3. publicclassAccountController4. 5. RequestMapping(method=RequestMethod.GET)6. publicvoidget()7. 8. 9. RequestMapping(method=RequestMethod.POST)10. publicvoidpost()11. 12. 这与我们久别的Servlet很相像,类似于doGet()和doPost()方法!我们也可以将其改造为多动作控制器,如下代码所示:Java代码1. Controller2. RequestMapping(/account.do)3. publicclassAccountController4. 5. RequestMapping(params=method=login)6. publicvoidlogin()7. 8. 9. RequestMapping(params=method=logout)10. publicvoidlogout()11. 这样,我们可以通过参数“method”指定不同的参数值从而通过请求(/account.do?method=login和/account.do?method=logout)调用不同的方法!注意:使用多动作控制器必须在配置文件中加入注解支持!Xml代码1. 当然,我们也可以将注解RequestMapping指定到某一个方法上,如:Java代码1. Controller2. publicclassAccountController3. 4. RequestMapping(/a.do)5. publicvoida()6. 7. RequestMapping(/b.do)8. publicvoidb()9. 这样,请求“a.do”和“b.do”将对应不同的方法a() 和b()。这使得一个控制器可以同时承载多个请求!RequestMapping(/account.do)是RequestMapping(value=/account.do)的简写!再说输入参数!这里的方法名可以随意定义,但是参数和返回值却又要求!为什么?直接看源代码,我们就能找到答案!AnnotationMethodHandlerAdapter.java部分源代码有关参数部分:Java代码1. Override2. protectedObjectresolveStandardArgument(ClassparameterType,NativeWebRequestwebRequest)3. throwsException4. 5. HttpServletRequestrequest=(HttpServletRequest)webRequest.getNativeRequest();6. HttpServletResponseresponse=(HttpServletResponse)webRequest.getNativeResponse();7. 8. if(ServletRequest.class.isAssignableFrom(parameterType)9. returnrequest;10. 11. elseif(ServletResponse.class.isAssignableFrom(parameterType)12. this.responseArgumentUsed=true;13. returnresponse;14. 15. elseif(HttpSession.class.isAssignableFrom(parameterType)16. returnrequest.getSession();17. 18. elseif(Principal.class.isAssignableFrom(parameterType)19. returnrequest.getUserPrincipal();20. 21. elseif(Locale.class.equals(parameterType)22. returnRequestContextUtils.getLocale(request);23. 24. elseif(InputStream.class.isAssignableFrom(parameterType)25. returnrequest.getInputStream();26. 27. elseif(Reader.class.isAssignableFrom(parameterType)28. returnrequest.getReader();29. 30. elseif(OutputStream.class.isAssignableFrom(parameterType)31. this.responseArgumentUsed=true;32. returnresponse.getOutputStream();33. 34. elseif(Writer.class.isAssignableFrom(parameterType)35. this.responseArgumentUsed=true;36. returnresponse.getWriter();37. 38. returnsuper.resolveStandardArgument(parameterType,webRequest);39. 也就是说,如果我们想要在自定义的方法中获得一些个“标准”输入参数,参数类型必须包含在以下类型中:引用ServletRequestServletResponseHttpSessionPrincipalLocaleInputStreamOutputStreamReaderWriter当然,上述接口其实都是对于HttpServletRequest和HttpServletResponse的扩展。此外,我们还可以定义自己的参数。注意:自定义参数必须是实现类,绝非接口!Spring容器将帮你完成对象初始化工作!比如说上文中,我们需要参数username和password。我们可以这么写:Java代码1. RequestMapping(method=RequestMethod.GET)2. publicvoidhello(Stringusername,Stringpassword)3. System.out.println(accountService.verify(username,password);4. 如果参数名不能与这里的变量名保持一致,那么我们可以使用注解RequestParam进行强制绑定,代码如下所示:Java代码1. RequestMapping(method=RequestMethod.GET)2. publicvoidhello(RequestParam(username)Stringu,3. RequestParam(password)Stringp)4. System.out.println(accountService.verify(u,p);5. 这比起我们之前写的代码有所简洁:Java代码1. RequestMapping(method=RequestMethod.GET)2. publicvoidhello(HttpServletRequestrequest,HttpServletResponseresponse)3. throwsException4. 5. Stringusername=ServletRequestUtils.getRequiredStringParameter(6. request,username);7. Stringpassword=ServletRequestUtils.getRequiredStringParameter(8. request,password);9. System.out.println(accountService.verify(username,password);10. ServletRequestUtils类的工作已经由Spring底层实现了,我们只需要把参数名定义一致即可,其内部取参无需关心!除了传入参数,我们还可以定义即将传出的参数,如加入ModelMap参数:Java代码1. SuppressWarnings(unchecked)2. RequestMapping(method=RequestMethod.GET)3. publicMaphello(Stringusername,Stringpassword,ModelMapmodel)4. 5. System.out.println(accountService.verify(username,password);6. 7. model.put(msg,username);8. 9. returnmodel;10. 这时,我们没有定义页面名称,Spring容器将根据请求名指定同名view,即如果是jap页面,则account.do-account.jsp!不得不承认,这样写起来的确减少了代码量!接着说输出参数!通过ModelMap,我们可以绑定输出到的页面的参数,但最终我们将要返回到何种页面呢?再次查看AnnotationMethodHandlerAdapter源代码!AnnotationMethodHandlerAdapter.java部分源代码有关返回值部分:Java代码1. SuppressWarnings(unchecked)2. publicModelAndViewgetModelAndView(MethodhandlerMethod,ClasshandlerType,ObjectreturnValue,3. ExtendedModelMapimplicitModel,ServletWebRequestwebRequest)4. 5. if(returnValueinstanceofModelAndView)6. ModelAndViewmav=(ModelAndView)returnValue;7. mav.getModelMap().mergeAttributes(implicitModel);8. returnmav;9. 10. elseif(returnValueinstanceofModel)11. returnnewModelAndView().addAllObjects(implicitModel).addAllObjects(Model)returnValue).asMap();12. 13. elseif(returnValueinstanceofMap)14. returnnewModelAndView().addAllObjects(implicitModel).addAllObjects(Map)returnValue);15. 16. elseif(returnValueinstanceofView)17. returnnewModelAndView(View)returnValue).addAllObjects(implicitModel);18. 19. elseif(returnValueinstanceofString)20. returnnewModelAndView(String)returnValue).addAllObjects(implicitModel);21. 22. elseif(returnValue=null)23. /Eitherreturnednullorwasvoidreturn.24. if(this.responseArgumentUsed|webRequest.isNotModified()25. returnnull;26. 27. else28. /Assumingviewnametranslation.29. returnnewModelAndView().addAllObjects(implicitModel);30. 31. 32. elseif(!BeanUtils.isSimpleProperty(returnValue.getClass()33. /Assumeasinglemodelattribute.34. ModelAttributeattr=AnnotationUtils.findAnnotation(handlerMethod,ModelAttribute.class);35. StringattrName=(attr!=null?attr.value():);36. ModelAndViewmav=newModelAndView().addAllObjects(implicitModel);37. if(.equals(attrName)38. ClassresolvedType=GenericTypeResolver.resolveReturnType(handlerMethod,handlerType);39. attrName=Conventions.getVariableNameForReturnType(handlerMethod,resolvedType,returnValue);40. 41. returnmav.addObject(attrName,returnValue);42. 43. else44. thrownewIllegalArgumentException(Invalidhandlermethodreturnvalue:+returnValue);45. 46. 返回值的定义十分庞大,或者说可怕的if-else多少有点让我觉得厌恶!我们可以定义以下类型的返回值:引用ModelAndViewModelViewMapStringnullModelAndView、Model和View都是Spring之前版本所特有的元素,Map对应于传入参数ModelMap,String定义页面名称,null即对应void类型方法!最常用的实现方式如下:Java代码1. SuppressWarnings(unchecked)2. RequestMapping(method=RequestMethod.GET)3. publicStringhello(Stringusername,Stringpassword,ModelMapmodel)4. 5. System.out.println(accountService.verify(username,password);6. 7. model.put(msg,username);8. 9. returnaccount;10. 当然,对于我来说在返回值中写入这么一个字符串多少有点不能接受,于是我还是乐于使用输入参数ModelMap+输出参数Map的方式。给出一个完整的AccountController实现:AccountController.javaJava代码1. /*2. *2010-1-233. */4. packageorg.zlex.spring.controller;5. 6. importjava.util.Map;7. 8. importorg.springframework.beans.factory.annotation.Autowired;9. importorg.springframework.stereotype.Controller;10. importorg.springframework.ui.ModelMap;11. importorg.springframework.web.bind.annotation.RequestMapping;12. importorg.springframework.web.bind.annotation.RequestMethod;13. importorg.zlex.spring.service.AccountService;14. 15. /*16. *17. *author梁栋18. *version1.019. *since1.020. */21. Controller22. RequestMapping(/account.do)23. publicclassAccountController24. 25. Autowired26. privateAccountServiceaccountService;27. 28. SuppressWarnings(unchecked)29. RequestMapping(method=RequestMethod.GET)30. publicMaphello(Stringusername,Stringpassword,ModelMapmodel)31. 32. System.o

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论