SpringMVC入门学习三

今天是Springmvc学习的第三天,今天我将主要介绍一下: 常用注解的使用 关于非post、get请求的处理 文件上传与下载 拦截器 常用注解的使用 老大在此 @Controller @Controller放在类的上面,用于将一个类标记为Controller,处理DispatcherServlet分发的请求,当然真正处理请求的还是使用@RequestMapping注解的方法。 处理request URI的注解 @RequestMapping @RequestMapping是一个用来处理请求地址映射的注解,可用于类上面【代表模块】和方法上面【代表业务】 里面参数属性,其中所有的参数都可以传入数组的形式: value:代表请求的地址如"/login",可以写多个【使用数组】,只写它时,可以省略不写 name:value的别名,作用是一样的。 method:请求的method类型,里面要传入RequestMethod类型的数据,如GET,POST,PUT等等,可以指令多个(使用数组传递即可) 它的衍生品: @GetMapping:专门处理get请求 @PostMapping:专门处理Post请求 params:设置需要的参数,如果没有,请求就过不去,还可以设置参数是否等于或则不等于 // 当穿过来的参数data不为not才进行响应 @RequestMapping(value = "/test1",params = "data!=not") // 当穿过来的参数data为hava才进行响应 @RequestMapping(value = "/test1",params = "data=have") ps:中间注意别打空格 headers 指定request中必须包含某些指定的header值,该方法才会处理请求。 @RequestMapping(value="/hello",headers="Referer=https://baidu.com") consumes 消费者,指令请求提交内容的类型(Content-Type),例如可以限令必须为application/json;charset=UTF-8,指令多个使用数组形式 produces 生产者,指令放回的内容的类型,但是必须是请求头所包含的类型 @PathVariable 这个是restful风格的请求方式,用于将URL中的模板变量映射到方法的参数上面,这个在我的上一篇博客有所介绍。 共享数据 @ModelAttribute @ModelAttribute注解可以被应用在方法参数上面和方法声明上面。其中被@ModelAttribute注解的方法会优先于controller方法(被@RequestMapping注解)之前执行,因为模型对象优先于controller方法创建。 简单的来说,@ModelAttribute有两个作用,将数据保存在model上面【标注在方法上面】,将数据从model取出来【标注在参数里面】 将数据保存在model上面 使用@ModelAttribute注解无返回值方法 @ModelAttribute public void model1(Model model){ model.addAttribute("modle1","你好呀"); } @RequestMapping("/modleC") public String modleC(){ return "test"; } 其实这个就相当于 @RequestMapping("/modleC") public String modleC(Model model){ model.addAttribute("modle1","你好呀"); return "test"; } 注解有返回值的方法 /** * 注解有返回值的 * 在这种情况下,放回值对象会默认的放在隐藏的Model中。 * 其key为放回值 **类型** 首字母小写,当然也可以在@ModelAttribute * 加上value或则name的属性来指令key * @return */ @ModelAttribute public String modeler02(){ String Hello = "你好呀"; return Hello; //在这里面key为string } 与@RequestParam结合使用 @RequestParam的具体用法将在下面介绍 加入此时我们发送了一个这样的请求:/test/name=googboy // 取出get请求的参数name,将其存入modle中 @ModelAttribute("name") public String modeler02(@RequestParam()String name){ return name; } @RequestMapping("/test") public String test(){ return "test"; } 将数据从model取出来 假如此时有了一个model,key为name,value为Tom数据,那么我们可以通过@ModelAttribute将数据取出来。 @RequestMapping("/test") public String test(@ModelAttribute("name")String name){ // 输出是 名字是Tom System.out.println("名字是"+name); return "test"; } 保存数据 @SessionAttributes 假如希望在多个请求之间共用数据,则可以在控制器类上面标注一个@SessionAttributes,其中value指令是model中的哪一个存入session,type为数据类型,两者都可以放数组类型的数据。 取出数据 @SessionAttribute @SessionAttribute的作用很简单,就是获得session的值 假如此时有一个session key为name,value为Tom,获得session @RequestMapping("/test2") public String test2(@SessionAttribute("name") String name){ System.out.println("session结果是"+name); return "test"; } 假如此时不存在就会报错,这是可以使用required来确定是否必须 @RequestMapping("/test2") //非必须,同时value/name必须加上 public String test2(@SessionAttribute(value = "name",required = false) String name){ System.out.println("session结果是"+name); return "test"; } 对于取出参数的处理 @RequestParam @RequestParam主要是用于在Springmvc后台控制层获得参数,类似request.getParameter("name") 它有下列参数 value:value表示要取出的参数,当只有value这个参数时,可以省略不写。 name:value的别名,作用和value一样。 required:默认值是true,当传入的参数值不存在时,程序就会报错,这时候就可以将required设置为false。 defaultValue:当设置defaultValue时,会自动的将required设置为false,如果此时请求参数不存在,就会默认的将参数设置为defaultValue。当然,如果参数存在,defaultValue也就是不会发挥作用了。 举个栗子: @RequestMapping("/test3") public String test3(@RequestParam(value = "name",defaultValue = "TomCat") String name){ // 请求网址是: /test3 // 输出是 名字是TomCat System.out.println("名字是"+name); return "test"; } @RequestBody 这时候大家可能会问,既然有@RequestParam来处理方式了,为什么我们还要使用@RequestBody来获取参数呢? 这个主要主要是因为他们处理数据的类型Content-Type不一样 @RequestParam:处理application/x-www-form-urlencoded编码的内容,提交方式为Get,Post。 @RequestBody:通常是来处理非application/x-www-form-urlencoded编码格式的内容的数据,比如说application/json和application/xml。 既然是处理json数据,那么就需要使用json的jar包。 com.fasterxml.jackson.core jackson-databind 2.9.7 com.fasterxml.jackson.core jackson-core 2.9.7 com.fasterxml.jackson.core jackson-annotations 2.9.7 当发了一个如下所示的json请求时 $(document).ready(function () { $("button").click(function () { $.ajax({ url: "/test4", type:"post", data:JSON.stringify({ "name":"TODO" }), dataType:"json", contentType:"application/json; charset=utf-8", success:function (data) { console.log(data) } }); }); }); controller代码,在参数里面加上@RequestBody: @RequestMapping("/test4") public String test4(@RequestBody String name){ // 名字是{"name":"TOFO"} System.out.println("名字是"+name); return "test"; } 对于返回数据的处理 @ResposeBody 返回json数据 在大多数的情况下,我们不一定是想返回一个视图,只想返回一个json数据或者说xml数据,那么这时候我们就要使用@RequestBody了。@ResponseBody注解被应用于方法上,标志着响应会写到响应体里面去,而不是放到视图Model里面去。 首先在springmvc配置文件中,启动`` 那么就可以这样使用: @RequestMapping(value = "/test4") @ResponseBody public User test4(@RequestBody String name){ // 名字是{"name":"TOFO"} System.out.println("名字是"+name); User u = new User(); u.setName("小明"); u.setAge("17"); return u; } 返回xml数据 要导入额外的jacksonxml jar包 com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.9.7 // 由于要返回xml格式的数据,所以需要设置produces为application/xml // 使用MediaType里面的静态常量,可以防止写错 @ResponseBody @RequestMapping(value = "/test5",produces = org.springframework.http.MediaType.APPLICATION_XML_VALUE) public User test5(){ User u = new User(); u.setName("小红"); u.setAge("18"); return u; } SpringMVC关于非post、get请求的处理 在HTML5的规范中,表单元素唯二允许的HTTP的方法是GET和POST,但是如果我们想使用PUT或则DELET方法,那怎么办呢? 在浏览器中装作自己是post或则get请求,实际上是PUT请求
姓名
在web.xml文件中,从_method找到真正的http请求 加入 HiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter HiddenHttpMethodFilter springmvc springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml springmvc / 文件上传与下载 文件上传 文件上传同时也是使用form表单进行提交,一般我们的表单的提交是文本型的数据,实际上就是进行字符串的拼接。那么文件便不是这样的进行处理,这时候我们就要使用到multipart表单了。 首先我们的配置一个MultipartResolver来告诉DispatchServlet如何来处理multipart请求。 在Servlet3.0中,Spring会默认注册一个StandardServletMultipartResolver,我们只需要在web.xml启用就行。 /tmp 属性 作用 location 上传文件所存放的临时目录。必须指定 max-file-size 文件的最大大小,单位为字节。默认没有限制 max-request-size 请求的最大大小,单位为字节。默认没有限制 file-size-threshold 文件大小阈值,当大于这个阈值时将写入到磁盘,否则在内存中。默认值为0 前端代码
文件
控制文件上传的代码 @RequestMapping("/upload") public String upload(@RequestParam("file")MultipartFile file, HttpServletRequest request) { // 假如没有文件 if (!file.isEmpty()) { // 获得文件原始名字 String fileName = file.getOriginalFilename(); // 获得文件的后缀名 String fileSuffix = fileName.substring(fileName.lastIndexOf(".")); // 取新的名字 UUID可以保证产生的名字不一样,产生全球唯一的ID String newName = UUID.randomUUID() + fileSuffix; // 获取文件存储目录地址 String filePath = request.getSession().getServletContext().getRealPath("/upload"); File fileForPath = new File(filePath); // 如果文件不存在 if (!fileForPath.exists()) { // 新建文件 fileForPath.mkdir(); } File targetFile = new File(filePath, newName); try { // 将文件写入 file.transferTo(targetFile); } catch (IOException e) { e.printStackTrace(); } } else { System.out.println("文件不存在"); } return "test"; } 文件下载 @RequestMapping("down") public String down(HttpServletResponse response,HttpServletRequest request){ // 假如我的文件在/home/xiaohiu/images/鬼刀.jpg String fileName= "鬼刀.jpg"; String parentPath = "/home/xiaohiu/images"; // 这时候path.toString就是/home/xiaohiu/images/鬼刀.jpg了 Path path = Paths.get(parentPath,fileName); // 假如文件存在 if (Files.exists(path)){ // 取出后缀名 jpg String fileSuffix = fileName.substring(fileName.lastIndexOf(".")+1); // 设置ContentType,只有设置它,才会去下载 response.setContentType("application/"+fileSuffix); try { // 添加头信息 同时对文件名重新编码防止中文名乱码 response.addHeader("Content-Disposition","attachment;filename="+new String(fileName.getBytes("utf-8"),"ISO8859-1")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { // 使用输出流写出去 Files.copy(path,response.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } }else { System.out.println("文件不存在"); } return "test"; } SpringMVC拦截器 拦截器实在我们请求之前做检查,同时有权决定我们接下来是否继续,同时也可以对我们的请求进行加工处理,可以设置多个拦截器。 看到这里,是不是想到了我在前面介绍的AOP,其实我们可以理解为Spring拦截器是SpringMVC对AOP的一种实现方式。AOP是通过配置进行配置,而拦截器是通过进行配置。 那么我们怎么实现呢? 实现HandlerInterceptorAdapter接口 在SpringMVC中,为实现拦截器功能,有两种方式,一个是实现HandlerInterceptor接口,第二个是实现WebRequestInterceptor接口,这里我们选择使用HandlerInterceptor。 在HandlerInterceptor接口中,定义了三个方法 preHandle():请求之前调用,返回true或则false,返回true,接下来的postHandle和afterCompletion才会起作用。 postHandle():在请求之后调用,也就是controller方法执行完后再调用,但是却是在DispatcherServlet进行视图返回渲染之前被调用。也就是说,这个可以对modle进行操作。 afterCompletion():在DispatcherServlet进行完试图渲染之后才执行。 public class TestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("请求前进行拦截"); // 返回true才会查找下一个拦截器,如果没有下一个拦截器,则返回controller return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("视图渲染前进行拦截"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("视图渲染后进行拦截"); } } 拦截器的配置 在springmvc的xml配置文件中 这时候就可以进行拦截了。 拦截器顺序的问题 拦截器顺序是根据配置的顺序来决定的,但是pre、post、after却有些区别,这张图就可以表示了。 好了,今天的Springmvc就到了这里了。 君子不行陌路,管它咫尺还是天涯https://www.cnblogs.com/xiaohuiduan/p/9977891.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信