@RequestMapping
- value:用于指定请求的 URL。它和 path属性的作用是一样的。如果只有value一个属性可以省略不写
- path:用于指定请求的 URL,它和value的属性作用一样,但是不能省略
- method:用于指定请求的方式
- params:用于指定限制请求参数的条件
- hereders:用于指定限制请求消息头的条件
controller:
1 2 3 4 5 6 7 8 9 10 11
| @Controller @RequestMapping(path = "/user") public class UserController {
@RequestMapping(value = "/select/phone",method = RequestMethod.GET,params = {"phone") public String selectByPhone(String phone){ System.out.println("测试requestMapping"); return null; } }
|
path 用来指controller的寻址,value用来指方法的寻址,但是他们功能一致
method 用来指定访问方法的请求类型,请求类型不同无法访问。
param 接收数组类型数据,用大括号抱起来,它限制了必须接收到的参数,如果没有这里的参数,就会报错
时间接收
如果你输入的时间格式是 yyyy-mm-dd,那么你大概率会碰到400的报错,那是因为springmvc有自己默认的时间格式 是 yyyy/mm/dd,如果你想要用自己的格式来,那需要自定义转换器。
首先确保你的springmvc.xml 中开启自定义注解
1
| <mvc:annotation-driven></mvc:annotation-driven>
|
然后看例子:
1 2 3 4 5
| @RequestMapping(value = "/canshu",params = {"name","money"}) public void show02(String name, @DateTimeFormat(pattern = "yyyy-MM-dd") Date money) { System.out.println("name:::" + name); System.out.println("money:::" + money); }
|
类似于java的日期类型转换
可以用在参数的声明,也可以直接定义在成员变量上声明
修饰日期类型才会真正有效
还有第二种方法:
1、创建一个转换类
2、在你的springmvc.xml 中添加转换器的位置
3、重新设置指定的自定义注解
转换类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.ls.controller;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;
public class StringToDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { if (source != null && !source.trim().equals("")) { SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd"); try { Date date = format.parse(source); return date; } catch (ParseException e) { System.out.println("日期格式错误!"); e.printStackTrace(); } } return null; } }
|
增加配置器:
1 2 3 4 5 6 7 8 9 10
| <bean id="converterService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <array> <bean class="com.czxy.mvc.converter.StringToDateConverter"></bean> </array> </property> </bean>
|
修改自定义转化
1
| <mvc:annotation-driven conversion-service="converterService"/>
|
之后接受的日期类型都是你指定的类型,不需要用到@DateTimeFormat注解了
servletAPI
SpringMVC还支持使用原始 ServletAPI对象作为控制器方法的参数。支持原始 ServletAPI对象有:
HttpServletRequest
(常用)
HttpServletResponse
(常用)
HttpSession
(常用)
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
我们可以把上述对象,直接写在控制的方法参数中使用。例如需要使用HttpSession获取session中登录的用户信息,可以将HttpSession对象作为方法参数
1 2 3 4 5 6 7 8 9 10
| @RequestMapping("/test/servletAPI") public String testServetAPI(HttpServletRequest request, HttpServletResponse response, HttpSession session){ System.out.println(request); System.out.println(response); System.out.println(session);
return "success"; }
|
当然这些并不是只能用来打印的,我们的return跳转的原始方法可以用 request来实现
1
| request.getRequestDispatcher("跳转页面").forward(request,response)
|
forward和redirect
forward
- 转发都是一次请求: A -> B -> C 整个过程还是一次请求,也就是同个request,同一个作用域,过程中的信息共享
- 转发地址栏显示地址不变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RequestMapping("/forward") public String forward(HttpServletRequest request, HttpSession session){ request.setAttribute("name","张三"); session.setAttribute("age",20); System.out.println("参数设置完毕...转发..."); return "forward:/user/get/params.do"; }
@RequestMapping("/get/params") public String getParams(HttpServletRequest request, HttpSession session){ String name = (String) request.getAttribute("name"); Integer age = (Integer) session.getAttribute("age"); System.out.println("name : "+name+" age : "+age); return "success"; }
|
1、默认就是跳转,重定向需要自己指定
2、请求在一个作用域中,前面的消息,后面也可以拿到
3、也可以通过方法跳转,request.getRequestDispatcher(“跳转页面”).forward(request,response)
redirect
- 重定向是2次请求:A -> B ,那么A和B 就是不同request,B无法获取到A 的request中的数据,但是只要没有关闭浏览器,A和B还在一次会话总,A和B可以使用session共享数据
- 重定向浏览器地址栏会显示新的请求地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RequestMapping("/redirect") public String redirect(HttpServletRequest request, HttpSession session){ request.setAttribute("name","张三"); session.setAttribute("age",20); System.out.println("参数设置完毕...转发..."); return "redirect:/user/get/params.do"; }
@RequestMapping("/get/params") public String getParams(HttpServletRequest request, HttpSession session){ String name = (String) request.getAttribute("name"); Integer age = (Integer) session.getAttribute("age"); System.out.println("name : "+name+" age : "+age); return "success"; }
|
1、重定向不默认,需要自己写单词了
2、两次请求,所以信息不可能共享,想要获取公共信息,需要依靠session了。
3、可以直接用方法跳转:response。sendRedirect(“跳转页面”)
注解方式接收参数
- RequestBody:用于获取请求体内容。
- PathVariable:用于绑定 url中的占位符
- RequestHerder:用于获取请求消息头
- CookieValue:用于把指定 cookie名称的值传入控制器方法参数
@RequestParam
把请求中指定名称的参数赋值给方法的形参。也就是说不要求你必须把方法参数写成与请求的参数一致了
1
| ?username=tom --> public String hello(@requestParam("username") String name)
|
1
| @RequestParam(value = "userToken",required = true) String token
|
@RequestBody
依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <jackson-version>2.11.0</jackson-version>
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson-version}</version> </dependency>
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson-version}</version> </dependency>
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson-version}</version> </dependency>
|
1 2 3 4 5 6
| @RequestMapping("/test/body/user") public String testBodyPojo(@RequestBody(required = false) User user){ System.out.println(user); return "success"; }
|
@PathVeriable
用于绑定 url中的占位符。例如:请求 url中 /delete/**{id},这个{id}**就是 url占位符。
不支持get请求
url支持占位符是 spring3.0之后加入的。是 springmvc支持 rest风格 URL的一个重要标志。
1 2 3 4 5
| @RequestMapping(value = "/user/{id}/{name}",method = RequestMethod.POST) public String testPathVariable(@PathVariable(value = "id",required = true)Integer id,@PathVariable("name")String name){ System.out.println("id = "+id+" name = "+name); return "success"; }
|
前端直接用/拼接参数 : /user/12/haoren
浏览器传递数据过来的时候,会有请求头,这个就是用来获取请求头的
1 2 3 4 5 6 7
| @RequestMapping("/header") public String getHeader(@RequestHeader(value = "Host")String host, @RequestHeader(value = "token",required = true)String token){ System.out.println("Host: "+host); System.out.println("token: "+token); return "success"; }
|
1、请求头可以在浏览器按f12看
2、请求头可以用 required = true 来设定是不是必须有
@CookieValue
用于把指定 cookie 名称的值传入控制器方法的参数中。
1 2 3 4 5
| @RequestMapping(value = "/cookie/value",method = RequestMethod.GET) public String getCookieVal(@CookieValue("JSESSIONID")String jsessionID){ System.out.println("JSESSIONID: "+jsessionID); return "success"; }
|
1、required:是否必须有此 cookie
springMVC文件上传
文件上传的3要素
form表单的 enctype取值必须是:multipart/form-data
(默认值是:application/x-www-form-urlencoded)
enctype:是表单请求正文的类型
method属性取值必须是 Post
提供一个文件选择域
HTTP协议中新增的rfc1867协议,为 http 协议添加了上传功能。
根据 rfc1867协议规范,enctype=”multipart/form-data”, method=post, type=”file” 。这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。
值 |
描述 |
application/x-www-form-urlencoded |
默认值。在发送前对所有字符进行编码为名称/值对 (将空格转换为 “+” 符号,特殊字符转换为 ASCII HEX 值)。 |
multipart/form-data |
不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain |
空格转换为 “+” 加号,但不对特殊字符编码。 |
文件上传流程
- 客户端的浏览器,如 Microsoft IE, Mozila Firefox, Chrome 等,按照此规范将用户指定的文件发送到服务器端的网页程序。
- 服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。经过编码发送给服务器。
- http server ,例如 tomcat ,已经支持此协议,可接收发送来的文件。
pom:
1 2 3 4 5 6 7
|
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
|
controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @RequestMapping("/upload") public String uploadFile(String picname, MultipartFile uploadFile, HttpServletRequest request) throws IOException { if(uploadFile == null){ return "error"; } String fileName = "";
String originalFilename = uploadFile.getOriginalFilename(); String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase(); if(!StringUtils.isEmpty(picname)){ fileName = uuid+"_"+picname+suffix; }else { fileName = uuid+"_"+originalFilename; } System.out.println(fileName);
ServletContext servletContext = request.getSession().getServletContext(); String basePath = servletContext.getRealPath("/upload"); String datePath = new SimpleDateFormat("yyyy-mm-dd").format(new Date()); File dir = new File(basePath + "/" + datePath); if (!dir.exists()){ dir.mkdir(); } uploadFile.transferTo(new File(dir,fileName));
return "success"; }
|
1、判断传进来东西没有
2、获取文件名字
3、获取文件的扩展名
4、判断用户是否传入了名称,传入了则使用,否则默认uuid加扩展名
5、设置上传的位置,主要是生成日期文件夹,防止一个文件夹内文件过多
6、将上传的文件保存到文件夹 用 transferTo 方法
其实上传就两部,起名+存放,但是要考虑各种因素,导致步骤很多
上传注意三点,multipart/form-data, post请求,type=file 并且name与后端形式参数一致
springmvc文件下载
download.jsp
1 2 3 4 5 6 7 8 9
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>文件下载</title> </head> <body> <a href="/download?filename=年轻的我.jpg">年轻的我</a> </body> </html>
|
controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| @RequestMapping("/download") public String download(String filename, HttpServletResponse response){ if(StringUtils.isEmpty(filename)){ return null; } System.out.println("用户要下载的文件:"+filename); File sourceFile = new File("H:\\upload\\2020-07-27\\5C1CE96586654999BB7C12A18ECE26B0_帅照.jpg");
byte[] bytes = null; FileInputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(sourceFile); bytes = new byte[inputStream.available()]; inputStream.read(bytes);
filename = URLEncoder.encode(filename,"utf-8"); response.setHeader("Content-Disposition","attachment;filename="+filename); outputStream = response.getOutputStream(); outputStream.write(bytes); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("文件下载异常!"); }finally { if(inputStream != null){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
return null; }
|
那个响应头如果不设置,就不会跳出现在弹窗,所以还是设置的好