1. RESTful简述
    REST是一种设计风格,是一组约束条件及原则,而遵循REST风格的架构就称为RESTful架构,资源是RESTful的核心,一个好的RESTful架构,通过URL就能很清晰的了解其相应的操作和需求是什么,即
1. 通过URL定位资源,如:
com.mobin/api/v1/shenzhen/subways //获取深圳地铁列表
com.mobin/api/v1/shenzhen/schools   //获取深圳学校列表
2. HTTP描述操作
GET:获取资源
POST:创建资源
PUT:更新资源
DELETE:删除资源
如:
GET com.mobin/api/v1/shenzhen/subways/1:获取ID为1的地铁信息
请求的资源通常都以JSON或XML等返回给Client,使用RESTful架构只需在Sever端提供一套RESTful API便能在web、IOS、Android共用
API设计是个很讲究的事情,可以参考GitHub的API设计规范

2. SpringBoot集成MyBatis
 1. 将xxxMapper.xml及sqlMapConfig.xml放入resource对应目录
 2. application.properties加载MyBatis配置文件及配置数据源

 ##application.properties
#加载mybatis配置文件
mybatis.mapper-locations = classpath:mapper/*Mapper.xml
mybatis.config-location = classpath:mapper/config/sqlMapConfig.xml

#指定别名
mybatis.type-aliases-package = com.mobin.entity

#数据源
spring.datasource.url = jdbc:postgresql://localhost:5432/xxx
spring.datasource.driver-class-name = org.postgresql.Driver
spring.datasource.username = postgres
spring.datasource.password = xxxx

MyBatis 3之后官方提供了特定的API来的支持动态SQL,可以使用注解+Java代码来替代XML,但是复杂的SQL语句还是走XML的方式,XML更直观(其实也恶心),注解的方式对于代码的侵入太严重,修改后还需要重新编译。

3. 日志配置
     Spring boot默认的日志框架为Logback,配置起来相当友好具有更好的性能,还可以对指定的服务的日志进行不同级别的过滤并不影响其他服务日志的级别
1. 控制台日志配置
2. 开发、测试、生产环境的配置

 ##logbcak-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<contextName>${appname}</contextName>
<!--控制台日志配置-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>

<appender name="FILEPROD" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>SpringBootRESTful.%d{yyyy-MM-dd}.log</FileNamePattern>
<!-- 日志保留天数-->
<MaxHistory>20</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>

<appender name="FILETEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>test.SpringBootRESTful.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>20</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>

<!--开发环境的日志配置 -->
<springProfile name="dev">
<!--开发环境通常会对指定包或类进行测试 -->
<logger name="com.mobin.dao" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</springProfile>

<!--测试环境的日志配置 -->
<springProfile name="test">
<root level="DEBUG">
<appender-ref ref="FILETEST"/>
<appender-ref ref="STDOUT"/>
</root>
</springProfile>

<!--生产环境的日志配置 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="FILEINFO"/>
<appender-ref ref="STDOUT"/>
</root>
</springProfile>
</configuration>

4. 异常处理
4.1 在API设计规范中,对异常的处理至少是
 1. 返回相应的错误代码
 2. 返回相应的错误描述
 3. 对应的资源模块
4.2 使用@RestControllerAdvice定义全局异常处理
@RestControllerAdvice是Spring 4.3之后的新特性,其相当于@ControllerAdvice+ResponseBody,所以使用@RestControllerAdvice可以将错误信息以Json的格式返回
1. 自定义异常类

 ##com.mobin.exception.EntityNotFoundException
//当请求的资源不存在时抛出该异常
public class EntityNotFoundException extends RuntimeException{
public EntityNotFoundException(String mes){
super(mes);
}
}

2. 定义全局异常类

 ##com.mobin.exception.GlobalExceptionHadlerActice
@RestControllerAdvice
public class GlobalExceptionHadlerActice {
private static final long serialVersionUID = 1L;
@ExceptionHandler(value = EntityNotFoundException.class)
public ErrorMessage entityNotFoundException(HttpServletRequest request, Exception e){
ErrorMessage errorMessage = new ErrorMessage();
errorMessage.setStatus(HttpStatus.NOT_FOUND.value());
errorMessage.setMessage(e.getLocalizedMessage());
errorMessage.setUrl(request.getRequestURL().toString());
return errorMessage;
}
}

ErrorMessage为自定义的实体类,包含statusCode,message及url字段。

3. 相应的请求方法

 ## com.mobin.controller.SubwayController
@RequestMapping(value="/{id}",method = RequestMethod.GET )
public SubwayResult<Subway> getSubwayByID(@PathVariable Integer id) {
SubwayResult<Subway> result = new SubwayResult();
Subway subway = subwayService.findSubwayByID(id);
if (subway == null){
throw new EntityNotFoundException("资源不存在");
}
result.setStatus(HttpStatus.OK.value());
result.setData(subway);
return result;
}

4. 通过curl进行测试

 MOBIN:~ mobin$ curl -XGET -w "\n" 'localhost:8089/api/subways/1999'
{
"message":"资源不存在",
"status":404,
"url":"http://localhost:8089/api/subways/1999"
}

5. 使用fastjson
1.  引入fastJson依赖
2. 自定义WebMvcConfigurer并继承WebMvcConfigurerAdapter
3. 重写configureMessageConverters方法
4. 自定义配置FastJsonConfig
5. 将FastJsonHttpMessageConverter添加到HttpMessageConverter
相应代码:

 ##com.mobin.config.WebMvcConfigurer
@Configuration
public class WebMvcConfigurer extends WebMvcConfigurerAdapter{
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullBooleanAsFalse,
SerializerFeature.PrettyFormat);
converter.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(config);
converters.add(converter);
}
}

SerializerFeature.WriteNullListAsEmpty:List类型字段为null时输出[]而非null
SerializerFeature.WriteMapNullValue:显示空字段
SerializerFeature.WriteNullStringAsEmpty:字符串类型字段为null时间输出""而非null
SerializerFeature.WriteNullBooleanAsFalse:Boolean类型字段为null时输出false而null
SerializerFeature.PrettyFormat:美化json输出,否则会作为整行输出

解决浏览器中返回json显示乱码问题(参考自:http://blog.csdn.net/kingboyworld/article/details/70068676

##application.properties
spring.http.encoding.charset=UTF-8
spring.http.encoding.enable=true
spring.http.encoding.force=true

6. 使用PageHelper进行分页
      分页使用的是PageHelper插件,基本原理就是在Executor及mappedStatement之间对SQL语句进行拦截并对SQL添加相应的分页操作再封装传递给mappedStatement,该插件支持单表及多表的分页,使用方便,只需在SQL执行语句前加上一条分布代码即可(通常是在server层),想想如果是手动的设置SQL语句的limit和offset,分页场景一旦多了就特别恶心,即便配合MyBatis的逆向工程也是。
1. 引入Spring boot对应的PageHelper依赖
2. 在application.properties配置PageHelper
3. 在指定的SQL语句前添加分页代码

 ##application.properties
#指定数据库方言
pagehelper.helperDialect=postgresql
#pageNum<=0时返回第一页数据,pageNum超过总页数时返回最后一页数据
pagehelper.reasonable=true

相应代码:

 ##com.mobin.service.impl.SubwayServiceImpl
public List<Subway> findSubways(int pageNum,int pageSize){
//第三个参数为fales时表示不对表进行count操作
PageHelper.startPage(pageNum,pageSize,false);
return subwayMapper.findSubways();
}

项目地址:

https://github.com/MOBIN-F/SpringBootRESTful

参考资料:

GitHub API

How to use @RestControllerAdvice for handling Exception with RestfulApi

PageHelper使用方法

SerializerFeature使用详解

logback相关配置

基于Spring Boot的RESTful API实践(一)的更多相关文章

  1. 使用 Spring Boot 构建 RESTful API

    1. 使用 Idea 创建 Spring Initializer 项目 在创建项目的对话框中添加 Web 和 Lombok,或者建立项目后在 pom.xml 中添加依赖: <dependency ...

  2. Spring Boot中Restful Api的异常统一处理

    我们在用Spring Boot去向前端提供Restful Api接口时,经常会遇到接口处理异常的情况,产生异常的可能原因是参数错误,空指针异常,SQL执行错误等等. 当发生这些异常时,Spring B ...

  3. Spring Boot构建RESTful API与单元测试

    如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建议先看一下相关的内容. @Controller:修饰class,用来创建处理http请求的对象 @RestController:Spr ...

  4. 用Kotlin写一个基于Spring Boot的RESTful服务

    Spring太复杂了,配置这个东西简直就是浪费生命.尤其在没有什么并发压力,随便搞一个RESTful服务 让整个业务跑起来先的情况下,更是么有必要纠结在一堆的XML配置上.显然这么想的人是很多的,于是 ...

  5. Spring Boot构建RESTful API

    @Controller:修饰class,用来创建处理http请求的对象 @RestController:Spring4之后加入的注解,原来在@Controller中返回json需要@ResponseB ...

  6. 通过spring boot提供restful api

    1 将返回设置为produces = "application/json" 返回给客户端json格式的response. 2 对各种异常的处理 各种异常如何返回给客户端? 各种异常 ...

  7. 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践

    由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...

  8. 基于spring boot 2.x 的 spring-cloud-admin 实践

    spring cloud admin 简介 Spring Boot Admin 用于监控基于 Spring Boot 的应用,它是在 Spring Boot Actuator 的基础上提供简洁的可视化 ...

  9. 基于Spring Boot和Spring Cloud实现微服务架构学习

    转载自:http://blog.csdn.net/enweitech/article/details/52582918 看了几周Spring相关框架的书籍和官方demo,是时候开始总结下这中间的学习感 ...

随机推荐

  1. Python中Template使用的一个小技巧

    Python中Template是string中的一个类,可以将字符串的格式固定下来,重复利用. from string import Template s = Template("there ...

  2. 使用 RxJS 实现一个简易的仿 Elm 架构应用

    使用 RxJS 实现一个简易的仿 Elm 架构应用 标签(空格分隔): 前端 什么是 Elm 架构 Elm 架构是一种使用 Elm 语言编写 Web 前端应用的简单架构,在代码模块化.代码重用以及测试 ...

  3. Docker-v17 的层级(layer)概念

    html,body { font-size: 12pt } body { font-family: Helvetica, "Hiragino Sans GB", "微软雅 ...

  4. u-boot核心初始化

    异常向量表:异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件.ARM Architecture Reference Manual p54页.7种异常的类型:Re ...

  5. php + 和 array_merge的区别

    (1)对于+,当key相同时,都是舍弃后面的结果: array_merge ,当key相同时,key是字符,则后面的覆盖前面的:key是数字,则不发生覆盖,会重新建立数组索引. $arr1 = arr ...

  6. 企业级docker仓库Harbor部署

    1.安装环境下载离线安装包地址https://github.com/vmware/harbor/releases/yum install -y dockerpip install -i https:/ ...

  7. python学习:hashlib模块使用

    #!/usr/bin/env python   import sys import hashlib   def md5sum(f):     m = hashlib.md5()     with op ...

  8. Lua内存分析工具

    最近给公司写了一个lua内存分析工具,可以非常方便的分析出Lua内存泄露问题,有图形化界面操作,方便手机端上传快照等功能 内存分析我是在c语言端写的,也有人写过lua端的分析工具,也蛮好用的,不过lu ...

  9. CSS单行、多行文本溢出显示省略号

    如果实现单行文本的溢出显示省略号小伙伴们应该都知道用text-overflow:ellipsis属性来,当然还需要加宽度width属来兼容部分浏览. 实现方法: overflow: hidden; t ...

  10. hbase优化之region合并和压缩

    HBASE操作:(一般先合并region然后再压缩) 一 .Region合并: merge_region   'regionname1','regionname2' ,'true'  --true代表 ...