Все еще используете HttpUtil? Новый HTTP-клиент SpringBoot 3 уже здесь, и он достаточно элегантен в использовании!
Все еще используете HttpUtil? Новый HTTP-клиент SpringBoot 3 уже здесь, и он достаточно элегантен в использовании!

Когда мы обычно разрабатываем проекты,Часто необходимо удаленно вызвать интерфейс, предоставленный другими Служить,Поэтому мы будем использовать некоторые классы 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
Язык кода:javascript
копировать
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.0.0</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
  • потому чтоSpringBootМинимальное требованиеJava 17,Сначала нам нужно установить JDK 17,После завершения установки настройте проектSDKВерсияJava 17,Адрес загрузки JDK: https://www.oracle.com/cn/java/technologies/downloads/
  • потому чтоHttp Interfaceнужно зависеть отwebfluxосознать,Нам также необходимо добавить его зависимости.
Язык кода:javascript
копировать
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Это может быть полезный для вас проект с открытым исходным кодом.,Проект торгового центра представляет собой комплекс SpringBoot + Vue + uni-app выполнитьиз Система электронной коммерции(Звезда Github 60 тыс.),Развертывание с использованием Docker-контейнеров,Бэкэнд поддерживает многомодульную и микро-архитектуру. Включая внешний проект торгового центра и внутреннюю систему управления.,Может поддерживать полную Заказпроцесс!Охватываемая продукция、Заказ、корзина、Разрешения、Купон、член、Оплата и другие функции!

  • Bootпроект:https://github.com/macrozheng/mall
  • Cloudпроект:https://github.com/macrozheng/mall-swarm
  • Видеоурок:https://www.macrozheng.com/video/

Демонстрация проекта:

Базовыйиспользовать

Для звонка нижеmall-tiny-swaggerсерединаизинтерфейс Например,Давайте испытаем этоHttp Interfaceиз Базовыйиспользовать。

  • Сначала мы готовим Служить для облегчения удаленных звонков.,использоватьпредыдущегоmall-tiny-swaggerэтотDemo,Откройте Swagger и посмотрите.,Существует интерфейс входа в систему и интерфейс CRUD торговой марки, требующий аутентификации при входе.,Адрес проекта: https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-swagger
  • первыйapplication.ymlсередина Настроенmall-tiny-swaggerиз Служитьадрес;
Язык кода:javascript
копировать
remote:
  baseUrl: http://localhost:8088/
  • пройти еще раз@HttpExchangeобъявитьHttpСлужить,использовать@PostExchangeАннотация указывает на прогрессPOSTпросить;
Язык кода:javascript
копировать
/**
 * Определить 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);
}
  • Создайте бренд удаленного вызова. Служить интерфейс, аннотации параметров использовать — это те, которые мы обычно используем при написании методов контроллера;
Язык кода:javascript
копировать
/**
 * Определить 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этотдобрый,Сохраните токен в сеансе;
Язык кода:javascript
копировать
/**
 * Хранение токена входа (в сеансе)
 * 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;
    }

}
  • Создать конфигурацию Java,Просто настройте объекты клиентWebClient и HttpСлужить, используемые для запросов.,Так как бренду Служить необходимо добавить заголовок аутентификации для нормального доступа.,Поэтому фильтры добавляются равномерно;
Язык кода:javascript
копировать
@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);
    }
}
  • Затем внедрите объект HttpСлужить в контроллер и вызовите его;
Язык кода:javascript
копировать
/**
 * 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);
    }
}

тест

  • Далее мы используем Postman для выполнения теста. Сначала мы вызываем интерфейс входа в систему, чтобы получить токен, возвращаемый удаленным Служить;
  • Затем вызовите список брендов, требующих аутентификации при входе, и обнаружите, что вы можете получить к нему обычный доступ.

Подвести итог

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

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose