Когда мы обычно разрабатываем проекты,Часто необходимо удаленно вызвать интерфейс, предоставленный другими Служить,Поэтому мы будем использовать некоторые классы HTTP-инструментов, такие как HttpUtil, предоставляемые Hutool. SpringBoot 3.0Из одного
Http Interface
новые возможности,Это позволяет нам вызывать удаленный интерфейс способом декларативных вызовов.,Сегодня мы поговорим о его использовании!
Http Interface
позволяет вам определить что-то вродеJavaинтерфейсопределил такHTTPСлужить,И использование точно такое же, как вы обычно пишете Controller. Он автоматически сгенерирует классы реализации прокси для этих HTTP.,Нижний уровень реализован на основе WebClient Webflux.
Использовать Декларативный вызов Служить действительно достаточно элегантен.,Вот абзациспользоватьHttp Interface
заявилHttpСлужитькод。
В SpringBoot 3.0серединаиспользовать
Http Interface
это очень просто,Давайте испытаем это ниже.
pom.xml
серединачетко определенныйSpringBootВерсия3.0.0
;<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Java 17
,Сначала нам нужно установить JDK 17,После завершения установки настройте проектSDKВерсияJava 17
,Адрес загрузки JDK: https://www.oracle.com/cn/java/technologies/downloads/Http Interface
нужно зависеть отwebfluxосознать,Нам также необходимо добавить его зависимости.<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Это может быть полезный для вас проект с открытым исходным кодом.,Проект торгового центра представляет собой комплекс SpringBoot + Vue + uni-app выполнитьиз Система электронной коммерции(Звезда Github 60 тыс.),Развертывание с использованием Docker-контейнеров,Бэкэнд поддерживает многомодульную и микро-архитектуру. Включая внешний проект торгового центра и внутреннюю систему управления.,Может поддерживать полную Заказпроцесс!Охватываемая продукция、Заказ、корзина、Разрешения、Купон、член、Оплата и другие функции!
Демонстрация проекта:
Для звонка ниже
mall-tiny-swagger
серединаизинтерфейс Например,Давайте испытаем этоHttp Interface
из Базовыйиспользовать。
mall-tiny-swagger
этотDemo,Откройте Swagger и посмотрите.,Существует интерфейс входа в систему и интерфейс CRUD торговой марки, требующий аутентификации при входе.,Адрес проекта: https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-swaggerapplication.yml
середина Настроенmall-tiny-swagger
из Служитьадрес;remote:
baseUrl: http://localhost:8088/
@HttpExchange
объявитьHttpСлужить,использовать@PostExchange
Аннотация указывает на прогрессPOSTпросить;/**
* Определить Httpинтерфейс, используемый для удаленного вызова UmsAdminСлужить
* Created by macro on 2022/1/19.
*/
@HttpExchange
public interface UmsAdminApi {
@PostExchange("admin/login")
CommonResult<LoginInfo> login(@RequestParam("username") String username, @RequestParam("password") String password);
}
/**
* Определить Httpинтерфейс, используемый для удаленного вызова PmsBrandСлужить
* Created by macro on 2022/1/19.
*/
@HttpExchange
public interface PmsBrandApi {
@GetExchange("brand/list")
CommonResult<CommonPage<PmsBrand>> list(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize);
@GetExchange("brand/{id}")
CommonResult<PmsBrand> detail(@PathVariable("id") Long id);
@PostExchange("brand/create")
CommonResult create(@RequestBody PmsBrand pmsBrand);
@PostExchange("brand/update/{id}")
CommonResult update(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrand);
@GetExchange("brand/delete/{id}")
CommonResult delete(@PathVariable("id") Long id);
}
TokenHolder
этотдобрый,Сохраните токен в сеансе;/**
* Хранение токена входа (в сеансе)
* Created by macro on 2022/1/19.
*/
@Component
public class TokenHolder {
/**
* добавить токен
*/
public void putToken(String token) {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
request.getSession().setAttribute("token", token);
}
/**
* Получить токен
*/
public String getToken() {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) ra).getRequest();
Object token = request.getSession().getAttribute("token");
if(token!=null){
return (String) token;
}
return null;
}
}
@Configuration
public class HttpInterfaceConfig {
@Value("${remote.baseUrl}")
private String baseUrl;
@Autowired
private TokenHolder tokenHolder;
@Bean
WebClient webClient() {
return WebClient.builder()
//Добавляем глобальный заголовок запроса по умолчанию
.defaultHeader("source", "http-interface")
//Добавляем фильтр к запросу и добавляем собственный заголовок аутентификации
.filter((request, next) -> {
ClientRequest filtered = ClientRequest.from(request)
.header("Authorization", tokenHolder.getToken())
.build();
return next.exchange(filtered);
})
.baseUrl(baseUrl).build();
}
@Bean
UmsAdminApi umsAdminApi(WebClient client) {
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
return factory.createClient(UmsAdminApi.class);
}
@Bean
PmsBrandApi pmsBrandApi(WebClient client) {
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
return factory.createClient(PmsBrandApi.class);
}
}
/**
* HttpInterfaceтестинтерфейс
* Created by macro on 2022/1/19.
*/
@RestController
@Api(tags = "HttpInterfaceController")
@Tag(name = "HttpInterfaceController", description = "HttpInterfaceтестинтерфейс")
@RequestMapping("/remote")
public class HttpInterfaceController {
@Autowired
private UmsAdminApi umsAdminApi;
@Autowired
private PmsBrandApi pmsBrandApi;
@Autowired
private TokenHolder tokenHolder;
@ApiOperation(value = "Вызов удаленного входаинтерфейс Получить токен")
@PostMapping(value = "/admin/login")
public CommonResult<LoginInfo> login(@RequestParam String username, @RequestParam String password) {
CommonResult<LoginInfo> result = umsAdminApi.login(username, password);
LoginInfo loginInfo = result.getData();
if (result.getData() != null) {
tokenHolder.putToken(loginInfo.getTokenHead() + " " + loginInfo.getToken());
}
return result;
}
@ApiOperation("Вызов удаленного интерфейса для запроса списка брендов")
@GetMapping(value = "/brand/list")
public CommonResult<CommonPage<PmsBrand>> listBrand(@RequestParam(value = "pageNum", defaultValue = "1")
@ApiParam("Номер страницы") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "3")
@ApiParam("Количество на странице") Integer pageSize) {
return pmsBrandApi.list(pageNum, pageSize);
}
@ApiOperation("Вызовите удаленный интерфейс, чтобы получить информацию о бренде с указанным идентификатором")
@GetMapping(value = "/brand/{id}")
public CommonResult<PmsBrand> brand(@PathVariable("id") Long id) {
return pmsBrandApi.detail(id);
}
@ApiOperation("Вызовите удаленный интерфейс, чтобы добавить бренд")
@PostMapping(value = "/brand/create")
public CommonResult createBrand(@RequestBody PmsBrand pmsBrand) {
return pmsBrandApi.create(pmsBrand);
}
@ApiOperation("Вызов удаленного интерфейса для обновления указанной информации о бренде")
@PostMapping(value = "/brand/update/{id}")
public CommonResult updateBrand(@PathVariable("id") Long id, @RequestBody PmsBrand pmsBrand) {
return pmsBrandApi.update(id,pmsBrand);
}
@ApiOperation("Вызов удаленного интерфейса для удаления бренда с указанным идентификатором")
@GetMapping(value = "/delete/{id}")
public CommonResult deleteBrand(@PathVariable("id") Long id) {
return pmsBrandApi.delete(id);
}
}
Http Interface
Давайте просто определиминтерфейс,Выполнять удаленные вызовы HTTP без определения реализаций методов.,Действительно очень удобно! Но его реализация опирается на WebClient Webflux.,Это вызовет некоторые проблемы, если мы будем использовать SpringMVC.,Было бы лучше, если бы вы могли быть независимыми!
Официальная документация: https://docs.spring.io/spring-framework/reference/integration/rest-clients.html.
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-http-interface