基础框架:Spring MVC + MyBatis 。
本平台的搭建基于Spring MVC + MyBatis,本文讲述了spring mvc的使用思想。
核心思想是:Action层有两个Spring mvc DispatcherServlet容器 ,下层(service\dao)有一个Spring context容器。
|
应用场景举例,有一个多用户的博客系统。
来自互联网的用户:注册、登录、写博文、管理文章分类、关注好友。使用的是“前台”。url后缀是*.htm。
系统管理员:登录后台、栏目管理、文章管理、首页管理、静态化管理。使用的是“后台”。url后缀是*.do。
Spring mvc的拦截
前台:spring mvc统一拦截*.htm后缀
后台:spring mvc统一拦截*.do后缀
可以理解为“前台”、“后台”是两个网站。
静态资源(css\js\image)不会被拦截,不需要处理。
权限管理使用 shiro 框架, shiro 管理登录(认证)、授权、记住我。 shiro 框架拦截*.do,只有后台需要权限管理,前台不需要权限管理。
Spring MVC使用要点:
Controller类无接口,Service类无接口,Dao只有接口无实现
Controller上的注解@RequestMapping (value = "/admin/index" ) ,中的"/admin/index"统一不写.do、.htm后缀。
Controller中的return "redirect:/sys/menu.do"; 重定向时一定要写.do、.htm后缀。
Controller中的return "modules/sys/menuTreeselect"; 转发视图层时,前面不以/开头,最后不写.jsp后缀。
进入首页
当浏览器访问网站的首页时,地址可能是: http://www.abc.com/,这个请求会被index.jsp处理(因web.xml中配置的welcome-file-list中有index.jsp)
由FDP的spring mvc只拦截*.do、*.htm后缀,所以不可以拦截住这个请求,spring mvc无机会处理这个请求。所以在 indxe.jsp 要转发到 index.do
Spring mvc 常用注解
@Controller
@RequestMapping
@Autowired
@ModelAttribute
1、@ModelAttribute写在方法上,此controller每个方法执行前本方法被执行
2、@ModelAttribute 写在方法的参数上 ,可从model中获取值,或可从Form表单或URL参数中获取值来填充这个参数
@RequestParam
使用
@RequestParam
将 URL 参数插入方法中。
参数,相当于 request.getParameter(""), 使用@RequestParam必须要加上参数名,因为 编译出的class文件可以简化了参数名。
@PathVariable
使用
@PathVariable
注释可将 URI 中的路径变量作为参数插入。
@RequiresPermissions shiro 权限
@Service
@Transactional(readOnly = true)
@Transactional(readOnly = false)
@MyBatisDao
使用
@RequestHeader
将某一 HTTP 头插入方法中。
使用
@RequestBody
将 HTTP 请求正文插入方法中。
使用
@ResponseBody
将内容或对象作为 HTTP 响应正文返回。
使用
HttpEntity<T>
将它自动插入方法中,如果将它作为参数提供。
使用
ResponseEntity<T>
返回具有自定义状态或头的 HTTP 响应。
spring mvc的RedirectAttributes工具的使用
在Controller中用户保存或修改后,为了防止用户刷新浏览器(F5)导致表单重复提交,一般在保存或修改操作成功之后会redirect到一个结果页面(不是forward),
同时可携带参数,如操作成功的提示信息等等。
因为是Redirect(重定向),request里的的值(getAttribute())在重定时超越作用域值会无法过去。
Spring在3.1提供了 个新的能力--RedirectAttributes,原理是把值放在session中重定向完成后再清空sesison。
反复按F5,操作成功的提示信息也不会再次出来(总共只出现一次),效果很理想。
使用方法:redirectAttributes.addFlashAttribute("flag", 10);//只显示一次,第二次刷新就不显示
重定向到Controller时,想取出"flag",可以使用如下方法:
Map<String, Object> modelMap = (Map<String, Object>)RequestContextUtils.getInputFlashMap(request);
重定向到Controller时,想取出"flag",可以使用如下方法:
@ModelAttribute (value="flag") 注:request.getParameter("")\request.getAttribute(name)都无法取出来
redirectAttributes.addAttribute("param", value); 这种方式就相当于在url后面拼接参数再重定向。
如果:URL是: /accounts/{id } 这种的,应如下写
redirectAttrs.addAttribute("id", account.getId());
redirectAttrs.addFlashAttribute("message", "Account created!");
return " redirect:/accounts/{id }";
Spring mvc 内容协商
问题描述:浏览器使用*.htm的URL,发起ajax请求,服务端使用@ResponBody注解响应json串。浏览器无法收到正确的结果,状态码406.
结果:spring mvc的这个问题找到原因了,并解决了,不用换后缀了。
原因分析:spring mvc 4.0新特性,会根据 *.htm、*.json、*.xml 后缀分析出要返回的内容的类型,叫“内容协商”。 它适合于 不拦截后缀的spring配置方案。但我们的spring配置方案是,前台拦截*.htm,后台拦截*.do。 我们的开发框架,无论请求html\json\xml ,前台都拦截*.htm,后台都拦截*.do。 所以spring mvc 4.0新特性,对我们不适用,也用不上,把它关闭就行了, 就像spring 3.0一样了,这就是我们所熟悉的spring。 spring mvc 支持3种内容协商方式:1、根据后缀,2、根据请求头,3、根据参数。我通过配置,关闭了1、2 两种方案。