Обновление
Если вы ещё недостаточно знакомы с RESTful или считаете, что это просто стандарт без практического применения, рекомендую статью с сайта OSC, опубликованную два года назад: Лучшие практики проектирования RESTful API и очень теоретическую статью на сайте InfoQ: Понимание истинной природы архитектурного стиля REST. Несмотря на то, что они немного устарели и содержат простое описание, можно использовать их как базовое понимание. Больше преимуществ RESTful можно найти на Google.
Имеет такую же простую активную модель данных, как jfinal/activejdbc, использует более простой RESTful фреймворк.Проектирование RESTful API является лучшим выбором для серверной части RESTful сервиса (используется для разделения клиента и сервера, предоставляет API для статических HTML-клиентов (MVVM и т.д.), iOS, Android и других).Руководство по Java-разработке: Java стиль
Руководство по проектированию HTTP-API: HTTP API дизайн
Примеры Resty: resty-samples (только API) resty-demo (с интерфейсом)
Если вы рассматриваете вариант разделения front-end и back-end, рекомендую использовать resty + vuejs, https://github.com/Dreampie/vuejs2-demo
Полезные плагины от других разработчиков:
Если вас интересует участие в совместной работе над этим проектом, свяжитесь со мной.
Нормы работы:
Перед началом работы следует указать функционал. Создайте новую ветку с названием feature/дата
для новых функций и fix/дата
для исправлений. В разделе README добавьте список задач TODO. Пример:
Обратите внимание на два пробела отступа при оформлении кода. После этого все участники должны проверить код друг за другом, а затем объединить его с основной веткой master.Инструкция по использованию Maven:
Добавьте зависимость:
<dependency>
<groupId>cn.dreampie</groupId>
<artifactId>resty-route</artifactId>
<version>1.3.1.SNAPSHOT</version>
</dependency>
Если вы используете пакет с суффиксом SNAPSHOT, добавьте следующий репозиторий:
<repositories>
<repository>
<id>oss-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Запись (record)的时代已经到来,您可以完全使用它来处理数据而无需创建模型。
// Создание исполнителя записи для таблицы sec_user и включение кэширования
Record recordDAO = new Record("sec_user");
// Используя текущий источник данных и данные таблицы создаем объект для хранения данных
recordDAO.reNew().set("атрибут", "значение").save();
Record r1 = recordDAO.reNew().set("атрибут", "значение");
Record r2 = recordDAO.reNew().set("атрибут", "значение");
// Сохранение в батче
recordDAO.save(r1, r2);
// Обновление
r2.set("атрибут", "значение").update();
// Получение всех записей
List<Record> записи = recordDAO.findAll();
// Условный поиск
recordDAO.findBy(where, paras);
// Поиск с пагинацией
Page<Record> записи = recordDAO.paginateAll();
// Удаление по id
recordDAO.deleteById("1");
// В данном запросе отключаем использование кэша recordDAO.unCache().findBy(where, paras); // Устанавливаем источник данных record в dsmName recordDAO.useDS(dsmName).findBy(where, paras);
```java
// Поддержка динамического переключения источников данных и отключения кэширования для текущего запроса
User dao = new User();
// Отключение использования кэша для данного запроса
dao.unCache().findBy(where, paras);
// Установка источника данных model в dsmName
dao.useDS(dsmName).findBy(where, paras);
// Настройки базы данных и глобальные параметры перемещены в application.properties, подробнее см. resty-example
# Автоматическая загрузка не обязательна
app.encoding=UTF-8
app.devEnable=true
app.showRoute=false
app.cacheEnabled=true
# По умолчанию используется ehcacheProvider
# app.cacheProvider=cn.dreampie.cache.redis.RedisProvider
## Конфигурация плагина druid для автоматической загрузки
db.default.url=jdbc:mysql://127.0.0.1/example?useUnicode=true&characterEncoding=UTF-8
db.default.user=dev
db.default.password=dev1010
db.default.dialect=mysql
#c3p0 конфигурация
c3p0.default.minPoolSize=3
c3p0.default.maxPoolSize=20
# Конфигурация druid
# druid.default.initialSize=10
# druid.default.maxPoolPreparedStatementPerConnectionSize=20
# druid.default.timeBetweenConnectErrorMillis=1000
# druid.default.filters=slf4j,stat,wall
# Конфигурация flyway для автоматической миграции базы данных
flyway.default.validClean=true
flyway.default.migrationAuto=true
flyway.default.migrationInitOnMigrate=true
db.demo.url=jdbc:mysql://127.0.0.1/demo?useUnicode=true&characterEncoding=UTF-8
db.demo.user=dev
db.demo.password=dev1010
db.demo.dialect=mysql
# Конфигурация druid
druid.demo.initialSize=10
druid.demo.maxPoolPreparedStatementPerConnectionSize=20
druid.demo.timeBetweenConnectErrorMillis=1000
druid.demo.filters=slf4j,stat,wall
# Конфигурация flyway
flyway.demo.validClean=true
flyway.demo.migrationAuto=true
flyway.demo.migrationInitOnMigrate=true
``````java
// Минимальная конфигурация базы данных, автоматически читающая параметры из файла, требуется только указание директории сканирования моделей и имени источника данных
public void configPlugin(PluginLoader pluginLoader) {
// Первый источник данных
ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(new DruidDataSourceProvider("default"), true);
activeRecordPlugin.addIncludePaths("cn.dreampie.resource");
pluginLoader.add(activeRecordPlugin);
}
2. Минимальный дизайн активной записи данных, операции с данными требуют всего одной строки кода, поддерживаются массовые сохранения объектов.
```java
//Массовое сохранение
User u1 = new User().set("username", "тест").set("providername", "тест").set("password", "123456");
User u2 = new User().set("username", "тест").set("providername", "тест").set("password", "123456");
User.dao.save(u1, u2);
//Обычное сохранение
User u = new User().set("username", "тест").set("providername", "тест").set("password", "123456");
u.save();
``` // Обновление
u.update();
// Условное обновление
User.dao.updateBy(columns, where, paras);
User.dao.updateAll(columns, paras);
// Удаление
u.deleted();
// Условное удаление
User.dao.deleteBy(where, paras);
User.dao.deleteAll();
// Поиск
User.dao.findById(id);
User.dao.findBy(where, paras);
User.dao.findAll();
// Пагинация
User.dao.paginateBy(pageNumber, pageSize, where, paras);
User.dao.paginateAll(pageNumber, pageSize);
```java
Client httpClient = null; // Создание объекта клиента
// Запустите проект resty-example, чтобы протестировать клиента
String apiUrl = "http://localhost:8081/api/v1.0";
// Если учетная запись не требуется, то ее можно пропустить
// httpClient = new Client(apiUrl);
// Если есть ограничения по правам доступа, то потребуется авторизация
httpClient = new Client(apiUrl, "/tests/login", "u", "123");
// Этот запрос должен быть выполнен после авторизации, иначе будет возвращён код ошибки 401 (неавторизован)
ClientRequest authRequest = new ClientRequest("/пользователи");
ClientResult authResult = httpClient.build(authRequest).get();
System.out.println(authResult.getResult());
// GET
ClientRequest getRequest = new ClientRequest("/tests");
ClientResult getResult = httpClient.build(getRequest).get();
System.out.println(getResult.getResult());
// POST
ClientRequest postRequest = new ClientRequest("/tests");
postRequest.addParam("test", Jsoner.toJSONString(Maper.of("a", "谔谔")));
ClientResult postResult = httpClient.build(postRequest).post();
System.out.println(postResult.getResult());
// PUT
ClientRequest putRequest = new ClientRequest("/тесты/х");
ClientResult putResult = httpClient.build(putRequest).put();
System.out.println(putResult.getResult());
``````markdown
//удаление
ClientRequest deleteRequest = new ClientRequest("/тесты/а");
ClientResult deleteResult = httpClient.build(deleteRequest).delete();
System.out.println(deleteResult.getResult());
//загрузка
ClientRequest uploadRequest = new ClientRequest("/тесты/resty");
uploadRequest.addUploadFiles("resty", ClientTest.class.getResource("/resty.jar").getFile());
uploadRequest.addParam("описание", "тестовый файл параметры 测试笔");
ClientResult uploadResult = httpClient.build(uploadRequest).post();
System.out.println(uploadResult.getResult());
//скачивание Поддерживает прерывистую загрузку
ClientRequest downloadRequest = new ClientRequest("/тесты/файл");
downloadRequest.setDownloadFile(ClientTest.class.getResource("/resty.jar").getFile().replace(".jar", "x.jar"));
ClientResult downloadResult = httpClient.build(downloadRequest).get();
System.out.println(downloadResult.getResult());
4.Поддержка нескольких источников данных и вложенных транзакций (в случае использования: при необходимости доступа к нескольким базам данных, или как внутренний компонент данных компании для предоставления клиентам API доступа к данным)
// В ресурсе используется транзакция, то есть в контроллере, в мире REST все запросы считаются ресурсами, поэтому здесь это называется ресурсом
@GET("/пользователи")
@Transaction(name = {"по умолчанию", "демо"}) // Транзакция с несколькими источниками данных, если у вас всего один источник данных, используйте просто @Transaction без параметров
public User transaction() {
// TODO Используйте модель для выполнения операций с базой данных, любое возникшее исключение приведёт к откату обоих источников данных, хотя это не распределённая транзакция, она обеспечивает безопасность выполнения блока кода
}
<! -- Если вам требуется реализовать транзакцию в сервисе с помощью динамического прокси Java (обязательно использовать интерфейсы, так проектировалось JDK) -->
public interface UserService {
@Transaction(name = {"demo"}) // Чтобы добавить транзакцию с несколькими источниками данных в сервисе, если используется только один базовый источник данных, используйте просто @Transaction без параметров
public User save(User u);
}
<! -- В ресурсах используйте транзакцию уровня сервиса --> <! -- Аннотация @Transaction(name = {"demo"}) должна быть указана на интерфейсе сервиса --> <! -- Обратите внимание, что автоматическое проксирование Java требует наличия интерфейса --> <! -- TransactionAspect — это аспект транзакции, вы также можете реализовать свои аспекты, такие как аспект логирования, реализуя интерфейс Aspect --> <! -->-- Например, private UserService userService = AspectFactory.newInstance(new UserServiceImpl(), new TransactionAspect(), new LogAspect()); -->
private UserService userService = AspectFactory.newInstance(new UserServiceImpl(), new TransactionAspect(), new LogAspect());
// Implementation of the interface public class MyAuthenticateService implements AuthenticateService { // Upon entering the system via a username, we retrieve their password and access rights information public Principal findByName(String name) { DefaultPasswordService defaultPasswordService = new DefaultPasswordService();
Principal principal = new Principal(name, defaultPasswordService.hash("123"), new HashSet<String>() {{
add("api");
}});
return principal;
}
// Main list of all access rights where all URL permissions are stored. You can configure these permissions through a configuration file, database or directly in the code.
public Set<Credential> loadAllCredentials() {
Set<Credential> credentials = new HashSet<Credential>();
credentials.add(new Credential("GET", "/api/v1.0/users**", "users"));
return credentials;
}
}
6. Minimal caching implementation that easily scales and automatically activates model caching.
```java
// Activate caching and apply it to the model you want to cache
//@Table(name = "sec_user", cached = true)
@Table(name = "sec_user", cached = true)
public class User extends Model<User> {
public static User dao = new User();
}
File
.@GET("/files")
public File file() {
return new File(path);
}
```8. Для загрузки файла используется аннотация для указания директории назначения.
```java
@POST("/files")
@FILE(dir = "/upload/") // Настройка информации о загружаемых файлах
public UploadedFile file(UploadedFile file) {
return file;
}
public void configConstant(ConstantLoader constantLoader) {
// Возврат различных типов данных на основе расширения файла. Можно добавить свои собственные Render, такие как FreemarkerRender.
// По умолчанию уже добавлены json и text. Добавьте свои собственные Render для использования.
// constantLoader.addRender("json", new JsonRender());
}
Создайте базы данных demo и example в локальной базе данных MySQL, соответствующие конфигурациям базы данных в application.properties.
Запустите pom.xml
в папке resty-example -> flyway-maven-plugin:migrate
, чтобы автоматически создать структуру таблиц на основе файлов базы данных в директории resources/db.
Запустите pom.xml
в папке resty-example -> tomcat6-maven-plugin:run
, чтобы запустить программу example.
Примечание: рекомендуется использовать IntelliJ IDEA как среду разработки для модульной разработки с несколькими модулями.
Лицензия: Apache License V2
Донат: Али-pay
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )