SpringMVC小结

入门程序

11. 创建maven项目需要选择webapp骨架(org.apache.maven.archetypes:maven-archetype-webapp),还有添加额外配置(archetypeCatalog internal),防止创建maven的web项目慢的问题。 22. 引入依赖(修改maven的jdk编译环境为1.8) 3 spring-context 4 spring-web 5 spring-webmvc 6 servlet-api(scope--->provide) 7 jsp-api(scope--->provide) 8 3. 核心配置文件的配置(mvc和context约束) 9 1. 开启注解扫描 <context:component-scan base-package /> 10 2. 视图解析器对象 <bean class="InternalResourceViewResolver"> 拼接字符串的前面 和 拼接字符串的后面的两个set </bean> 11 3. 开启SpringMVC框架注解支持 <mvc:annotation-driven/> 124. web.xml的配置 13 1. 配置前端控制器,加载核心配置文件 14 <servlet> 15 <servlet-name>dispatcherServlet</servlet-name> 16 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 17 <init-param> 18 <param-name>contextConfigLocation</param-name> 19 <param-value>classpath:springmvc.xml</param-value> 20 </init-param> 21 <load-on-startup>1</load-on-startup> 22 </servlet> 23 <servlet-mapping> 24 <servlet-name>dispatcherServlet</servlet-name> 25 <url-pattern>/</url-pattern> 26 </servlet-mapping> 275. 编写Controller和jsp页面进行测试 28 1. 使用@Controller注解和jsp配置视图解析器进行测试 29 2. 使用@RestController进行测试(推荐,相对简单)

MVC的执行流程

11. 配置文件的加载: 2 启动项目,加载web.xml文件 3 创建Servlet(前端/核心控制器-->指挥中心)的对象 4 springmvc.xml的加载 5 注解扫描加载SpringIOC的bean(@Controller) 6 视图解析器 7 SpringMVC注解支持(@RequestMapping) 82. 请求响应: 9 客户端发送请求------> 核心控制器(进入SpringMVC的请求流程)-----> 10 调用HandlerMapping(处理器映射器),匹配被@Controller注解注解的类中的@RequestMapping -----> 11 调用HandlerAdapter(处理器适配器)执行handle(Controller中声明的方法),handle返回结果(ModelAndView,模型视图,封装结果和视图)给HandlerAdapter -------> 12 HandlerAdapter返回MOdelAndView给核心控制器,核心控制器拿到结果去找视图解析器(ViewResolver)进行视图解析-----> 13 视图解析器进行物理拼接形成具体的路径(View),返回给核心控制器 ------> 14 核心控制器进行视图渲染,填充数据到reuqest域中,response响应返回给客户端 153. 组件介绍 16 前端/核心控制器: 中央调度,协调作用 17 处理器映射器(HanderMapping): 根据请求的url查找Handler 18 处理器适配器(HanderAdapter): 执行Handle 19 ModelAndView: 模型及视图,封装结果视图 20 ViewResolver: 视图解析器,解析逻辑视图 21 Handle: 程序员编写业务逻辑处理,也就是Controller的方法

请求参数绑定

11. 基本数据类型绑定: 2 原则: 请求后拼接的参数与handle的参数名保持一致 32. JavaBean对象的绑定 4 1. 简单Bean直接使用form表单,name属性的值为Bean对象的属性名 5 2. Bean内包含另一个Bean,name的值使用属性.属性的方式 6 3. list使用属性下标点属性 ------> list[0].name 7 4. map使用属性key属性的方式 -----> list['one'].name 8 93. 中文乱码问题: 10 post乱码可以在web.xml中配置Spring提供的CharacterEncodingFilter 11 get乱码: 12 tomcat8之前,在tomcat的配置文件中配置URIEncoding="utf-8" 13 new String(username.getBytes("ios-8859-1"),"UTF-8")的方式 14 154. 日期类型转换: 16 1. 自定义类实现Converter<S,T>接口,使用DateFormat进行格式的转换. 17 2. 在springmvc中配置自定义转换器(ConversionServiceFactoryBean). 18 * 注意是context包下的转换器 19 * 配置converters属性 20 * 注入自定义转换器的bean

SpringMVC使用原生的Servlet

Handler方法的形参设置HttpServletRequest和HttpServletResponse就可以获取到所有的原生Servlet对象了

注解介绍

11. @RequestMapping: 2 * 作用位置: 3 1. 类上: 窄化请求路径,业务隔离 4 2. 方法上: url请求映射 5 * 属性: 6 1. value: 指定请求路径,与path属性一样 7 2. method: 指定请求方式,值有GET,POST,DELETE等等(枚举类型,RequestMethod) 8 3. params: 用于指定限制请求参数条件 9 4. headers: 用于指定请求头 10 112. @RequestParam: 12 * 作用 : 在页面传递的参数名与后台不一致的时候需要使用该注解,作用于参数之前 13 * 属性 : 14 1. name/value : 指定页面传递的参数名 15 2. required : 是否为必须,默认为true,表示该参数必须传递 16 3. defaultValue : 给定参数一个默认值,当有默认值的时候required属性感觉就无效了 17 183. @RequestBody 19 * 作用: 用于获取请求体的内容.(get请求不适用,POST请求适用) 20 214. @PathVariable(基于Restful风格的url支持) 22 * 作用在参数之前,目的是获取请求url中的占位符(参数)的信息 23 /test/{sid} ----> 请求路径 24 @PathVaribale(name="sid") Integer id ---> 方法的参数 25 /test/10 ----> 客户端的访问路径 26 * Restful的理解: 27 通过请求参数决定对哪个资源进行操作 28 通过请求方式决定采用何种操作(post,delete,put,get) 29 305. HiddenHttpMethodFilter: 31 浏览器的form表单只支持get和post请求,要洗那个发送put或delete请求,需要借助SpringMVC提供的HiddenHttpMethodFilter. 32 使用: 33 1. 在web中配置HiddenHttpMethodFilter过滤器 34 2. 在表单中添加隐藏域,<input type="hidden" name="_method" value="PUT"/> 35 3. 定义handle,声明method为RequestMethod.PUT 36 376. @RequestHeader 38 用于获取请求消息头,作用在方法参数之前 39 value属性可以指定获取哪个请求头信息(User-Agent比较常用) 40 417. @CookieValue 42 * 获取指定名称cookie的值 43 * value属性指定cookie名称(JSESSIONID) 44 458. @ModelAttribute 46 * 作用位置: 47 1. 方法上: 被@ModelAttribute注解修饰的方法表示该方法会在当前Controller的人格一个方法执行前先执行 48 应用在表单提交实体数据不完整的情况下,为实体数据添加内容. 49 方法有返回值(直接返回user),springmvc会将方法执行的返回值,存放在Model对象,最终会存放在Request中: 50 考虑在修改的时候根据id获取实体,方法返回实体,前台只需要传递修改的内容就可以了. 51 方法无返回值,springmvc会将方法形参中的map中的数据存放在Model对象,最终会存放在Request中: 52 在方法中使用map保存数据,在Handler的参数前使用@ModelAttribute(name="key")获取 53 2. 形式参数前(需制定value(key)属性): 54 获取request中获取对应的value的数据 55 569. @SessionAttributes(只能作用于类上,指定属性) 57 * 用于多个Handler间的参数共享(将数据存放在session域) 58 * 使用Model对象的addAttribute方法存放数据 59 * 使用ModelMap对象的get方法来获取session数据 60 * 使用setComplete()方法清空session域的数据(使用的是SessionStatus对象)

Handler返回值类型

11. 字符串:简单字符串是逻辑视图名称 2 * 使用返回的字符串,经过视图解析器,拼接前缀后缀,跳转到真实路径 32. void ===> 原始的Servlet操作 4 * 请求路径默认是: 前缀 + handle访问路径 + 后缀 5 * 使用原生Servlet进行跳转和携带参数,但是注意这个时候不会执行ViewResolver,所以必须写全路径,这个需要注意.在handle最后加个return;防止handle跳转方法完成后继续执行后续的代码. 6 * 还有需要注意重定向是无法访问WEB-INF目录下的东西. 7 * 直接响应数据: response.getWriter().print("content");注意处理乱码问题 83. ModelAndView 9 * ModelAndView对象: ModelAndView mv = new ModelAndView(); 10 * 可以存放数据到对象,使用mv.addObject("key","value");实际还是存放在Model中,最后还是request域中 11 * 存放跳转的页面: 使用mv.setViewName("success"); 124. forward和redirect关键字的用法(返回类型还是String): 13 * 返回的写法不一样,有了forward关键字后就不能调用视图解析器. 14 return "forward:/WEB-INF/pages/success.jsp" 15 * return "redirect:/index.jsp"; 重定向不能直接跳转到WEB-INF的目录下,并且redirect关键字不用添加项目目录 16 * return "forward:testString"; 转发到指定的的Handle 17 return "redirect:/user/testString";重定向到指定的的Handle

响应JSON数据

11. 在springmvc配置文件中配置静态资源不拦截(因为前端控制器会拦截所有资源): 2 <mvc:resources mapping="/js/**" location="/js/" />,表示js文件下面的所有文件都不拦截 3 <mvc:resources mapping="/css/**" location="/css/" /> 4 <mvc:resources mapping="/images/**" location="/images/" /> 5 > 注意静态资源放在web-app下 6 7 上面的配置在mapping的后面也一定要加**,否则会失败(在我电脑上是这样),如果还是失败,可以试试在web.xml中配置: 8 <servlet-mapping> 9 <servlet-name>default</servlet-name> 10 <url-pattern>*.js</url-pattern> 11 </servlet-mapping> 12 132. ajax请求返回json数据: 14 * $.ajax({ 15 url:"user/testAjax", 16 type:"POST", 17 contentType:"application/json;charset=utf-8", 18 data:'{"username":"hehe","password":"123456","age":24}', 19 dataType:"json", 20 success:function(data){ 21 alert(data); 22 } 23 24 }) 253. 自动转换,将json字符串转换为对象,需要额外依赖jackson的jar包: 26 <dependency> 27 <groupId>com.fasterxml.jackson.core</groupId> 28 <artifactId>jackson-databind</artifactId> 29 <version>2.9.7</version> 30 </dependency> 31 <dependency> 32 <groupId>com.fasterxml.jackson.core</groupId> 33 <artifactId>jackson-core</artifactId> 34 <version>2.9.7</version> 35 </dependency> 36 <dependency> 37 <groupId>com.fasterxml.jackson.core</groupId> 38 <artifactId>jackson-annotations</artifactId> 39 <version>2.9.7</version> 40 </dependency> 41 42 接收json数据需要使用 ==@RequestBody== 43 获取请求中的数据 44 如果请求的参数是json格式,使用pojo接受,但是注意参数名和实体属性名一致 45 46 响应json数据需要使用 ==@ResponseBody== 47 直接将方法执行的返回值响应给客户端 48 如果是pojo,将pojo对象转化为json字符串

传统方式文件上传(了解):

11. 表单的enctype属性取值必须是: multipart/form-data 2 method属性值必须是post 3 提供你文件选择域: <input type="file" /> 42. 三方组件实现,引入额外依赖: 5 commons-fileupload 6 commons-io 73. 传统方式文件上传(后台代码实现): 8 创建文件的上传路径(path),使用request.getSession().getServletContext().getRealPath("/uploads"); 9 核心解析器: 10 DiskFileItemFactory ---> 磁盘文件的工厂对象 11 ServletFileUpload ---> 文件上传的核心解析器,传入工厂对象 12 解析request对象 13 List<FileItem> list = ServletFileUpload.parseRequest(request); 14 文件上传: 15 遍历list,判断是否为普通表单项(isFormFiled),不是则进行上传 16 获取文件上传名,修改上传名为唯一上传名(考虑使用UUID或者日期) 17 fileItem.write(new File(path,filename));path表示父级目录,filename表示修改后的文件名. 18 最后使用fileItem.delete(); 用来删除临时文件 19 20 /** 21 * 文件上传 22 * @return 23 */ 24 @RequestMapping("/fileupload1") 25 public String fileuoload1(HttpServletRequest request) throws Exception { 26 System.out.println("文件上传..."); 27 28 // 使用fileupload组件完成文件上传 29 // 上传的位置 30 String path = request.getSession().getServletContext().getRealPath("/uploads/"); 31 // 判断,该路径是否存在 32 File file = new File(path); 33 if(!file.exists()){ 34 // 创建该文件夹 35 file.mkdirs(); 36 } 37 38 // 解析request对象,获取上传文件项 39 DiskFileItemFactory factory = new DiskFileItemFactory(); 40 ServletFileUpload upload = new ServletFileUpload(factory); 41 // 解析request 42 List<FileItem> items = upload.parseRequest(request); 43 // 遍历 44 for(FileItem item:items){ 45 // 进行判断,当前item对象是否是上传文件项 46 if(item.isFormField()){ 47 // 说明普通表单向 48 }else{ 49 // 说明上传文件项 50 // 获取上传文件的名称 51 String filename = item.getName(); 52 // 把文件的名称设置唯一值,uuid 53 String uuid = UUID.randomUUID().toString().replace("-", ""); 54 filename = uuid+"_"+filename; 55 // 完成文件上传 56 item.write(new File(path,filename)); 57 // 删除临时文件 58 item.delete(); 59 } 60 } 61 62 return "success"; 63 }

SpringMVC的文件上传(掌握)

11. springmvc.xml配置文件上传解析器: 2 类为CommonsMultipartResolver 3 id为multipartResolver,这个不能改变(这个很重要) 4 属性为:maxUploadSize,值为10485760 5 <!--配置文件上传解析器--> 6 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 7 <property name="maxUploadSize" value="10485760"/> 8 </bean> 9 102. handler的形参: (HttpServletRequest request,MultipartFile upload) 11 表单的隐藏域的name属性必须和handler的形参MultipartFile的对象的名字一样. 12 <form action="/file/fileupload" method="post" enctype="multipart/form-data"> 13 文件上传:<input type="file" name="upload"> 14 <input type="submit" value="提交"> 15 </form> 163. handler的步骤: 17 1. 创建文件上传目录path 18 2. 获取文件名,修改文件名为唯一名字 19 3. 使用upload.transferTo(new File(newFileName))就完成了 20 21 @RequestMapping("fileupload") 22 public String fileUpload(HttpServletRequest request, MultipartFile upload) throws Exception { 23 // 创建文件上传目录 24 String realPath = request.getSession().getServletContext().getRealPath("/uploads/"); 25 // 创建File 26 File file = new File(realPath); 27 // 判断目录是否存在 28 if(!file.exists()){ 29 // 创建该文件夹 30 file.mkdirs(); 31 } 32 // 获取文件名,并修改文件名为唯一 33 String name = upload.getOriginalFilename(); 34 // 生成uuid 35 String replace = UUID.randomUUID().toString().replace("-", ""); 36 // 唯一文件名 37 String fileName = replace + "_" + name; 38 // 拼接最后的路径 39 String newPath = realPath + fileName; 40 41 // 进行文件的上传 42 upload.transferTo(new File(newPath)); 43 44 45 return "hello"; 46 }

SpringMVC跨服务器方式的文件上传

11. 搭建图片服务器 2 1. 修改tomcat端口号(修改3个地方) 3 2. 修改tomcat的conf下的web.xml,修改readonly属性为false 4 3. 在webapps下新建uploads目录 52. 加入依赖: 6 jersey-core 7 jersey-client 83. 步骤: 9 创建客户端的对象Client.create() 10 和图片服务器建立连接(client.resource()) 11 上传文件(webResource.put(new File(newFileName))) 12 13 @RequestMapping("/fileupload3") 14 public String fileuoload3(MultipartFile upload) throws Exception { 15 System.out.println("跨服务器文件上传..."); 16 17 // 定义上传文件服务器路径 18 String path = "http://localhost:9090/uploads/"; 19 20 // 说明上传文件项 21 // 获取上传文件的名称 22 String filename = upload.getOriginalFilename(); 23 // 把文件的名称设置唯一值,uuid 24 String uuid = UUID.randomUUID().toString().replace("-", ""); 25 filename = uuid+"_"+filename; 26 27 // 创建客户端的对象 28 Client client = Client.create(); 29 30 // 和图片服务器进行连接 31 WebResource webResource = client.resource(path + filename); 32 33 // 上传文件 34 webResource.put(upload.getBytes()); 35 36 return "success"; 37 }

SpringMVC的异常处理

11. 不处理异常造成的问题: 2 * 用户体验差 3 * 系统安全性容易出现问题 42. 处理: 5 1. 编写自定义异常处理类,继承Exception 6 public class MyException extends Exception { 7 private String msg; 8 public MyException(String msg) { 9 this.msg = msg; 10 } 11 public String getMsg() { 12 return msg; 13 } 14 public void setMsg(String msg) { 15 this.msg = msg; 16 } 17 } 18 2. 编写异常处理器,实现HandlerExceptionResolver 19 public class MyExceptionResolver implements HandlerExceptionResolver { 20 @Override 21 public ModelAndView resolveException(HttpServletRequest httpServletRequest, 22 HttpServletResponse httpServletResponse, 23 Object o, 24 Exception e) { 25 // 创建自定义异常类 26 MyException myException = null; 27 // 转换 28 if(e instanceof MyException){ 29 myException = (MyException)e; 30 } else{ 31 myException = new MyException("程序遇到错误,但不是自定义异常类"); 32 } 33 // 创建ModelAndView 34 ModelAndView mv = new ModelAndView(); 35 mv.addObject("errormsg",myException.getMsg()); 36 mv.setViewName("error"); 37 return mv; 38 } 39 } 40 3. 配置异常处理器,SpringMVC中配置异常处理器(也就是声明Bean) 41 <!--配置异常处理器 --> 42 <bean id="myExceptionResolver" class="com.itheima.exception.MyExceptionResolver"></bean> 43 4. Controller如何进行编写呢? 44 @RequestMapping("exce") 45 public String testException() throws MyException { 46 try { 47 int i = 1 / 0; 48 } catch (Exception e) { 49 e.printStackTrace(); 50 throw new MyException("程序错误"); 51 } 52 return "hello"; 53 }

SpringMVC的拦截器

11. 拦截器: 对处理器进行预处理和后处理(AOP的思想) 22. 拦截器链: 多个拦截器按一个次序形成一个链,执行顺序考虑栈的结构,前置代码是入栈,后置代码是出栈 33. 过滤器(filter)与拦截器(interceptor): 4 过滤器什么都可以拦截,并且是属于servlet的,任何项目都可以用 5 拦截器属于SpringMVC的,只有在SpringMVC的项目中使用,并且只能拦截控制器的访问 64. 使用拦截器的步骤: 7 1. 编写拦截器: 类实现HandlerInterceptor,实现3个方法: 8 boolean preHandler(): 预处理,handler执行前执行 9 true: 放行,如果有多个拦截器,放行到下一个拦截器,没有后续拦截器,执行Handler方法 10 false: 不放行, 到此为止,不继续向下执行 11 postHandler(): 后处理,handler之后,跳转页面之前执行 12 afterComletion(): 最后执行的方法,也就是成功返回页面后执行的代码 13 14 public class MyInterceptor implements HandlerInterceptor { 15 /** 16 * Handler执行之前执行 17 * @param request 18 * @param response 19 * @param handler 20 * @return 21 * @throws Exception 22 */ 23 @Override 24 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 25 System.out.println("preHandle======================="); 26 return true; 27 } 28 29 /** 30 * Handler执行之后,跳转页面之前 31 * @param request 32 * @param response 33 * @param handler 34 * @param modelAndView 35 * @throws Exception 36 */ 37 @Override 38 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 39 System.out.println("postHandle======================="); 40 } 41 42 /** 43 * 跳转页面之后执行 44 * @param request 45 * @param response 46 * @param handler 47 * @param ex 48 * @throws Exception 49 */ 50 @Override 51 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 52 System.out.println("afterCompletion============================="); 53 } 54 } 55 2. 配置拦截器: 56 <mvc:interceptors> 57 <!--可以配置对个interceptor,表示多个拦截器--> 58 <mvc:interceptor> 59 <!--拦截的具体方法--> 60 <mvc:mapping path="/**"/> <!--所有的方法都拦截--> 61 <!--不要拦截的具体方法,和上面那个配置一个就好--> 62 <!-- <mvc:exclude-mapping path=""/>--> 63 <!--配置拦截器对象--> 64 <bean class=""/> 65 </mvc:interceptor> 66 67 </mvc:interceptors> 68 69 70 <!--配置拦截器--> 71 <mvc:interceptors> 72 <mvc:interceptor> 73 <mvc:mapping path="/**"/> 74 <bean class="com.itheima.interceptor.MyInterceptor"/> 75 </mvc:interceptor> 76 </mvc:interceptors> 77 78 79 3. 前端: 80 <% System.out.println("hello.jsp================"); %> 81 82 执行效果: 83 preHandle======================= 84 interceptor=================== 85 postHandle======================= 86 hello.jsp================ 87 afterCompletion============================= 885. 拦截器的作用: 89 登录拦截器=======> 在prehandler()方法中获取session,判断有无用户,无用户跳转到登录.
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

KVM调整cpu和内存

一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid