Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)

2023-10-27

转载自 https://blog.csdn.net/jy02268879/article/details/82830789

一、接收参数(postman发送)

1.form表单

@RequestParam("name") String name

会把传递过来的Form表单中的name对应到formData方法的name参数上

该注解不能接收json传参

该注解表示name字段是必须入参的,否则会报错

@RequestParam(value = "name", required = false) String name

required = false表示必须入参

@RequestParam(value = "name", defaultValue = "admin") String name

defaultValue = "admin"表示当name入参为空的时候给它一个默认值admin


 
 
  1. /**
  2. * 测试接收form表单、URL的数据。不能接收Json数据
  3. * */
  4. @RequestMapping(value = "/test1", method = RequestMethod.POST)
  5. public String formData(@RequestParam("name") String name , @RequestParam("age") int age){
  6. String result = "receive name = "+name+ " age = "+age;
  7. System.out.println(result);
  8. return result;
  9. }

2.URL

代码跟1.form表单中的代码一样

3.动态接收URL中的数据

@PathVariable将URL中的占位符参数绑定到控制器处理方法的入参

此种情况下,url求情中一定要带占位符pageNo,pageSize的值,不然访问失败

即访问时一定要用 http://localhost:8088/sid/test2/2/20

如果用 http://localhost:8088/sid/test2 则访问失败


 
 
  1. /**
  2. * 测试动态接收URL中的数据
  3. * */
  4. @RequestMapping(value = "/test2/{pageNo}/{pageSize}", method = RequestMethod.POST)
  5. public String urlData(@PathVariable int pageNo , @PathVariable int pageSize){
  6. String result = "receive pageNo = "+pageNo+ " pageSize = "+pageSize;
  7. System.out.println(result);
  8. return result;
  9. }

4.json

@RequestBody 接收Json格式的数据需要加这个注解。该注解不能接收URL、Form表单传参


 
 
  1. /**
  2. * 测试接收json数据
  3. * */
  4. @RequestMapping(value = "/jsonData", method = RequestMethod.POST)
  5. public String jsonData(@RequestBody TestModel tm){
  6. String result = "receive name = "+tm.getName()+ " age = "+tm.getAge();
  7. System.out.println(result);
  8. return result;
  9. }

5.@RequestMapping注解详细介绍

1.处理多个URL


 
 
  1. @RestController
  2. @RequestMapping( "/home")
  3. public class IndexController {
  4. @RequestMapping(value = {
  5. "",
  6. "/page",
  7. "page*",
  8. "view/*,**/msg"
  9. })
  10. String indexMultipleMapping() {
  11. return "Hello from index multiple mapping.";
  12. }
  13. }

这些 URL 都会由 indexMultipleMapping() 来处理: 

localhost:8080/home

localhost:8080/home/

localhost:8080/home/page

localhost:8080/home/pageabc

localhost:8080/home/view/

localhost:8080/home/view/view

2.HTTP的各种方法

如POST方法

@RequestMapping(value = "/test1", method = RequestMethod.POST)

3.produces、consumes 

produces 指定返回的内容类型,仅当request请求头header中的(Accept)类型中包含该指定类型才返回。结合@ResponseBody使用


 
 
  1. @Controller
  2. @RequestMapping(value = "/t")
  3. public class TestController {
  4. //方法仅处理request请求中Accept头中包含了"text/html"的请求
  5. @ResponseBody
  6. @RequestMapping(value = "/produces",produces = { "text/html"})
  7. public String testProduces(String name)
  8. {
  9. return "test requestMapping produces attribute! "+name;
  10. }
  11. }

方法仅处理request请求中Accept头中包含了"text/html"的请求

比如用postman构建一个Accept=“application/json”的请求,请求会失败


comsumes  指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。结合@RequestBody使用


 
 
  1. @Controller
  2. @RequestMapping(value = "/t")
  3. public class TestController {
  4. //方法仅处理request Content-Type为"application/json"类型的请求
  5. @ResponseBody
  6. @RequestMapping(value = "/consumes",consumes = { "application/json"})
  7. public String testConsumes(@RequestBody String name)
  8. {
  9. return "test requestMapping consumes attribute! "+name;
  10. }
  11. }

方法仅处理request Content-Type为"application/json"类型的请求。

如果用postman构建一个Content-Type=“application/x-www-form-urlencoded”的请求,该方法不处理

4.headers 

根据请求中的消息头内容缩小请求映射的范围

例如:

只处理header中testHeader = sid的请求


 
 
  1. //方法仅处理header中testHeader = sid的请求
  2. @ResponseBody
  3. @RequestMapping(value = "/header",headers = { "testHeader = sid"})
  4. public String testHeader(String name)
  5. {
  6. return "test requestMapping headers attribute! "+name;
  7. }

构建一个header钟不带testHeader=sid的请求,会失败

 

必须要header中带testHeader=sid的请求的请求才处理

5.结合params属性处理请求参数

例如:

请求参数name=sid的时候由getParams方法处理

请求参数name=lee的时候由getParamsDifferent方法处理


 
 
  1. @Controller
  2. @RequestMapping(value = "/t")
  3. public class TestController {
  4. @RequestMapping(value = "/params", params = {
  5. "name=sid"
  6. })
  7. @ResponseBody
  8. public String getParams(@RequestParam("name") String name) {
  9. return "getParams method do " + name;
  10. }
  11. @RequestMapping(value = "/params", params = {
  12. "name=lee"
  13. })
  14. @ResponseBody
  15. public String getParamsDifferent(@RequestParam("name") String name) {
  16. return "getParamsDifferent method do " + name;
  17. }
  18. }

 

二、返回值

@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面

1.返回静态html页面

application.yml


 
 
  1. server:
  2. port: 8088
  3. servlet:
  4. context-path: /sid
  5. spring:
  6. mvc:
  7. view:
  8. prefix: /
  9. suffix: .html


 
 
  1. /**
  2. * 返回界面 index.html
  3. * @Controller修饰的类 直接定义方法返回值为String
  4. * */
  5. @RequestMapping(value = "/index")
  6. public String index(){
  7. return "index";
  8. }
  9. /**返回界面 index.html
  10. * @RestController修饰的类  
  11. * 需要配合视图解析器    
  12. * */
  13. @RequestMapping( "/indexmv")
  14. public ModelAndView indexmv() {
  15. ModelAndView mv = new ModelAndView( "index");
  16. return mv;
  17. }

2.通过object返回查询结果

@ResponseBody会把返回值变成json


 
 
  1. /**
  2. * 直接查询得到的model类,@ResponseBody会把返回值变成json
  3. * */
  4. @RequestMapping(value = "/object", method = RequestMethod.POST)
  5. @ResponseBody
  6. public Object object(@RequestParam("name") String name , @RequestParam("age") String age){
  7. TestModel t =getModel( name , age);
  8. List<TestModel> list = new ArrayList();
  9. list.add(t);
  10. return list;
  11. }

3.返回时直接抛出自定义异常


 
 
  1. /**
  2. * 返回时直接抛出自定义异常
  3. * */
  4. @RequestMapping(value = "/list", method = RequestMethod.POST)
  5. @ResponseBody
  6. public List<TestModel> list(@RequestParam("name") String name , @RequestParam("age") String age){
  7. TestModel t =getModel( name , age);
  8. if(t != null){
  9. throw new MyException( "测试抛出自定义异常");
  10. }
  11. List<TestModel> list = new ArrayList();
  12. list.add(t);
  13. list.add(t);
  14. return list;
  15. }

4.返回ResponseEntity

两种不同的创建ResponseEntity的方式


 
 
  1. /**
  2. * 返回ResponseEntity
  3. *
  4. * ResponseEntity的优先级高于@ResponseBody
  5. * 在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解。
  6. * 如果响应类型是ResponseEntity可以不写@ResponseBody注解
  7. * */
  8. @RequestMapping(value = "/responseEntity", method = RequestMethod.POST)
  9. public ResponseEntity<?> responseEntity( @RequestParam( "name") String name , @RequestParam( "age") String age){
  10. try{
  11. TestModel t =getModel( name , age);
  12. if(!t.getAge().equals( "27")){
  13. throw new MyException( "年龄错误!");
  14. }
  15. List<TestModel> list = new ArrayList();
  16. list.add(t);
  17. list.add(t);
  18. HttpHeaders headers = new HttpHeaders();
  19. //headers.set("Content-type", "application/json;charset=UTF-8");
  20. headers.add( "code", "1");
  21. headers.add( "msg", "success");
  22. headers.add( "error", "");
  23. return new ResponseEntity<List>(list,headers,HttpStatus.OK);
  24. } catch (MyException e){
  25. return ResponseEntity.badRequest()
  26. //.header("Content-type", "application/json;charset=UTF-8")
  27. .header( "code", "0")
  28. .header( "msg", "")
  29. .header( "error", e.getMessage()) //中文乱码
  30. .build(); //build无返回值 body有返回值
  31. }
  32. }

5.返回自定义类,其中有code msg error data 而查询结果在data中

MyResponse.java


 
 
  1. package com.sid.springtboot.test.springboottest;
  2. public class MyResponse<T> {
  3. private String code;
  4. private String msg;
  5. private String error;
  6. private T data;
  7. public MyResponse(String code, String msg, String error, T data) {
  8. this.code = code;
  9. this.msg = msg;
  10. this.error = error;
  11. this.data = data;
  12. }
  13. public String getCode() {
  14. return code;
  15. }
  16. public void setCode(String code) {
  17. this.code = code;
  18. }
  19. public String getMsg() {
  20. return msg;
  21. }
  22. public void setMsg(String msg) {
  23. this.msg = msg;
  24. }
  25. public String getError() {
  26. return error;
  27. }
  28. public void setError(String error) {
  29. this.error = error;
  30. }
  31. public T getData() {
  32. return data;
  33. }
  34. public void setData(T data) {
  35. this.data = data;
  36. }
  37. }
MyException.java
 
 

 
 
  1. package com.sid.springtboot.test.springboottest;
  2. public class MyException extends RuntimeException{
  3. private String errorCode;
  4. private String msg;
  5. public MyException(String message) {
  6. super(message);
  7. }
  8. public MyException(String errorCode, String msg) {
  9. this.errorCode = errorCode;
  10. this.msg = msg;
  11. }
  12. public String getErrorCode() {
  13. return errorCode;
  14. }
  15. public void setErrorCode(String errorCode) {
  16. this.errorCode = errorCode;
  17. }
  18. public String getMsg() {
  19. return msg;
  20. }
  21. public void setMsg(String msg) {
  22. this.msg = msg;
  23. }
  24. }

 controller


 
 
  1. /**
  2. * 返回自定义类,其中有code msg error data 而查询结果在data中
  3. * */
  4. @RequestMapping(value = "/myResponse", method = RequestMethod.POST)
  5. @ResponseBody
  6. public MyResponse<?> myResponse( @RequestParam( "name") String name , @RequestParam( "age") String age){
  7. try{
  8. TestModel t1 =getModel( name , age);
  9. if(!t1.getAge().equals( "27")){
  10. throw new MyException( "年龄错误!");
  11. }
  12. List<TestModel> list = new ArrayList();
  13. list.add(t1);
  14. list.add(t1);
  15. list.add(t1);
  16. return new MyResponse<List>( "1", "success", null,list);
  17. } catch (MyException e){
  18. return new MyResponse<>( "0", null,e.getMessage(), null);
  19. }
  20. }

三、上传、下载文件

上传文件


 
 
  1. @PostMapping( "/upload")
  2. @ResponseBody
  3. public Map<String, String> upload1(@RequestParam("file") MultipartFile file) throws IOException {
  4. System.out.println( "[文件类型] - [{}]"+ file.getContentType());
  5. System.out.println( "[文件名称] - [{}]"+ file.getOriginalFilename());
  6. System.out.println( "[文件大小] - [{}]"+ file.getSize());
  7. //保存
  8. file.transferTo( new File( "D:\\gitrep\\springboot\\testFile\\" + file.getOriginalFilename()));
  9. Map<String, String> result = new HashMap<>( 16);
  10. result.put( "contentType", file.getContentType());
  11. result.put( "fileName", file.getOriginalFilename());
  12. result.put( "fileSize", file.getSize() + "");
  13. return result;
  14. }

下载文件

1.通过ResponseEntity<InputStreamResource>实现

封装ResponseEntity,将文件流写入body中。这里注意一点,就是文件的格式需要根据具体文件的类型来设置,一般默认为application/octet-stream。文件头中设置缓存,以及文件的名字。文件的名字写入了,都可以避免出现文件随机产生名字,而不能识别的问题。


 
 
  1. @GetMapping( "/download")
  2. public ResponseEntity<InputStreamResource> downloadFile() throws IOException {
  3. String filePath = "D:\\gitrep\\springboot\\testFile\\" + "api-ms-win-core-console-l1-1-0.dll";
  4. FileSystemResource file = new FileSystemResource(filePath);
  5. HttpHeaders headers = new HttpHeaders();
  6. headers.add( "Cache-Control", "no-cache, no-store, must-revalidate");
  7. headers.add( "Content-Disposition", String.format( "attachment; filename=\"%s\"", file.getFilename()));
  8. headers.add( "Pragma", "no-cache");
  9. headers.add( "Expires", "0");
  10. return ResponseEntity.ok().headers(headers)
  11. .contentLength(file.contentLength())
  12. .contentType(MediaType.parseMediaType( "application/octet-stream"))
  13. .body( new InputStreamResource(file.getInputStream()));
  14. }

2.用HttpServletResponse


 
 
  1. @GetMapping( "/download2")
  2. public String downloadFile2( HttpServletResponse response) throws IOException {
  3. // 获取指定目录下的文件
  4. String fileName = "D:\\gitrep\\springboot\\testFile\\" + "api-ms-win-core-console-l1-1-0.dll";
  5. File file = new File(fileName);
  6. // 如果文件名存在,则进行下载
  7. if (file.exists()) {
  8. // 配置文件下载
  9. response.setHeader( "content-type", "application/octet-stream");
  10. response.setContentType( "application/octet-stream");
  11. // 下载文件能正常显示中文
  12. response.setHeader( "Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
  13. // 实现文件下载
  14. byte[] buffer = new byte[ 1024];
  15. FileInputStream fis = null;
  16. BufferedInputStream bis = null;
  17. try {
  18. fis = new FileInputStream(file);
  19. bis = new BufferedInputStream(fis);
  20. OutputStream os = response.getOutputStream();
  21. int i = bis.read(buffer);
  22. while (i != - 1) {
  23. os.write(buffer, 0, i);
  24. i = bis.read(buffer);
  25. }
  26. System.out.println( "Download the song successfully!");
  27. }
  28. catch (Exception e) {
  29. System.out.println( "Download the song failed!");
  30. } finally {
  31. if (bis != null) {
  32. try {
  33. bis.close();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. if (fis != null) {
  39. try {
  40. fis.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }
  46. }
  47. return null;
  48. }

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件) 的相关文章

  • Apache Airflow --- Linux安装

    Apache Airflow Linux安装 1 Python Install 2 Mysql Install 3 Airflow Install 3 1 Run Locally 3 2 Pip3 install 3 2 Config My
  • QT多线程

    Qt多线程 1 QThread类 QThread类并不是代表一个新的线程 而是QT提供的一个接口 用于控制一个子线程 每个QThread的实例就代表着对一个新线程的一个控制类 对于第一次使用QT多线程的人 或许就会很迷惑很不适应 QThre

随机推荐