Практика RESTful API на основе Spring Boot (1)

Spring Boot
Практика RESTful API на основе Spring Boot (1)

1. RESTful введение
REST — это стиль дизайна, набор ограничений и принципов, а архитектура, соответствующая стилю REST, называется архитектурой RESTful. Ресурсы — это ядро ​​RESTful. Хорошую архитектуру RESTful можно четко понять по URL-адресу. Что такое операции и требования, т.е.
1. Найдите ресурсы по URL, например:
com.mobin/api/v1/shenzhen/subways //Получить список метро Шэньчжэня
com.mobin/api/v1/шэньчжэнь/школы //Получить список школ в Шэньчжэне
2. Операция описания HTTP
ПОЛУЧИТЬ: получить ресурс
POST: создать ресурс
ПОСТАВИТЬ: обновить ресурс
УДАЛИТЬ: удалить ресурс
Такие как:
GET com.mobin/api/v1/shenzhen/subways/1: получить информацию о метро с идентификатором 1.
Запрошенные ресурсы обычно возвращаются клиенту в формате JSON или XML.Использование архитектуры RESTful требует только предоставления набора RESTful на стороне сервера. API можно использовать в Интернете, IOS, Android
Дизайн API — это очень специфическая вещь, вы можете обратиться кСпецификация дизайна API GitHub

2. SpringBoot интегрирует MyBatis
1. Поместите xxxMapper.xml и sqlMapConfig.xml в соответствующий каталог ресурса.
2. application.properties загружает файл конфигурации MyBatis и настраивает источник данных.

 1 ##application.properties
 2 #加载mybatis配置文件
 3 mybatis.mapper-locations = classpath:mapper/*Mapper.xml
 4 mybatis.config-location = classpath:mapper/config/sqlMapConfig.xml
 5 ​
 6 #指定别名
 7 mybatis.type-aliases-package = com.mobin.entity
 8 ​
 9 #数据源
10 spring.datasource.url = jdbc:postgresql://localhost:5432/xxx
11 spring.datasource.driver-class-name = org.postgresql.Driver
12 spring.datasource.username = postgres
13 spring.datasource.password = xxxx

После MyBatis 3 официально предоставляется специальный API для поддержки динамического SQL. Аннотации + код Java можно использовать для замены XML, но сложные операторы SQL по-прежнему находятся в XML. XML более интуитивно понятен (фактически отвратительный). Вторжение слишком серьезно, и его необходимо перекомпилировать после модификации.

3. Конфигурация журнала
Структура журналов загрузки Spring по умолчанию — это Logback, который довольно удобен в настройке и имеет лучшую производительность, а также может фильтровать журналы указанных служб на разных уровнях, не затрагивая уровни журналов других служб.
1.Конфигурация журнала консоли
2.Конфигурация среды разработки, тестирования и производства

 1 ##logbcak-spring.xml
 2 <?xml version="1.0" encoding="UTF-8"?>
 3 <configuration debug="false">
 4    <contextName>${appname}</contextName>
 5    <!--控制台日志配置-->
 6    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 7    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
 8    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
 9    </encoder>
10    </appender>
11 ​
12    <appender name="FILEPROD" class="ch.qos.logback.core.rolling.RollingFileAppender">
13        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
14        <FileNamePattern>SpringBootRESTful.%d{yyyy-MM-dd}.log</FileNamePattern>
15        <!-- 日志保留天数-->
16        <MaxHistory>20</MaxHistory>
17        </rollingPolicy>
18        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
19            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
20        </encoder>
21    </appender>
22 ​
23    <appender name="FILETEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
24        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
25            <FileNamePattern>test.SpringBootRESTful.%d{yyyy-MM-dd}.log</FileNamePattern>
26            <MaxHistory>20</MaxHistory>
27        </rollingPolicy>
28        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
29            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]%-5level %logger{50} - %msg%n</pattern>
30        </encoder>
31    </appender>
32 ​
33    <!--开发环境的日志配置 -->
34    <springProfile name="dev">
35        <!--开发环境通常会对指定包或类进行测试 -->
36        <logger name="com.mobin.dao" level="DEBUG">
37            <appender-ref ref="STDOUT"/>
38        </logger>
39        <root level="INFO">
40            <appender-ref ref="STDOUT"/>
41        </root>
42    </springProfile>
43 ​
44    <!--测试环境的日志配置 -->
45    <springProfile name="test">
46        <root level="DEBUG">
47            <appender-ref ref="FILETEST"/>
48            <appender-ref ref="STDOUT"/>
49        </root>
50    </springProfile>
51 ​
52    <!--生产环境的日志配置 -->
53    <springProfile name="prod">
54        <root level="INFO">
55            <appender-ref ref="FILEINFO"/>
56            <appender-ref ref="STDOUT"/>
57        </root>
58    </springProfile>
59 </configuration>

4. Обработка исключений
4.1 В спецификации дизайна API обработка исключений, по крайней мере,
 1.Вернуть соответствующий код ошибки
 2.Вернуть соответствующее описание ошибки
 3.Соответствующий ресурсный модуль
4.2 Используйте @RestControllerAdvice для определения глобальной обработки исключений
@RestControllerAdvice — это Spring Новая функция после версии 4.3 эквивалентна @ControllerAdvice+ResponseBody, поэтому использование @RestControllerAdvice может возвращать информацию об ошибке в формате Json.
1. Пользовательский класс исключений

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

2. Определите глобальный класс исключений

 1 ##com.mobin.exception.GlobalExceptionHadlerActice
 2 @RestControllerAdvice
 3 public class GlobalExceptionHadlerActice {
 4    private static final long serialVersionUID = 1L;
 5    @ExceptionHandler(value = EntityNotFoundException.class)
 6    public ErrorMessage entityNotFoundException(HttpServletRequest request, Exception e){
 7        ErrorMessage errorMessage = new ErrorMessage();
 8        errorMessage.setStatus(HttpStatus.NOT_FOUND.value());
 9        errorMessage.setMessage(e.getLocalizedMessage());
10        errorMessage.setUrl(request.getRequestURL().toString());
11        return errorMessage;
12   }
13 }

ErrorMessage — это настраиваемый класс сущностей, включающий поля statusCode, сообщения и URL-адреса.

3. Соответствующий метод запроса

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

4. Тест с завитком

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

5. Используйте fastjson
1. Внедрить зависимости fastJson
2.Настройте WebMvcConfigurer и наследуйте WebMvcConfigurerAdapter
3.Переопределить метод configureMessageConverters
4.Пользовательская конфигурация FastJsonConfig
5.Добавьте FastJsonHttpMessageConverter в HttpMessageConverter
Соответствующий код:

 1 ##com.mobin.config.WebMvcConfigurer
 2 @Configuration
 3 public class WebMvcConfigurer extends WebMvcConfigurerAdapter{
 4    @Override
 5    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
 6        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
 7        FastJsonConfig config = new FastJsonConfig();
 8        config.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty,
 9                SerializerFeature.WriteMapNullValue,
10                SerializerFeature.WriteNullStringAsEmpty,
11                SerializerFeature.WriteNullBooleanAsFalse,
12                SerializerFeature.PrettyFormat);
13        converter.setDateFormat("yyyy-MM-dd HH:mm:ss");
14        converter.setFastJsonConfig(config);
15        converters.add(converter);
1617   }
18 }

SerializerFeature.WriteNullListAsEmpty: вывод [] вместо null, когда поле типа списка имеет значение null
SerializerFeature.WriteMapNullValue: показывает пустые поля
SerializerFeature.WriteNullStringAsEmpty: когда поле строкового типа имеет значение null, вместо null выводится ""
SerializerFeature.WriteNullBooleanAsFalse: вывод false и null, когда поле логического типа имеет значение null
SerializerFeature.PrettyFormat: украсить вывод json, иначе он будет выводиться как целая строка.

Решить проблему возврата json для отображения искаженных символов в браузере.(Ссылка из:blog.CSDN.net/king boy Я смирился с этим...)

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

6. Разбиение на страницы с помощью PageHelper
Пейджинг использует подключаемый модуль PageHelper.Основной принцип заключается в перехвате операторов SQL между Executor и mappedStatement, добавлении соответствующих операций подкачки в SQL, а затем инкапсуляции и передаче в mappedStatement.Плагин поддерживает однотабличное и многотабличное пейджинг, легко использовать, только Вам нужно добавить код распределения перед оператором выполнения SQL (обычно на уровне сервера). Подумайте о ручной установке предела и смещения оператора SQL. Когда сценариев подкачки слишком много, это будет особенно отвратительно, даже с реверс-инжинирингом MyBatis.
1.Введите зависимость PageHelper, соответствующую загрузке Spring.
2.Настройте PageHelper в application.properties
3.Добавить код подкачки перед указанным оператором SQL

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

Соответствующий код:

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

 

адрес проекта:

GitHub.com/mobi N-F/SPR…

Использованная литература:

GitHub API

How to use @RestControllerAdvice for handling Exception with RestfulApi

Как использовать PageHelper

SerializerFeature использует подробное объяснение

конфигурация, связанная с логбэком