Springmvc
- 回顾
- 理解MVC设计模式
- 视图(View)-对应组件:JSP或者HTML文件
- 控制器(Controller)-对应组件:Servlet
- 模型(Model) -对应组件:JavaBean
- MVC 优点
- 多视图共享一个模型,大大提高代码的可重用性
- MVC三个模块相互独立,松耦合架构
- 控制器提高了应用程序的灵活性和可配置性
- 有利于软件工程化管理
- 完美的系统架构 = 松耦合+高重用性+高扩展性
- 理解MVC设计模式
- Spring MVC框架搭建步骤
- 下载jar文件并导入工程
- spring-web-3.2.13.RELEASE.jar
- spring-webmvc-3.2.13.RELEASE.jar
- 配置文件
- 在web.xml中配置Servlet
- 创建Spring MVC的配置文件
- 创建Controller-处理请求的控制器
- BeanNameUrlHandlerMapping
- 创建View-jsp
- 部署运行
- 下载jar文件并导入工程
- Web.xml
-
web.xml <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
-
- Springmvc.xml
-
<bean name="/index.action" class="com.company.controller.IndexController"></bean> <!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"></property> </bean>
-
- 创建Controller
-
IndexController public class IndexController extends AbstractController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { System.out.println("hello, SpringMVC"); return new ModelAndView("index"); } }
-
- 注解驱动控制器
- 基于注解的处理器
-
<context:component-scan />
-
-
@Controller
- 标注一个普通的JavaBean成为可以处理请求的控制器
- @RequestMapping
- 通过请求URL进行映射
- 配置MVC注解驱动
-
<mvc:annotation-driven /><!-- 配置注解驱动 -->
- 自动注册DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter
- 提供一些列:数据绑定,数字和日期的format @NumberFormat, @DateTimeFormat, xml,json默认读写支持
-
- 基于注解的处理器
-
SpringMVC请求的流程
- Spring MVC体系结构
- DispatcherServlet(前端控制器)
- web.xml中配置
- Spring MVC最核心的类
- Handler(处理器):对应MVC中C(Controller)
- 标注了@RequestMapping的所有方法都可以看作是一个Handler
- 作用:实际处理请求
- 类型:Object
- ModelAndView(视图解析器)
- 逻辑视图名
- 模型对象
- DispatcherServlet(前端控制器)
- 核心组件
- HandlerMapping(处理器映射)
- BeanNameUrlHandlerMapping(默认)
- 将请求URL映射到同名的控制器Bean上
- DefaultAnnotationHandlerMapping
- 将请求映射到标注@RequestMapping注解的控制器和处理方法上
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping(默认)
- HandlerAdapter(适配器)
- RequestMappingHandlerAdapter
- AnnotationMethodHandlerAdapter
- ViewResolver(视图解析器)
- InternalResourceView
- HandlerMapping(处理器映射)
- Springmvc框架特点
- 清晰地角色划分
- 灵活的配置功能
- 提供了大量的控制器接口和实现类
- 真正做到了View层的实现无关(JSP,VUE,angularjs)
- 国际化支持
- 面向接口编程
- Spring提供了web应用开发的一整套流程,不仅仅MVC,他们之间可以很方便的结合一起
- SpringMVC参数传递,转发跳转
- 处理器映射
- 方式1
-
@RequestMapping("/welcome") public String index(String username){ return "index"; }
-
- 方式2
-
@RequestMapping("/welcome") public String index(@RequestParam String username){ return "index"; }
-
- 方式3
-
@RequestMapping("/welcome") public String index(@RequestParam(value="username",required=false) String username) { return "index"; }
-
- 方式1
- @RequestParam
- value:参数名称
- defaultValue:默认值
- required:是否必须
- @RequestMapping
- 标注在类定义处
- 标注在方法定义处
- 映射规则
- 通过请求URL进行映射
- 通过请求参数进行映射
- 若选择方法参数直接入参的话,方法入参名必须与请求中参数名保持一致
- 通过请求方法进行映射
- GET
- POST
-
@RequestMapping(value="/welcome", method=RequestMethod.GET,params="username")
- 处理器映射
-
如何将模型数据传递给视图?
- ModelAndView
- 包含视图信息和模型数据信息
- 常用方法
- 添加模型数据
- ModelAndView addObject(String attributeName,Object attributeValue);
- ModelAndView addAllObjects(Map<String,?> modelMap);
- 设置视图
- void setView(View view);
- void setViewName(String viewName);
- 添加模型数据
-
12.如何将模型数据传递给视图? (1)ModelAndView ①包含视图信息和模型数据信息 ②常用方法 1)添加模型数据 a.ModelAndView addObject(String attributeName,Object attributeValue); b.ModelAndView addAllObjects(Map<String,?> modelMap); 2)设置视图 a.void setView(View view); b.void setViewName(String viewName);
-
Model
- 数据结构:Map类型
- 常用方法:添加模型数据
-
Model.addAttribute(String attributeName,Object attributeValue);
-
@RequestMapping("/index2") public String index2(String username,Model model){ logger.info("welcome username : " + username); model.addAttribute(username); User user = new User(); user.setUserName(username); model.addAttribute(user); return "index"; }
- Model其实就是一个Map的数据结构,那么是否可以使用Map作为处理方法入参?
- ModelAndView
- InternalResourceViewResolver
- prefix
- suffix
-
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
- Spring的常用标签
- @ModelAttribute
- 不仅仅和从页面中获取对象的所有属性,而且可以将对象放入request当中
- @DateTimeFormat(pattern="yyyy-MM-dd")的使用
- 设置对应日期属性的字符串格式
-
/** * @ModelAttribute 不仅仅和从页面中获取对象所有属性, * 而且可以将对象放入request当中 * @param user * @return * @ModelAttribute 的使用 * @DateTimeFormat(pattern="yyyy-MM-dd")的使用 */ @RequestMapping("/add") public String add(@ModelAttribute("user") User user){ System.out.println(user.getUserName()); System.out.println(user.getPassWord()); System.out.println(user.getBirthday()); return "showuser"; }
- @ModelAttribute
- @ModelAttribute
- 不仅仅和从页面中获取对象的所有属性,而且可以将对象放入request当中
- @DateTimeFormat(pattern="yyyy-MM-dd")的使用
- 设置对应日期属性的字符串格式
- Struts2和Springmvc的对比
- Struts2 中 result
- 字符串 一个对应一个 View视图
- springmvc 对于跳转这件事,简化!(不用配置,可以使用字符串自动跳转)
- 但是如果路径特别深,需要 "视图解析器",在spring-servlet.xml中配置
- 除去了前缀,后缀,使用ModelAndView,将视图页面和对象放到ModelAndView对象当中,实现跳转功能
- Struts2底层实现是过滤器,Springmvc底层是servlet
- 页面跳转的多种方式
- 使用字符串:forward:/页面全名称
-
转发到对应的页面: return "forward:/welcome.jsp";
-
-
使用视图解析器
-
路径特别深,需要 "视图解析器",在spring-servlet.xml中配置 return "admin/wel"; 相当于: return "forward:/WEB-INF/jsp/admin/wel.jsp";
-
- 重定向到指定路径,可以是互联网上的任意地址:redirect:网址
-
return "redirect:http://www.baidu.com";
-
- 使用ModelAndView设置跳转位置
-
ModelAndView mv = new ModelAndView(); mv.setViewName("admin/wel"); return mv;
-
- 使用字符串:forward:/页面全名称
- 使用REST风格
- REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
-
@RequestMapping(value="/view/{id}", method=RequestMethod.GET) public String view(@PathVariable String id,Model model){ //......中间代码省略 }
-
- REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的一种软件架构风格。它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。
- pringmvc文件上传
- MultipartResolver接口
- ①用于处理上传请求,将上传请求包装成可以直接获取文件的数据,方便操作
- 两个实现类
- StandardServletMultipartResolver
- 使用了Servlet3.0标准的上传方式
- CommonsMultipartResolver
- 使用了Apache的commons-fileupload来完成具体的上传操作
- StandardServletMultipartResolver
- MultipartResolver接口
- 文件上传的实现步骤
- 导入jar文件
- commons-io-2.4.jar
- commons-fileupload-1.2.2.jar
- 配置MultipartResolver(springmvc-servlet.xml)
- 使用CommonsMultipartResolver配置一个MultipartResolver解析器
-
<bean id="multipartResolver" class="org.springframework.web.multipart.commons. CommonsMultipartResolver"> <property name="maxUploadSize" value="5000000"/> <property name="defaultEncoding" value="UTF-8"/> </bean>
-
<!-- 处理文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="gbk" /> <!-- 默认编码 (ISO-8859-1) --> <property name="maxInMemorySize" value="10240" /> <!-- 最大内存大小 (10240) --> <property name="uploadTempDir" value="/upload/" /> <!-- 上传后的目录名 --> <property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1为无限止(-1) --> </bean>
- 编写文件上传表单页
- method="POST" enctype="multipart/form-data" 指定表单内容类型,支持文件上传
- <input type="file" name="file"/> 用来上传文件的file组件
-
<form action="upload.action" method="post" enctype="multipart/form-data"> 姓名:<input type="text" name="name" /> 头像:<input type="file" name="file" /> <input type="submit" /> </form>
- 导入jar文件
-
文件上传中的业务流程
- 使用上传类,方法
- MultipartFile
- Spring MVC会将上传文件绑定到MultipartFile对象中,并通过该对象完成文件的上传操作
- 提供的方法
- CommonsMultipartFile类实现:MultipartFile接口
- MultipartFile
- 文件上传中需要注意的细节
- File.separator
- Windows、Linux自适应路径分隔符
- 低入侵性的代码实现
- 必须对上传文件进行重命名
- 原因
- 原文件名存在中文 乱码问题
- 原文件名与服务器上已有文件重名 覆盖问题
- 重新定义上传文件名(保证不重名)
- 当前系统时间+随机数+“_Personal.jpg”
- 原因
- 上传位置:
- 指定磁盘路径
- 文件上传成功后
- 获取文件上传 文件的url访问地址
- 页面展示该文件,并可以对该文件进行下载。
- File.separator
- Springmvc处理AJAX请求
- 相关jar包:
- jackson-all-1.8.10.jar
- fastjson-1.2.47.jar(阿里巴巴)
- 以上两个jar包都可以处理AJAX请求
- 相关jar包:
- 在控制器中增加方法
- 使用注解:@ResponseBody
- 该注解设置返回值为JSON类型
- @ResponseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON
- 使用注解:@ResponseBody
- 使用对象返回,Json自动解析
-
@RequestMapping(value="/byid2") public @ResponseBody User findById2(int id){ User user = new User(); user.setId(id); user.setName("小霞"); user.setPhone("188"); //这里可以使用JSON工具转换为字符串 return user; }
- 需要jackson-all-1.8.10.jar包,否则无法解析该类对象
-
- 接收JSON类型的对象
- 创建一个Controller方法
- 该方法的参数上必须加上注释“@RequestBody”
-
@RequestMapping("/receive") public void receive(@RequestBody String name){ String str = "welcome "+name; System.out.println(str); }
-
-
注意:
- @RequestBody接收的是一个Json对象的字符串,而不是一个Json对象
- 用 JSON.stringify(data)的方式就能将对象变成字符串
-
<script type="text/javascript"> function sendJson(){ //创建对象 var user={ name:"lisa", age:22, phone:18898472345 } // 把JS当中的对象转换成为字符串 // 1、jquery.param name="小丽"&phone="110"&age=20 // 2、json字符串 // 3、在Controller中需要接收一个JSON的字符串,不能直接接收JSON对象 var str = JSON.stringify(user); $.ajax({ type:"post", url:"receive2.action", contentType:'application/json;charset=utf-8', data:str, success: function(data){ $("#h").html(data); } }); }</script>
- Controller中处理
-
@RequestMapping("/receive2") public @ResponseBody String receive2(@RequestBody User user) { String str =user.getName(); System.out.println(str); return str; }
- 解决中文乱码问题:
-
/* * 中文乱码问题得到解决 * 原理: 手动给对应的Accept返回制定格式编码数据。 * 发现produces设置多个Accept只有第一个的charset是有用的, */ @RequestMapping(value = "/receive3", produces={"text/html;charset=UTF-8;","application/json;"}) public @ResponseBody String receive3(@RequestBody String name) { String str = "welcome " + name; System.out.println(str); return str; }
-
- 将集合转换成为一个JSON类型的字符串
-
@RequestMapping(value="/receive3",produces={"text/html;charset=UTF-8;","application/json;"}) public @ResponseBody String receive3(@RequestBody String name){ String str = "welcome : "+ name; List<User> list = new ArrayList<>(); list.add(new User("zs",12)); list.add(new User("ls",13)); list.add(new User("ww",14)); list.add(new User("zl",15)); // 使用阿里巴巴的fastjson.jar return JSONArray.toJSONString(list); }
-
- 在JS当中,将JSON格式的字符串转换成为一个JSON对象
-
$.ajax({ type:"post", url:"receive3.action", data:n, contentType:'application/json;charset=utf-8', success:function(data){ // 返回响应的字符串,需要转换成为JSON对象 console.log(data); $("#s").html(data); var json = JSON.parse(data); var html = ""; $.each(json,function(i,item){ html += "<li><span>"+i+"</span>" html += "<strong>"+item.name+"</strong></li>"; }) $("#d").html(html); } });
-
- Springmvc拦截器
- 概念:
- Spring Web MVC的处理器拦截器
- 类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
- 常见的应用场景
- 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
- 权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
- 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
- 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
- OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现。
- 概念:
- Springmvc拦截器和过滤器的区别
- 拦截器的配置
- 在Springmvc-servlet.xml中增加
-
<!-- 拦截器 --> <mvc:interceptors> <!-- 多个拦截器,顺序执行 --> <mvc:interceptor> <mvc:mapping path="/entryOrJsonController/*" /> <bean class="com.wy.interceptor.CommonInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
- 创建拦截器
-
package org.springframework.web.servlet; public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception; }
-
- 开发步骤
- 创建Interceptor,实现:HandlerInterceptor接口
- 注意:
- HandlerInterceptor的包:org.springframework.web.servlet
- preHandle方法必须返回true否则不能继续
- return true;
- 注意:
- 配置springmvc-servlet.xml
-
<mvc:interceptors> <bean class="cn.smbms.interceptor.MyInterceptor"></bean> <!-- 拦截所有springmvc的url! --> </mvc:interceptors>
-
- 创建Interceptor,实现:HandlerInterceptor接口
- 多个拦截器的执行顺序
觉得有点用记得给我点赞哦!
这篇文章就到这里啦,如果觉得有收获的话,不妨给一个赞喔;文章中涉及的内容肯定是不全面的,欢迎大家评论区留言补充。