Http Helper
HttpHelper — это облегчённый HTTP-запросный фреймворк, направленный на предоставление простых и понятных интерфейсов для HTTP-запросов, что позволяет разработчикам сосредоточиться на бизнес-логике и повысить эффективность работы. Версия v2.0 предоставляет набор процессов обработки HTTP-запроса и стандартов, которые позволяют добавлять разнообразные функциональные возможности в конвейер запросов.
Разработчики могут определять запросы к REST-интерфейсам с помощью интерфейса Interface
, соответствующего каждому клиентскому определению. Достаточно настроить конфигурацию в соответствии с определением интерфейса, чтобы реализовать декларативный вызов, подобный RPC. Это делает интерфейс запроса простым, стандартизированным, эффективным и легко читаемым.
Для запросов HTML-ресурсов можно использовать WebClient, который не только поддерживает выполнение AJAX-запросов через JS-рендеринг, но и предоставляет функции извлечения данных, поддерживающие xpath, css и регулярные выражения для определения правил извлечения данных. Данные могут быть извлечены в виде сложных форматированных объектов.
Версия v2.0 предлагает более гибкие механизмы расширения, больше встроенных функций и более высокую производительность, а также использует совершенно новый подход к проектированию.
Дизайн учитывает повторное использование кода, модулей и шаблонов, а также уделяет внимание повторному использованию моделей. Конвейер запросов основан на шаблонах, а не на отдельных интерфейсах, что позволяет разрабатывать новые обработчики, основываясь на общих чертах шаблонов.
Конфигурация шаблона TempleConfig поддерживает наследование, позволяя определить общие родительские конфигурации верхнего уровня и использовать наследование и обобщение для создания индивидуальных конфигураций.
Использование стандартов и соглашений позволяет преобразовать проблемы, связанные с запросами к интерфейсу, в определение клиента на основе бизнес-интерфейса. Требуется лишь скопировать определение интерфейса ввода-вывода POJO для завершения определения одного интерфейса запроса.
Встроенные обработчики в текущем конвейере запросов могут удовлетворить большинство сценариев использования HTTP-запросов в Java.
PS: Недавно я потратил некоторое время на рефакторинг HttpHelper, чтобы он мог быть адаптирован под SpringBoot, и использовал новый подход для решения проблем.
Также обратите внимание на мой другой открытый проект (рекомендуемый проект) «Ядро пакета распределённой задачи» https://gitee.com/wolfsmoke/ws-task.
[Объяснение HttpPipeline](docs/HttpPipeline объяснение.md)
[Объяснение протокола Http](docs/Объяснение протокола Http.md)
[Объяснение HttpHandler](docs/Объяснение HttpHandler.md)
[UT объяснение](docs/UT объяснение.md)
Подробные сведения см. в README.MD модуля: http-helper-sample.
Пример представляет собой приложение SpringBoot и использует @EnableHttpHelper для включения функции.
Способ Builder предоставляет гибкий способ настройки для создания объектов HttpHelper. В проекте SpringBoot вы можете использовать @Bean для внедрения объекта в контейнер, чтобы его можно было внедрить.
Функция примера: этот пример может загружать все изображения с URL-адреса в локальный.
Фрагмент кода для создания объекта HttpHelper:
/**
* Запрос и анализ изображений в сети
* @return
*/
@Bean
public HttpHelper searchImgHttp(){
RequestTemplate template = RequestTemplateBuilder.builder()
// Конфигурация клиента
.buildClientConfig()
.clientType(ClientType.WEB_CLIENT)
.enableSsl(true)
.enableCookie(true)
.followRedirects(true)
.threadNumber(4)
.timeout(10_000)
.privateClient(false)
.requestConfig()
// Добавить поле анализа HTML: тип List, анализ с использованием CSS,
// выражение анализа img@src => означает получение всех ссылок на изображения на веб-странице
.addParseHtmlFields(new ParseField("imageList", ParseFieldType.LIST, "img@src", ExpressionType.CSS))
.method(HttpMethod.GET)
.charset("UTF-8")
// Добавление: обработчик по умолчанию перед запросом
Этот текст представляет собой перевод исходного текста. Он может содержать неточности или ошибки, поскольку исходный текст содержит специальные символы и форматирование, которые невозможно точно передать в переводе. **Текст запроса:**
```
.addHandler(DefaultHandlers.requestHandlers())
// 添加:解析响应内容类型
.addHandler(new ParseResponseTypeHandler())
// 添加:根据ParseHtmlFields解析HTML处理器
.addHandler(new ParseHtmlHandler())
.end()
.build();
// 根据template创建一个HttpHelper对象
return HttpHelperBuilder.builder().builderByTemplate(template);
}
/**
* 保存图片HttpHelper
* @return
* @throws URISyntaxException
*/
@Bean
public HttpHelper saveImgHttp() throws URISyntxException {
RequestTemplate template = RequestTemplateBuilder.builder()
// 客户端配置:使用默认OkHttpClient配置
.clientConfig(DefaultClientConfig.okHttpClientConfig(4,3_000,true))
.buildRequestConfig()
.method(HttpMethod.GET)
.charset("UTF-8")
// 添加:默认请求前处理器
.addHandler(DefaultHandlers.requestHandlers())
// 解析响应内容类型
.addHandler(new ParseResponseTypeHandler())
// 保存文件Handler
.addHandler(saveFileHandler())
.end()
.build();
return HttpHelperBuilder.builder().builderByTemplate(template);
}
/**
* 保存文件Handler
* @return
* @throws URISyntaxException
*/
@Bean
public ResponseHandler saveFileHandler() throws URISyntxException {
Path path = Paths.get(this.getClass().getResource("/").toURI());
String savePath = path.toString()+"/download";
SaveFileHandler saveFileHandler = new SaveFileHandler(savePath);
saveFileHandler.setFollowUrlPath(true);
log.info("savePath:{}",savePath);
return saveFileHandler;
}
```
**Перевод текста на русский язык:**
```
.addHandler (DefaultHandlers.requestHandlers ())
// Добавить: анализ типа содержимого ответа
.addHandler (новый ParseResponseTypeHandler ())
// Добавить: обработчик анализа HTML на основе ParseHtmlFields
.addHandler (новый ParseHtmlHandler ())
.end ()
.build ();
// Создать объект HttpHelper на основе шаблона
вернуть HttpHelperBuilder.builder ().builderByTemplate (шаблон);
}
/**
* Сохранить изображение HttpHelper
* @return
* @throws URISyntaxException
*/
@Bean
общедоступный HttpHelper saveImgHttp () выбрасывает URISyntxException {
Запрос шаблона шаблона = RequestTemplateBuilder.builder ()
// Конфигурация клиента: использование конфигурации OkHttpClient по умолчанию
.clientConfig (DefaultClientConfig.okHttpClientConfig (4, 3_000, true))
.buildRequestConfig ()
.метод (HttpMethod.GET)
.кодировка («UTF-8»)
// Добавить: обработчик запросов по умолчанию
.addHandler (DefaultHandlers.requestHandlers ())
// Анализ типа содержимого ответа
.addHandler (новый ParseResponseTypeHandler ())
// Обработчик сохранения файла
.addHandler (saveFileHandler ())
.end ()
.build ();
вернуть HttpHelperBuilder.builder ().builderByTemplate (шаблон);
}
/**
* Обработчик сохранения файлов
* @return
* @throws URISyntaxException
*/
@Bean
публичный ответчик saveFileHandler () выбрасывает URISyntxException {
Путь путь = пути.получить (этот.getClass ().getResource ("/"). ToURI ());
Строка savePath = путь.toString () + "/загрузка";
Сохранить файл обработчика сохранить файл обработчика = новый сохранить файл обработчика (сохранить путь);
сохранить файл обработчика.setFollowUrlPath (истина);
журнал.информация («savePath: {}», сохранить путь);
вернуть сохранить файл обработчика;
}
``` **Annotation示例二: 根据 API интерфейса описанию, определение API запроса интерфейса**
> Согласно описанию интерфейса платформы открытых данных, определяется соответствующий интерфейс, который может реализовать псевдо-RPC декларативный вызов, подобный @Feign.
>
>Интерфейс документа: http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
~~~java
/**
* Определение API запроса интерфейса согласно описанию API интерфейса
*/
// Глобальный клиент этого интерфейса
@HttpClient(
clientType = ClientType.OK_HTTP_CLIENT,
privateClient = true,
timeout = 3_000, threadNumber = 4,
enableCookie = false, followRedirects = false, enableSsl = false
)
// Глобальная конфигурация запроса этого раздела
@HttpRequest(
rootUrl = "http://api.map.baidu.com/place/v2",
contentType = ContentType.X_WWW_FORM_URLENCODED,
responseType = ResponseType.JSON,
method = HttpMethod.GET
)
@HttpOperation
public interface BaiduMapSearchApi {
/**
* Использование аннотаций для указания запроса и ответа сущности, параметр является сущностью
* @param path путь запроса
* @param param класс сущности параметра
* @return сущность ответа
*/
@Get(
requestEntity = SearchRegionParam.class, // Класс сущности запроса
responseEntity = SearchRegionResult.class, // Класс сущности ответа (можно не указывать, передать при вызове)
handlers = {BuildSnHandler.class} // Добавить обработчик создания URL-адреса sn (встроенные обработчики по умолчанию будут автоматически добавлены)
)
SearchRegionResult searchRegionByEntity(String path, SearchRegionParam param);
/**
* Использование аннотации для настройки запроса, параметр - карта, ответ - универсальный тип
* @param path путь запроса
* @param map карта параметров
* @param outputClass класс ответа
* @param <T> тип ответа: может быть Map или JSON соответствующая сущность класса
* @return
*/
@Get(
requestParams = { // Настройка параметров запроса с помощью аннотаций
@RequestParam(fieldName = "query", required = true, example = "天安门、美食", description = "ключевые слова поиска"),
@RequestParam(fieldName = "tag", example = "美食", description = "категория поиска предпочтений"),
@RequestParam(fieldName = "region", required = true, example = "北京、131(北京的code)、海淀区、全国,等", description = "область данных поиска"),
@RequestParam(fieldName = "city_limit", defaultValue = "true", example = "true、false", description = "ограничение данных области поиска, если true, то только данные в пределах region"),
@RequestParam(fieldName = "extensions_adcode", defaultValue = "true", example = "true、false", description = "включать ли код административного деления страны, если true, то включать"),
@RequestParam(fieldName = "output", defaultValue = "json", example = "json или xml", description = "формат вывода json или xml"),
@RequestParam(fieldName = "scope", defaultValue = "1", example = "1、2", description = "степень детализации результатов поиска. Если значение равно 1 или пусто, возвращаются основные сведения; если значение равно 2, возвращаются подробные сведения о POI"),
@RequestParam(fieldName = "filter", example = "sort_name:distance|sort_rule:1", description = "условия фильтрации поиска. Когда scope равно 2, можно установить filter для сортировки"),
@RequestParam(fieldName = "coord_type", defaultValue = "3", example = "1、2、3(по умолчанию)、4", description = "тип координат, 1 (wgs84ll, т.е. GPS широта и долгота), 2 (gcj02ll, т. е. координаты широты и долготы национальной геодезической системы), 3 (bd09ll, т. е. широта и долгота координат Baidu), 4 (bd09mc, т. е. метрические координаты Baidu)"),
@RequestParam(fieldName = "ret_coordtype", example = "gcj02ll", description = "необязательный параметр, после добавления POI возвращает координаты национальной геодезической системы"),
@RequestParam(fieldName = "page_size", defaultValue = "10", example = "10", description = "количество записей, возвращаемых за один раз, по умолчанию 10 записей, максимум 20 записей"),
@RequestParam(fieldName = "page_num", defaultValue = "0", example = "0、1、2", description = "номер страницы, по умолчанию равен 0, 0 представляет первую страницу, 1 представляет вторую страницу и так далее"),
@RequestParam(fieldName = "ak", required = true, description = "ключ доступа разработчика, обязательный атрибут. До версии v2 этот атрибут назывался key"),
@RequestParam(fieldName = "sn", description = "подпись полномочий разработчика"),
@RequestParam(fieldName = "timestamp", description = "после установки sn это значение должно быть заполнено")
},
handlers = {BuildSnHandler.class} // Добавить обработчик построения URL-адреса sn (обработчики по умолчанию автоматически добавляются)
)
<T> T searchRegionByMap(String path, Map<String, String> map, Class<T> outputClass);
}
Properties способ:
# В файле application.yml добавьте атрибут http-helper, чтобы можно было внедрить объект с помощью @Autowired private HttpHelper httpHelper;
http-helper:
client:
client-type: web_client
enable-cookie: true
follow-redirects: true
enable-ssl: true
private-client: true
thread-number: 4
timeout: 3000
request:
charset: utf-8
content-type: empty
default-headers:
- name: Accept
value: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
method:
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )