最近在网易云课堂上看一些视频,给大家推荐一个讲Spring Boot的视频https://study.163.com/course/courseMain.htm?courseId=1005213034,老师讲的很不错。在学习的时候我也会做一些笔记,方便日后巩固。
对这个系列感兴趣的可以看我之前写的博客:
在程序中记录日志
-
有两种方法,分别依赖两个包,他们是Commons-logging和SLF4j。使用方法:
private static final Log log = LogFactory.getLog(Xxxx.class); private static final Logger logger = LoggerFactory.getLogger(Xxxx.class);
-
日志级别:可以选择某个级别及以上的日志进行记录,这点比单纯的用
System.out.print()
要好。TRACE和FATAL是Commons-logging包独有的TRACE < DEBUG < INFO < WARN < ERROR < FATAL
-
需要在application.yml中进行配置,下面是参考:
logging: file: target/app.log level: ROOT: WARN cn.luxiaofen: TRACE #改成对应的包的名字
commons-logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SampleClass {
//这是一个不变的对象。修饰为static是因为允许静态方法调用
private static final Log log = LogFactory.getLog(SampleClass.class);
public void print(String name) {
if(log.isTraceEnabled()) {
log.trace("传入参数是: " + name);
}
try {
// do something
}catch(Exception e) {
if(log.isErrorEnabled()) {
log.error("出错啦", e);
}
}
}
… …
}
在getAll()方法中测试
课时6.1启动Spring Boot后,在浏览器中打开http://localhost:8080/tvseries
课时6.2注意这个下载的项目设置的编码形式为UTF-8,不支持其他编码形式。如需修改就去.pom文件里改。
使用POSTMAN来测试API
请求方式不止GET这一种,如果是其他的如POST,DELETE,PUT这种就不能单纯的用浏览器去测试。这时候就需要一些工具来帮助我们。一个是命令行工具UNIX系统自带的curl,因为我的系统是WIN10,所以接下来我主要会用到的是一个带界面的API测试工具POSTMAN。
POSTMAN详解RestController中获取请求的各种数据
请求方式的POST,GET,PUT,DELETE形式分别对应着C(create),R(retrieve),U(update),D(delete)。下面来看看这些方法的实现。
GET方法
-
首先对代码做一些重构,这是为了方便将各种TvSeriesDto对象放入list:
课时8.1 -
添加一个从list中取得一个TvSeriesDto对象的方法
课时8.2 -
启动Spring Boot后,在POSTMAN中测试
课时8.3
POST方法
-
在Controller中新增一个POST方法
课时8.4 -
为了方便测试需要重写TvSeriesDto的toString()方法
@Override public String toString() { return this.getClass().getName()+"{id:"+id+",name:"+name+"}"; }
-
在POSTMAN中测试
课时8.5 -
看一下日志
传进来的参数是:cn.luxiaofen.test.TvSeriesDto{id:0,name:可爱的湖南人}
PUT方法
- 在Controller中新增PUT方法
@PutMapping("/{id}") public TvSeriesDto updateOne(@PathVariable int id,@RequestBody TvSeriesDto tvSeriesDto) { if (log.isTraceEnabled()) { log.trace("update one "+id); } if (id==1 || id ==2) { tvSeriesDto.setName("NanNan");//更新数据 return tvSeriesDto; }else throw new ResourceNotFoundException(); }
-
在POSTMAN中测试
课时8.6
DELETE方法
-
新增DELETE方法
/** * * @param id 在url中的id * @param request 这个参数不用加注解,spring会自动传进来 * @param deleteReason 删除的理由,required = false表示不是必需的 * @return 删除的信息,储存在MAP中 */ @DeleteMapping("/{id}") public Map<String,String> deleteOne(@PathVariable int id, HttpServletRequest request, @RequestParam(name = "deleteReason",required = false)String deleteReason) throws Exception { if(log.isTraceEnabled()) { log.trace("delete one "+id); } Map<String,String> result = new HashMap<>(); if (id == 2) { // TODO:执行删除的代码 result.put("message","#2被"+request.getRemoteAddr()+"删除,原因("+deleteReason+")"); }else if (id == 1) { throw new RuntimeException("LoveManchester不能被删除"); }else throw new ResourceNotFoundException(); return result; }
-
在POSTMAN中测试,注意这里request parameter不能使用中文,会引起编码错误
课时8.7 -
查看日志
2018-11-10 09:46:15.693 DEBUG 8300 --- [nio-8080-exec-1] cn.luxiaofen.test.TvSeriesController : delete one 2
RestController中的上传和下载示例
上传文件
-
为了使用org.apache.commons.io包下的IOUtils,需要在MAVEN中引入这个包,在.pom文件中加入:
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
-
在Controller中新增文件上传方法
/** * 这是一个上传照片的方法 * consumes表示传入的参数,这里采用的是MULTIPART_FORM_DATA_VALUE类型 * @param photo 上传的照片 */ @PostMapping(value = "/photo",consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public void addPhoto(@RequestParam("photo")MultipartFile photo) throws IOException { if (log.isTraceEnabled()) { log.trace("接收到文件"+photo.getOriginalFilename()); } //保存文件到指定目录下 FileOutputStream fos = new FileOutputStream("target/"+photo.getOriginalFilename()); //注意这里引用的包是org.apache.commons.io.IOUtils IOUtils.copy(photo.getInputStream(),fos); fos.close(); }
-
在POSTMAN中测试
课时9.1 -
看一下IDEA中的结果:
课时9.22018-11-10 11:18:31.941 DEBUG 3420 --- [nio-8080-exec-1] cn.luxiaofen.test.TvSeriesController : 接收到文件nannan.jpg
下载文件
- 在src/main/resources目录下储存一张图片,命名为icon.jpg
- 增加下载文件的方法
/** * 这是一个返回数据的方法 * produces参数表示生成的文件格式,这里使用的是jpg文件格式 * @return 图片 */ @GetMapping(value = "/icon",produces = MediaType.IMAGE_JPEG_VALUE) public byte[] getIcon() throws IOException { if (log.isTraceEnabled()) { log.trace("getIcon() is invoked"); } //需要在指定目录下预先放好文件 String iconFile = "src/main/resources/icon.jpg"; InputStream inputStream = new FileInputStream(iconFile); return IOUtils.toByteArray(inputStream); }
- 浏览器中打开http://localhost:8080/tvseries/icon,看到浏览器中已经返回了我们预先储存的图片
课时9.3 - 在IDEA中查看日志
2018-11-10 12:05:26.622 DEBUG 6412 --- [nio-8080-exec-2] cn.luxiaofen.test.TvSeriesController : getIcon() is invoked
在RestController中获取各种相关信息的⽅法
-
URL中路径的⼀部分:
⾸先需要在RequestMapping做映射,之后在⽅法中可以通过注解使⽤映射的变量
@GetMapping("/{id}") public TvSeries getOne(@PathVariable("id") Integer id){}
可以写多个: @PutMapping("/{id}/characters/{cId}")
还可以使⽤正则表达式限制类型(不符合要求会返回4xx的错误信息,表示请求参数
有问题)此例⼦表示id必须是数字:
@PutMapping("/{id:\d+}") -
POST⽅法传递过来的JSON:
给参数前增加@RequestBody注解, Spring会⾃动把POST的Request Body部分的JSON转成⽅法声明的类。如果转化失败会返回4xx错误,表示请求参数有问题。
public Object updateOne(@RequestBody TvSeries tvSeries)
-
POST⽅法传递的是表单数据:
⾸先需要声明传⼊的是application/x-www-form-urlencoded的格式,可在RequestMapping增加consumes参数:
@PostMapping(value="/tvseries",consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE)
在⽅法上增加参数,参数使⽤@RequestParam注解即可:
public Object insert(@RequestParam(value="name",required=false) String name) {}
凡是可以通过HttpServletRequest.getParameter(String)⽅法取到的值,
包含表单提交的、 QueryString附带的,都可以使⽤@RequestParam注解得到
默认是request=true。 -
QueryString的参数:
使⽤@RequestParam注解,通过参数获得,例如:
public Object query(@RequestParam(value="page",required=false) Integer page)
-
Request Header:
可以使⽤@Requestheader注解获取Request的头信息,例如:
public ResultJSON editCompany(@RequestHeader("user-agent")String userAgent) {}
注意: @RequestHeader后⾯的头名字不区分⼤⼩写,但RequestParam,PathVariable等是区分的。
如果RequestHeader后⾯不写参数,会⽤后⾯的变量名替代 -
获取cookie值:
使⽤@CookieValue注解,和其他类似,除⾮为了兼容⽼现有客户端,新API⾥不建议⽤cookie。
-
获取当前的RequestResponse:
直接写参数,例如:
public Object doSomething(HttpServletRequest request,HttpServletResponse response){}
-
获取当前⽤户:
直接在⽅法上增加参数,类型为:org.springframework.security.core.Authentication,例如:
public TvSeries deleteOne(Authentication auth)
参数auth内会存储有当前的⽤户信息。
-
⽂件上传:
⾸先要设置consumes为multipart/form-data:
@PostMapping(value="/files",consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
在⽅法中写参数:
public Map<String, Object> uploadFile(@RequestParam("file")MultipartFile file)
在⽅法中可以直接使⽤MultipartFile中的流保存⽂件了。
网友评论