Введение в обслуживание отдыха
Restful Service - это архитектурная модель, которая стала более популярной в последние годы. Его легкий веб -сервис играет нативную Get, Post, Post и Delete of Http -протокола. По сравнению со сложным SOAP и XML-RPC, веб-сервисы режима REST, очевидно, более краткие, и все больше и больше веб-сервисов начинают применять дизайн и реализацию стиля REST. Например, Amazon.com предоставляет веб -сервисы, которые близки к стилю отдыха для поиска книг; Веб -сервисы, предоставляемые Yahoo, также являются стилем отдыха. Отдых не всегда правильный выбор. Он стал популярным как метод разработки веб -сервисов, которые не полагаются на проприетарное промежуточное программное обеспечение, например, на сервер приложений, чем на методы на основе SOAP и WSDL. В некотором смысле, подчеркивая ранние интернет -стандарты, такие как URI и HTTP, REST является регрессией к веб -подходу до эры крупных серверов приложений.
Пример, как показано на следующем рисунке:
Ключом к использованию отдыха является то, как абстрагировать ресурсы. Чем точнее абстракция, тем лучше применение отдыха.
Ключевые принципы обслуживания отдыха:
1. Дайте всем объектам идентификатор
2. Подключить объекты вместе
3. Используйте стандартные методы
4. Многочисленные представления ресурсов
5. Общение без гражданства
В этой статье представлено, как создать простую структуру обслуживания REST на основе Spring Boot и как реализовать аутентификацию службы REST через пользовательские аннотации
Построить рамку
Pom.xml
Во -первых, введите связанные зависимости, используйте MongoDB для баз данных и используйте Redis для кэша
ПРИМЕЧАНИЕ: Здесь нет Tomcat, но не
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <!--redis support--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-Поддержка MongoDB-> <Dependency> <groupId> org.springframework.boot </GroupId> <ratifactId> Spring-Boot-Starter-Data-MongoDB </artifactid> </vehyse>
Представьте веб-сервис поддержки Spring-Boot-Starter-Web Weeb
Представление Spring-Boot-Starter-Data-Redis и Spring-Boot-Starter-Data-Mongodb может легко использовать MongoDB и Redis
Файл конфигурации
Профили функционируют
Чтобы облегчить различие между средой разработки и онлайн -средой, функция профилей может использоваться для добавления в приложение.
spring.profiles.active=dev
Затем добавьте Application-dev.properties в качестве файла конфигурации DEV.
Конфигурация Mondb
Просто настройте адрес базы данных
spring.data.mongodb.uri = mongodb: // ip: port/database? readpreference = primaryprefrefred
Конфигурация Redis
spring.redis.database = 0 # redis Server Adders Adder Spring.redis.host = ip # Redis Server Connection Port Spring.Redis.port = 6379 # Redis Server Connection Password (по умолчанию пусто) Spring.redis.password = # Максимальное количество подключений в соединении (использование негативных значений не означает ограничение) spring.redis.pool.max-wait = -1 # максимальное соединение холостого хода в пуле подключений Spring.redis.pool.max-IDLE = 8 # Минимальное соединение с минимальным холостовым холодильником в пуле подключений. Ред.
Доступ к данным
Mongdb
Доступ к Mongdb очень прост. Вы можете напрямую определить интерфейс расширяет MongorePository. Кроме того, он может поддерживать синтаксис JPA, например:
@Componentpublic interface userRepository Extends mongorePository <user, integer> {public user findbyusername (String username);}При его использовании просто добавьте аннотацию @autowired.
@Componentpublic class ayservice extends baseservice {@autowired userRepository userRepository; }Redis Access
Используйте StringRedistemplate, чтобы получить доступ к Redis напрямую
@Componentpublic class baseservice {@autowired Защищенное монготневое mongotemplate; @Autowired protected stringredistemplate stringredistemplate; }Хранить данные:
.stringRedistemplate.osforValue (). set (token_key, user.getid ()+"", token_max_age, timeUnit.seconds);
Удалить данные:
stringredistemplate.delete (getFormattoken (AccessToken, Platform));
Веб -сервисы
Определите класс контроллера, добавьте RestController и используйте MeargeMapping для установки маршрута URL -адреса
@RestControllerPublic Class AuthController Extends BaseController {@RequestMapping (value = {"/"}, Pruefes = "Application/json; charset = utf-8", method = {requestMethod.get, requestMethod.post}) @responsebody public string main (return "hello world!"; }}Теперь начните, вы сможете увидеть Hello World! Его
Аутентификация услуг
Простой механизм AccessToken
Предоставьте интерфейс входа в систему. После успешной аутентификации сгенерируется AccessToken. При доступе к интерфейсу в будущем, AccessToken приносит с ним. Сервер использует AccessToken, чтобы определить, является ли он законным пользователем.
Для удобства вы можете сохранить AccessToken в Redis и установить период достоверности.
String token = encryptionutils.sha256Hex (string.format ("%s%s", user.getUsername (), system.currenttimemillis ())); String token_key = getFormattoken (token, platform); this.stringredistemplate.opforvalue (). set (token_key, user.getid ()+"", token_max_age, timeUnit.seconds);Аутентификация идентификации перехвата
Чтобы облегчить аутентификацию единой идентификации, может быть создан перехватчик на основе механизма перехвата Spring для выполнения единой аутентификации.
открытый класс AuthCheckEnterceptor реализует HandlerInterceptor {}Чтобы перехватчик вступил в силу, для добавления конфигурации необходим еще один шаг:
@ConfigurationPublic Class SessionConfiguration Extends webmvcconfigurerAdapter {@autowired autheckEcterceptor autheCheckInterceptor; @Override public void AddInterceptors (реестр ReceptorTorgistry) {Super.Adinterceptors (реестр); // Добавить receptor Registry.addinterceptor (AuthCheckEnterceptor) .AdDpathPatterns ("/**"); }}Пользовательские аннотации аутентификации
Например, чтобы уточнить аутентификацию разрешений, люди могут быть доступны только людьми с определенными разрешениями, и их можно легко решить с помощью пользовательских аннотаций. В пользовательской аннотации просто добавьте роли.
/*** Аннотация проверки разрешения*/@target (elementtype.method) @retention (artententypolicy.runtime) @documentedpublic @interface authcheck {/*** list* @return*/string [] rooles () default {};}Логика проверки:
Пока интерфейс добавляется с аннотацией Authcheck, он должен быть зарегистрированным пользователем
Если указаны роли, в дополнение к входу в систему, пользователь также должен играть соответствующую роль.
String [] ignoreUrls = new String [] {"/user/.*", "/Cat/.*", "/app/.*", "/error"}; Public Boolean Prehandle (httpservlectrequest httpservletrequest, httpservletresponse httpservletresponse, обработчик объекта) исключает исключение {// 0 Проверьте публичные параметры, если (! Checkparams («Платформа», httpservlectrequest, httpservelponse)) {return false; } // 1. Игнорировать проверку url string url = httpservletrequest.getRequesturi (). ToString (); for (string ignoreurl: ignoreurls) {if (url.matches (ignoreurl)) {return true; }} // 2. Аннотация проверки запроса ручной работы handlermethod = (handlermethod) Handler; Метод метод = handlermethod.getmethod (); // Аннотация запроса authcheck authcheck = method.getannotation (authcheck.class); if (authcheck == null) {// без аннотации, нет возврата true; } // 3. Если есть аннотация, проверьте AccessToken Сначала if (! CACKPARAMS ("AccessToken", httpservletRequest, httpservletresponse)) {return false; } // Проверьте, истекает ли токен integer userId = authService.getUserIdFromToken (httpservletrequest.getParameter ("accessToken"), httpservletrequest.getParameter ("платформа")); if (userId == null) {logger.debug ("accessToken") timeout "); output (responseSult.builder.error (" accessToken expired "). Build (), httpservletrespons if (authcheck.roles ()! Неудача if (! ismatch) {return false; Энкапсуляция результатов ответа на обслуживание
Добавьте строитель, чтобы облегчить получение окончательных результатов
Открытый класс ответа {public static class builder {responserSult responserSult; Map <string, object> dataMap = maps.newhashmap (); public Builder () {this.ResponserEsult = new RepsCesserSult (); } public Builder (String State) {this.ResponserEsult = new ответа на штат); } public Static Builder newBuilder () {return new Builder (); } public Static Builder Success () {return New Builder ("Успех"); } public Static Builder Error (String Message) {Builder Builder = new Builder ("error"); Builder.ResponserSult.SetError (сообщение); возвратный строитель; } public Builder Append (String Key, объект Data) {this.datamap.put (key, data); вернуть это; } / *** Установить список данных* @param Data* @return* / public Builder SetListData (List <?> Datas) {this.Datamap.put ("result", dataS); this.datamap.put ("total", datas.size ()); вернуть это; } public Builder setData (Data Object) {this.datamap.clear (); this.sresponseresult.setData (data); вернуть это; } boolean wrooddata = false; / ** * Обернуть данные в данные * @param wrooddata * @return */ public Builder wrap (boolean wrouddata) {this.wrapdata = wrapdata; вернуть это; } public String build () {jsonObject jsonObject = new jsonObject (); jsonobject.put ("state", this.responseresult.getState ()); if (this.responseresult.getState (). Equals ("error")) {jsonObject.put ("error", this.ResponserSult.getError ()); } if (this.responseresult.getData ()! = null) {jsonObject.put ("data", json.tojson (this.responseresult.getData ())); } else if (dataMap.size ()> 0) {if (wrapData) {jsonObject data = new jsonObject (); dataMap.foreach ((key, value) -> {data.put (key, value);}); jsonObject.put ("data", data); } else {dataMap.foreach ((key, value) -> {jsonObject.put (key, value);}); }} return jsonObject.tojsonstring (); }} частное строковое состояние; данные частного объекта; Приватная строка ошибка; public String getError () {return error; } public void seterror (строка ошибка) {this.error = error; } public ousserSult () {} public ousserSult (string rc) {this.state = rc; } / ** * Возврат при успешном * @param rc * @param result * / public oussersult (string rc, object result) {this.state = rc; this.data = результат; } public String getState () {return State; } public void setState (String state) {this.state = state; } public Object getData () {return Data; } public void setData (data Object) {this.Data = data; }} Быть более элегантным при звонке
@Requestmapping (value = {"/user/login", "/pc/user/login"}, provectes = "application/json; charset = utf-8", method = {requestMethod.get, requestMethod.post}) @ResponseBody public String Login (String username, String password, pllatory integer) {uster user = this. if (user! = null) {// Войти в string token = authservice.updateTetoken (user, platform); return responseresult.builder .success () .append ("accessToken", token) .append ("userId", user.getId ()) .build (); } return responsersult.builder.error («Пользователь не существует или пароль неверен»). build (); } Защищенная строковая ошибка (строковое сообщение) {return responsersult.builder.error (message) .build (); } Защищенный String Success () {return responseSult.builder .success () .build (); } Защищенный String SuccessDatalist (list <?> data) {return responsersult.builder .success () .wrap (true) // data package.setlistdata (data) .build (); }Суммировать
Вышеуказанное - все содержание этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.