{"id":329217,"date":"2022-02-07T15:01:31","date_gmt":"2022-02-07T15:01:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=329217"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2022-02-07T15:01:31","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=329217","title":{"rendered":"<span>Veslo \u2014 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 Retrofit \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (Java)<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0438 \u0434\u043b\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e HTTP \u043a\u043b\u0438\u0435\u043d\u0442\u0430 <a href=\"https:\/\/square.github.io\/retrofit\/\" rel=\"nofollow noopener noreferrer\">retrofit<\/a> \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f API. \u0421\u043e\u0437\u0434\u0430\u043d \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 API \u0442\u0435\u0441\u0442\u043e\u0432. \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u044f\u0433\u043a\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (softly assert) \u0438 \u0435\u0449\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u044f\u043a\u0438\u0445 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/ol\/lf\/aw\/ollfawiswjqiyiznfkmiyylu3rq.gif\"\/><\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u0435\u0441\u043b\u043e?<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412\u0435\u0441\u043b\u043e \u2014 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u0441\u043f\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u0438\u0435 (\u0434\u0432\u0438\u0436\u0438\u0442\u0435\u043b\u044c) \u0432 \u0432\u0438\u0434\u0435 \u0443\u0437\u043a\u043e\u0439 \u043b\u043e\u043f\u0430\u0442\u044b \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0441\u0443\u0434\u043e\u0432 (\u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432\u043e\u0435\u043d\u043d\u044b\u0445 <sup><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%93%D0%B0%D0%BB%D0%B5%D1%80%D0%B0\" rel=\"nofollow noopener noreferrer\">\u0433\u0430\u043b\u0435\u0440\u0430<\/a><\/sup>) \u0432 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0433\u0440\u0435\u0431\u043b\u0438 (\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443 \u0440\u044b\u0447\u0430\u0433\u0430).<\/p>\n<\/div><\/div>\n<p>  <a name=\"anchor_TOC\"><\/a>  <\/p>\n<h2 id=\"soderzhanie\">\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<ul>\n<li><a href=\"#anchor_Prerequisites\">\u041f\u0440\u0435\u0434\u043f\u043e\u0441\u044b\u043b\u043a\u0438<\/a><\/li>\n<li><a href=\"#anchor_Modules\">\u041c\u043e\u0434\u0443\u043b\u0438<\/a><\/li>\n<li><a href=\"#anchor_Requests\">\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_ObjectRequestBody\">Object \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/a><\/li>\n<li><a href=\"#anchor_ReflectQueryMap\">\u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (ReflectQueryMap)<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_QueryParameterNullValueRule\">\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 &#8216;null&#8217; (QueryParameterNullValueRule)<\/a><\/li>\n<li><a href=\"#anchor_QueryParameterCaseRule\">\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 (QueryParameterCaseRule)<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#anchor_Responses\">\u041e\u0442\u0432\u0435\u0442\u044b \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_SoftlyAsserter\">Softly Asserter<\/a><\/li>\n<li><a href=\"#anchor_ResponseAsserter\">Response Asserter<\/a><\/li>\n<li><a href=\"#anchor_HeaderAsserter\">Header Asserter<\/a><\/li>\n<li><a href=\"#anchor_BodyAsserter\">Body Asserter<\/a><\/li>\n<li><a href=\"#anchor_CustomResponseAssertion\">\u041a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#anchor_Models\">\u041c\u043e\u0434\u0435\u043b\u0438<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_RawBody\">RawBody<\/a><\/li>\n<li><a href=\"#anchor_ResourceFile\">ResourceFile<\/a><\/li>\n<li><a href=\"#anchor_Jackson2Model\">Jackson2 \u043c\u043e\u0434\u0435\u043b\u0438<\/a><\/li>\n<li><a href=\"#anchor_BeanValidationModel\">Jakarta Bean Validation<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#anchor_Client\">\u041a\u043b\u0438\u0435\u043d\u0442<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_CompositeInterceptor\">\u0421\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a (CompositeInterceptor)<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#anchor_Converters\">\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b<\/a><\/li>\n<li><a href=\"#anchor_Usefulness\">\u041f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u0438<\/a><br \/> \n<ul>\n<li><a href=\"#anchor_UsefulnessLogging\">\u041b\u043e\u0433-\u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430<\/a><\/li>\n<li><a href=\"#anchor_UsefulnessLiveTemplates\">\u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432<\/a><\/li>\n<li><a href=\"#anchor_UsefulnessPlugins\">\u041f\u043b\u0430\u0433\u0438\u043d\u044b IntelliJ IDEA<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#anchor_Finally\">\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/a><\/li>\n<\/ul>\n<p>  <a name=\"anchor_Prerequisites\"><\/a>  <\/p>\n<h2 id=\"predposylki\">\u041f\u0440\u0435\u0434\u043f\u043e\u0441\u044b\u043b\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u0430\u043d\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u044f \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0441 \u0446\u0435\u043b\u044c\u044e \u0430\u043a\u043a\u0443\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c API. \u041d\u043e \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043f\u0443\u0442\u0438 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f, \u0447\u0442\u043e \u043f\u043e\u0432\u043b\u0438\u044f\u043b\u043e \u0438 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0438 \u043d\u0430 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c\u0438, \u043d\u043e \u0432\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043e \u0441\u0442\u0440\u043e\u0433\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430\u043c\u0438 \u0432 \u0443\u0449\u0435\u0440\u0431 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u043c \u043a\u0430\u043d\u043e\u043d\u0430\u043c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0440\u043e\u0433\u0430 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f (\u0446\u0435\u043b\u0438\u043b\u0441\u044f \u0432 \u0434\u0436\u0443\u043d\u043e\u0432).<\/li>\n<li>\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c\/\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\/\u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e;<\/li>\n<li>\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\/\u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u0435\u043b\u043e\u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f\u043c\u0438;<\/li>\n<li>\u0441\u0430\u043c\u044b\u0439 \u043b\u0443\u0447\u0448\u0438\u0439 \u0442\u0435\u0441\u0442 \u2014 \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439;<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043d\u0435 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u0444\u0438\u0447\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438. \u0415\u0441\u043b\u0438 \u0432\u044b \u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u0447\u0442\u0435\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u0438\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0442\u043e \u043c\u0438\u043b\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0448\u0443 \u0432 <a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo\" rel=\"nofollow noopener noreferrer\">\u0440\u0435\u043f\u0443<\/a>. \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 <a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo#build-project-and-run-example-tests\" rel=\"nofollow noopener noreferrer\">\u043f\u043e\u0433\u043e\u043d\u044f\u0442\u044c<\/a> \u0442\u0435\u0441\u0442\u044b \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>example<\/code> (java 8+).<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">public static class ExampleTests {    public interface ExampleClient {     @POST(\"\/api\/example\")     DualResponse&lt;Pet, Err> get(@Query(\"id\") String id);   }    private static final ExampleClient CLIENT = buildClient(ExampleClient.class);    \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u0430 \u0441 \u0432\u044b\u043d\u043e\u0441\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434   public void test1639328754880() {     final Pet expected = new Pet().name(\"example\");     CLIENT.get(\"id_1\").assertSucResponse(Asserter::assertGetPet, expected);   }    \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u0430 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0442\u0435\u0441\u0442\u0435   public void test1639328754881() {     final Pet expected = new Pet().name(\"example\");     \/\/ \u041e\u0442\u0432\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 softly asserts      \/\/ \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u0438 \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430.      CLIENT.get(\"id_1\").assertResponse(respAsserter -> respAsserter         .assertHttpStatusCodeIs(200)         .assertHttpStatusMessageIs(\"OK\")         .assertHeaders(headersAsserter -> headersAsserter             .contentTypeIs(\"application\/json; charset=utf-8\")             .assertHeaderIsPresent(\"X-Request-Id\")             .accessControlAllowOriginIs(\"*\"))         .assertSucBody((asserter, actual) -> {             asserter.softly(actual::assertConsistency);             asserter.softly(() -> is(\"Pet.name\", actual.name, expected.name));         }));   } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u043e \u043c\u043e\u0434\u0443\u043b\u044c &#8216;example&#8217;<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 <code>example<\/code> \u043c\u043e\u0434\u0443\u043b\u0435 \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 allure \u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u0430 \u0432 <strong>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b<\/strong>. \u0421\u0442\u043e\u0438\u0442 \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u0431\u041e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0430\u0434\u0430\u044e\u0442 \u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438. \u041f\u043e \u0441\u0443\u0442\u0438, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c API \u0442\u0435\u0441\u0442\u044b, \u0442\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u044f\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>example<\/code>, \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c <code>pom.xml<\/code> (groupId, artifactId, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438), \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c API \u043a\u043b\u0438\u0435\u043d\u0442, \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e \u043e\u0431\u0440\u0430\u0437\u0443 \u0438 \u043f\u043e\u0434\u043e\u0431\u0438\u044e \u0441 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438, \u0438 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b.<\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Modules\"><\/a>  <\/p>\n<h2 id=\"moduli\">\u041c\u043e\u0434\u0443\u043b\u0438<\/h2>\n<p>  <\/p>\n<ul>\n<li><strong>all<\/strong> \u2014 \u0432\u0441\u0451 \u0438 \u0441\u0440\u0430\u0437\u0443 (\u0435\u0441\u043b\u0438 \u0432\u0430\u0441 \u043d\u0435 \u0441\u043c\u0443\u0449\u0430\u044e\u0442 \u043b\u0438\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435);<\/li>\n<li><strong>jackson<\/strong> \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 <a href=\"https:\/\/github.com\/FasterXML\/jackson\" rel=\"nofollow noopener noreferrer\">Jackson2<\/a> \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438;<\/li>\n<li><strong>gson<\/strong> \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 <a href=\"https:\/\/github.com\/google\/gson\" rel=\"nofollow noopener noreferrer\">Gson<\/a> \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438;<\/li>\n<li><strong>allure<\/strong> \u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u0432 API \u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\/\u043e\u0442\u0432\u0435\u0442\u0430;<\/li>\n<li><strong>bean<\/strong> \u2014 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 JSR 303 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 (jakarta bean validator);<\/li>\n<li><strong>core<\/strong> \u2014 \u044f\u0434\u0440\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438 <code>all<\/code>, <code>jackson<\/code>, <code>gson<\/code>, <code>allure<\/code>;<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3a2\/0a8\/374\/3a20a83745b0d4d1e26aafbb3f8c9a2f.svg\"\/><\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.touchbit.retrofit.veslo&lt;\/groupId>     &lt;artifactId>all&lt;\/artifactId>     &lt;version>${veslo.version}&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Requests\"><\/a>  <\/p>\n<h2 id=\"zaprosy-k-serveru\">\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443<\/h2>\n<p>  <a name=\"anchor_ObjectRequestBody\"><\/a>  <\/p>\n<h3 id=\"object-v-kachestve-tela-zaprosa\"><code>Object<\/code> \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h3>\n<p>  <\/p>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Object<\/code> \u0442\u0438\u043f \u0432 <code>@Body<\/code> \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430 <code>ExtensionConverterFactory<\/code>. \u0414\u043b\u044f json \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0432\u0430\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@Headers<\/code> \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 <code>Content-Type<\/code>. \u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u0442\u0435\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <a href=\"#anchor_Converters\">\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface PetApi {    \/** @param pet - {@link Pet} model (required) *\/   @POST(\"\/v2\/pet\")   @Headers({\"Content-Type: application\/json\"})   @Description(\"Add a new pet to the store\")   AResponse&lt;Pet, Err> addPet(@Body Object pet);   \/\/                               ^^^^^^ }<\/code><\/pre>\n<p>  <\/p>\n<p><code>Object<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0435\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043b\u044e\u0431\u0443\u044e \u0435\u0440\u0435\u0441\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class AddPetTests extends BasePetTest {    @Test   public void test1640455066880() {     \/\/ body -> {\"name\":\"fooBar\"}     PET_API.addPet(new Pet().name(\"fooBar\"));      \/\/ body (json string) -> \"fooBar\"     PET_API.addPet(\"fooBar\");      \/\/ body (string) -> fooBar     PET_API.addPet(new RawBody(\"fooBar\"));      \/\/ body -> true     PET_API.addPet(true);      \/\/ body -> &lt;\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442>     PET_API.addPet(ExtensionConverter.NULL_BODY_VALUE);      \/\/ body -> &lt;\u0438\u0437 \u0444\u0430\u0439\u043b\u0430>     final File file = new File(\"src\/test\/java\/transport\/data\/PetPositive.json\");     PET_API.addPet(file);      \/\/ body -> &lt;\u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430>     final ResourceFile resourceFile = new ResourceFile(\"PetPositive.json\");     PET_API.addPet(resourceFile);    } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_ReflectQueryMap\"><\/a>  <\/p>\n<h3 id=\"formirovanie-parametrov-zaprosa-reflectquerymap\">\u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (ReflectQueryMap)<\/h3>\n<p>  <\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 <code>@QueryMap<\/code> \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0442 ReflectQueryMap, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0430\u0440\u044b \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <strong>\u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u0430<\/strong>. \u042d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 <code>Map<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e <code>ReflectQueryMap<\/code>, \u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0439\u0442\u0438 \u043a\u0440\u043e\u0432\u044c \u0438\u0437 \u0433\u043b\u0430\u0437, \u043d\u043e \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 retrofit \u043d\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 API \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>@QueryMap<\/code>. \u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 <code>QueryMap<\/code> \u0441 fluent \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>lombok<\/code> \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><strong>LoginUserQueryMap<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@Getter @Setter @Accessors(chain = true, fluent = true) public class LoginUserQueryMap extends ReflectQueryMap {    private Object username;   private Object password;    \/\/ \u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430   static {     new LoginUserQueryMap().username(\"test\").password(\"abc123\");        } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface UserApi {    @GET(\"\/v2\/user\/login\")   @Description(\"Logs user into the system\")   AResponse&lt;Suc, Err> login(@QueryMap() LoginUserQueryMap queryMap);   \/\/                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   \/\/                        \/v2\/user\/login?password=abc123&amp;username=test }<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 QueryMap<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435 \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 QueryMap \u043f\u043e Swagger \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<br \/>  \u041f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0443 \u0440\u0443\u0447\u043a\u0430\u043c\u0438 \u043d\u0435\u043c\u043d\u043e\u0436\u043a\u043e \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u043e.<br \/>  \u0410 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>Map<\/code> \u0432 \u0442\u0435\u0441\u0442\u0435 \u044f \u0434\u0430\u0436\u0435 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class GeneratedQueryMap extends HashMap&lt;String, Object> {    private static final String USERNAME = \"username\";   private static final String PASSWORD = \"password\";    public GeneratedQueryMap(HttpUrl httpUrl) {     if (httpUrl == null) {       throw new NullPointerException(\"HttpUrl cannot be null\");     }     username(httpUrl.queryParameter(USERNAME));     password(httpUrl.queryParameter(PASSWORD));   }    public GeneratedQueryMap username(Object username) {     put(USERNAME, EncodingUtils.encode(username));     return this;   }    public GeneratedQueryMap password(Object password) {     put(PASSWORD, EncodingUtils.encode(password));     return this;   } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_QueryParameterNullValueRule\"><\/a>  <\/p>\n<h4 id=\"reflectquerymap---upravlenie-pravilami-obrabotki-null-znacheniy\">ReflectQueryMap \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 null \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/h4>\n<p>  <\/p>\n<p><code>ReflectQueryMap<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>null<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>  <\/p>\n<p><strong>QueryParameterNullValueRule<\/strong><\/p>\n<p>  <\/p>\n<ul>\n<li><code>RULE_IGNORE<\/code> \u2014 \u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>null<\/code> (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)<\/li>\n<li><code>RULE_NULL_MARKER<\/code> \u2014 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>null<\/code> \u043d\u0430 <code>null marker<\/code> -> <code>\/api\/call?foo=%00<\/code><\/li>\n<li><code>RULE_EMPTY_STRING<\/code> \u2014 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>null<\/code> \u043d\u0430 \u043f\u0443\u0441\u0442\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 -> <code>\/api\/call?foo=<\/code><\/li>\n<li><code>RULE_NULL_STRING<\/code> \u2014 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>null<\/code> \u043d\u0430 <code>null<\/code> \u0441\u0442\u0440\u043e\u043a\u0443 -> <code>\/api\/call?foo=null<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"java\">\/\/ \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u0430 @QueryMapParameterRules(nullRule = RULE_NULL_MARKER) public class LoginUserQueryMap extends ReflectQueryMap {    \/\/ \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   @QueryMapParameter(nullRule = RULE_EMPTY_STRING)   private Object password; }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_QueryParameterCaseRule\"><\/a>  <\/p>\n<h4 id=\"reflectquerymap---upravlenie-pravilami-naimenovaniya-parametrov\">ReflectQueryMap \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<\/h4>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043a\u043b\u0430\u0441\u0441\u0430, \u043d\u043e \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0438\u043c\u0451\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u044f\u0432\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430.<\/p>\n<p>  <\/p>\n<p><strong>QueryParameterCaseRule<\/strong><\/p>\n<p>  <\/p>\n<ul>\n<li>CAMEL_CASE \u2014 camelCase (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e)<\/li>\n<li>KEBAB_CASE \u2014 kebab-case<\/li>\n<li>SNAKE_CASE \u2014 snake_case<\/li>\n<li>DOT_CASE \u2014 dot.case<\/li>\n<li>PASCAL_CASE \u2014 PascalCase<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"java\">\/\/ \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d snake_case @QueryMapParameterRules(caseRule = SNAKE_CASE) public class LoginUserQueryMap extends ReflectQueryMap {    \/\/ \u0438\u043c\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439   @QueryMapParameter(name = \"userName\")   private Object username; }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Responses\"><\/a>  <\/p>\n<h2 id=\"otvety-ot-servera\">\u041e\u0442\u0432\u0435\u0442\u044b \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/h2>\n<p>  <\/p>\n<p>\u0422\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0432 \u0442\u0440\u0451\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445: <\/p>\n<p>  <\/p>\n<p><code>DualResponse&lt;Pet, Err><\/code>, \u0433\u0434\u0435 <\/p>\n<p>  <\/p>\n<ul>\n<li><code>Pet<\/code> \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430;<\/li>\n<li><code>Err<\/code> \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438;<\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>DualResponse<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>UniversalCallAdapterFactory<\/code> (\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;<a href=\"#anchor_ClientMethodDescription\">\u041a\u043b\u0438\u0435\u043d\u0442<\/a>&#171;). <\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface DualResponseClient {    @GET(\"\/api\/pet\")   @EndpointInfo(\"Get pet by ID\")   DualResponse&lt;Pet, Err> getPet(String id); }<\/code><\/pre>\n<p>  <\/p>\n<p><code>AResponse&lt;Pet, Err><\/code> \u0422\u043e \u0436\u0435, \u0447\u0442\u043e \u0438 <code>DualResponse<\/code>, \u0442\u043e\u043b\u044c\u043a\u043e \u0441 allure \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439.<br \/>  <code>AResponse<\/code> \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>AllureCallAdapterFactory<\/code> (\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;<a href=\"#anchor_ClientMethodDescription\">\u041a\u043b\u0438\u0435\u043d\u0442<\/a>&#171;). <\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface AResponseClient {    @GET(\"\/api\/pet\")   @EndpointInfo(\"Get pet by ID\")   AResponse&lt;Pet, Err> getPet(String id); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 &#171;\u043f\u0440\u043e\u0441\u0442\u044b\u0435&#187; \u0442\u0438\u043f\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043e\u043a (status code 400+) \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u0430\u043f\u0438\u0442\u044c \u0442\u0435\u043b\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0438 \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f <code>null<\/code>. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c API \u0432\u044b\u0437\u043e\u0432 <code>\/api\/live<\/code> (health check) \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439 <code>OK\/ERROR<\/code> -> <code>String live();<\/code><\/li>\n<li>\u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 <code>true\/false<\/code> -> <code>Boolean live();<\/code><\/li>\n<li>JSON \u043e\u0431\u044a\u0435\u043a\u0442 -> <code>LiveProbeModel live()<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"java\">public interface Client {    @GET(\"\/api\/live\")   @EndpointInfo(\"Service liveness probe\")   LiveProbeModel live(); }<\/code><\/pre>\n<p>  <\/p>\n<p><code>DualResponse<\/code> \u0438 <code>AResponse<\/code> \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u044b \u043e\u0442 <code>BaseDualResponse<\/code> \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>assertResponse()<\/code> \u2014 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430;<\/li>\n<li><code>assertSucResponse()<\/code> \u2014 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430;<\/li>\n<li><code>assertErrResponse()<\/code> \u2014 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430;<\/li>\n<li><code>getErrDTO()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 (nullable);<\/li>\n<li><code>getSucDTO()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044c \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 (nullable);<\/li>\n<li><code>getEndpointInfo()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 API;<\/li>\n<li><code>getResponse()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u044b\u0440\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441\u043e\u043c <code>okhttp3.Response<\/code> \u0441 \u0447\u0438\u0442\u0430\u0435\u043c\u044b\u043c \u0442\u0435\u043b\u043e\u043c;<\/li>\n<li><code>getCallAnnotations()<\/code> \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0432\u044b\u0437\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e API \u043c\u0435\u0442\u043e\u0434\u0430:<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0432\u0443\u043c\u044f \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435, \u043a\u043b\u0430\u0441\u0441\u044b <code>DualResponse<\/code> \u0438 <code>AResponse<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043c\u044f\u0433\u043a\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0441 \u0430\u0432\u0442\u043e\u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435\u043c (Closeable). \u0414\u0430\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 consumer-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f <code>IResponseAsserter<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ResponseAsserter<\/code> \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432 <code>DualResponse<\/code> \u0438 <code>AResponse<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0422\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u0430 \u0434\u043b\u044f <code>assertResponse<\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class ExampleTests {    public void example() {     CLIENT.updatePet(new Pet().id(100L).name(\"example\"))         .assertResponse(asserter -> asserter                 .assertHttpStatusCodeIs(204)                 .assertHttpStatusMessageIs(\"No Content\"));   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0441 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u0448\u0438\u0431\u043a\u0430\u043c\u0438. <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">veslo.BriefAssertionError: Collected the following errors:  HTTP status code Expected: is  204   Actual: was 200  HTTP status message Expected: is  No Content   Actual: was \u041e\u041a<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b <code>assertSucResponse<\/code> \u0438 <code>assertErrResponse<\/code> \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u0438 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 <code>IResponseAsserter<\/code> \u0438 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0434\u043b\u044f \u0432\u044b\u043d\u043e\u0441\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b. \u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 <code>example<\/code> \u043c\u043e\u0434\u0443\u043b\u044f:<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/habrastorage.org\/webt\/xg\/xh\/6r\/xgxh6rt8ahtwtcbaeiiktuojuwg.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/xg\/xh\/6r\/xgxh6rt8ahtwtcbaeiiktuojuwg.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_SoftlyAsserter\"><\/a>  <\/p>\n<h4 id=\"softly-asserter\">Softly Asserter<\/h4>\n<p>  <\/p>\n<p>\u041c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043c\u044f\u0433\u043a\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>SoftlyAsserter<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>AutoCloseable<\/code>.<br \/>  \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>try-with-resources<\/code> \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430 <code>close()<\/code>. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>close()<\/code> \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 &#171;\u0441\u043a\u043b\u0435\u0438\u0432\u0430\u043d\u0438\u0435&#187; \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438 \u0431\u0440\u043e\u0441\u043e\u043a \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e <code>AssertionError<\/code>. <\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class Example {    @Test   public void test1643976548733() {     try (SoftlyAsserter asserter = SoftlyAsserter.get()) {       \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435       asserter.softly(() -> { assert 1 == 0; });       \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435       asserter.softly(() -> { assert 1 != 1; });      } \/\/ \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f SoftlyAsserter.close()   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>softly()<\/code> \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>ThrowableRunnable<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a. <\/p>\n<p>  <\/p>\n<p>\u0422.\u0435. <code>softly(() -> { \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0439 \u0442\u0443\u0442 })<\/code> \u0438 \u0431\u0440\u043e\u0441\u0438\u0432\u0448\u0438\u0439 <code>Throwable<\/code> \u043d\u0435 \u043f\u0440\u0435\u0440\u0432\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. <code>SoftlyAsserter<\/code> \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0431\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0439 <code>Throwable<\/code> \u0434\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>try-with-resources<\/code> \u0431\u043b\u043e\u043a\u0430 \u0438\u043b\u0438 \u043f\u043e\u043a\u0430 <strong>\u044f\u0432\u043d\u043e<\/strong> \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434 <code>.close()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441 <code>hamcrest<\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class Example {    @Test   public void test1643977714496() {     try (SoftlyAsserter asserter = SoftlyAsserter.get()) {       asserter.softly(() -> assertThat(\"Body\", \"act\", is(\"exp\")));     }   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 <code>SoftlyAsserter<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0441 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c <code>try-with-resources<\/code> \u0431\u043b\u043e\u043a\u043e\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class Example {    @Test   public void test1643978036764() {     softlyAsserter(asserter -> asserter         .softly(() -> assertThat(\"Body\", \"act\", is(\"exp\")))         .softly(() -> assertThat(\"Body\", 1, is(2))));   } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_ResponseAsserter\"><\/a>  <\/p>\n<h4 id=\"response-asserter\">Response Asserter<\/h4>\n<p>  <\/p>\n<p>\u041b\u044e\u0431\u044b\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <code>BaseDualResponse<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>IResponseAsserter<\/code>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ResponseAsserter<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c\u0438 \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 (\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"#anchor_CustomResponseAssertion\">&#171;\u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a&#187;<\/a>).<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u044b\u0447\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438<\/strong><\/p>\n<p>  <\/p>\n<ul>\n<li><code>assertHttpStatusCodeIs(int)<\/code> \u2014 \u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 <code>HTTP status code<\/code><\/li>\n<li><code>assertHttpStatusMessageIs(String)<\/code> \u2014 \u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 <code>HTTP status message<\/code><\/li>\n<li><code>assertErrBodyIsNull()<\/code> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0438 \u0442\u0435\u043b\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/li>\n<li><code>assertErrBodyNotNull()<\/code> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u0438 \u0442\u0435\u043b\u043e \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/li>\n<li><code>assertIsErrHttpStatusCode()<\/code> \u2014 \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u043e\u0434 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 300&#8230;599<\/li>\n<li><code>assertSucBodyIsNull()<\/code> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438 \u0442\u0435\u043b\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/li>\n<li><code>assertSucBodyNotNull()<\/code> \u2014 \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438 \u0442\u0435\u043b\u043e \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/li>\n<li><code>assertIsSucHttpStatusCode()<\/code> \u2014 \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u043e\u0434 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 200&#8230;299<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438<\/strong> <\/p>\n<p>  <\/p>\n<ul>\n<li><code>assertSucBody()<\/code> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c (\u043e\u0431\u044a\u0435\u043a\u0442) \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430;<\/li>\n<li><code>assertErrBody()<\/code> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044c (\u043e\u0431\u044a\u0435\u043a\u0442) \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438;<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b, \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f <code>assertSucBody()<\/code>.<br \/>  \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0434\u043d\u0430 \u0438 \u0442\u0430 \u0436\u0435 \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445: <\/p>\n<p>  <\/p>\n<ul>\n<li><code>Lambda:<\/code> \u043b\u044f\u043c\u0431\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043c\u0435\u0442\u043e\u0434\u0430; <\/li>\n<li><code>Reference:<\/code> \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u044f\u043c\u0431\u0434\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f; <\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u0438\u043b &#171;\u043d\u0430 \u0432\u0441\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u0436\u0438\u0437\u043d\u0438&#187;. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u044f \u043f\u043e\u043c\u0435\u0442\u0438\u043b \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e. \u0422\u0430\u043a \u0436\u0435 \u0432\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 javadoc \u043a\u043b\u0430\u0441\u0441\u0430 <code>ResponseAsserter<\/code> \u0438 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>ExampleApiClientAssertions<\/code> \u0432 \u044f\u0434\u0440\u0435 (\u0445\u043e\u0442\u044c \u044d\u0442\u043e \u0438 \u043d\u0435 \u043a\u0430\u043d\u043e\u043d\u0438\u0447\u043d\u043e). <\/p>\n<p>  <\/p>\n<p><strong><code>assertHeaders(Consumer&lt;IHeadersAsserter>)<\/code><\/strong><br \/>  \u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b <a href=\"#anchor_HeaderAsserter\">Header Asserter<\/a>.<\/p>\n<p>  <\/p>\n<p><strong><code>assertSucBody(Consumer&lt;SUC_DTO>)<\/code><\/strong><br \/>  \u041c\u0435\u0442\u043e\u0434 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u0435\u0435 \u043c\u0435\u0442\u043e\u0434\u044b <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<br \/>  Lambda: <code>.assertSucBody(pet -> pet.assertConsistency())<\/code><br \/>  Reference: <code>.assertSucBody(Pet::assertConsistency)<\/code> <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u0432\u0435\u0440\u043a\u0438<br \/>  Lambda: <code>.assertSucBody(pet -> pet.match(expected))<\/code><sup>*<\/sup><br \/>  Reference: \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 <\/p>\n<p>  <\/p>\n<p><strong><code>assertSucBody(BiConsumer&lt;SUC_DTO, SUC_DTO>, SUC_DTO)<\/code><\/strong><br \/>  \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e actual \u0438 expected \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u0432\u0435\u0440\u043a\u0438.<br \/>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439<br \/>  Lambda: <code>.assertSucBody((act, exp) -> Asserts.assertPet(act, exp), expected)<\/code><br \/>  Reference: <code>.assertSucBody(Asserts::assertPet, expected)<\/code> <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0435\u0439<br \/>  Lambda: <code>.assertSucBody((pet, exp) -> pet.match(exp), expected)<\/code><br \/>  Reference: <code>.assertSucBody(Pet::match, expected)<\/code><sup>*<\/sup> <\/p>\n<p>  <\/p>\n<p><strong><code>assertSucBody(BiConsumer&lt;SoftlyAsserter, SUC_DTO>)<\/code><\/strong><br \/>  \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0441\u0441\u0435\u0440\u0442\u0435\u0440 \u0438 actual \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438.<br \/>  \u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0434\u0435\u043b\u0438<br \/>  Lambda: <code>.assertSucBody((sa, act) -> Asserts.assertPet(sa, act, expected))<\/code><br \/>  Reference: \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 <\/p>\n<p>  <\/p>\n<p><strong><code>assertSucBody(TripleConsumer&lt;SoftlyAsserter, SUC_DTO, SUC_DTO>, SUC_DTO)<\/code><\/strong><br \/>  \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0430\u0441\u0441\u0435\u0440\u0442\u0435\u0440, actual \u0438 expected \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<br \/>  Lambda: <code>.assertSucBody((sa, act, exp) -> Asserts.assertPet(sa, act, exp), expected)<\/code><br \/>  Reference: <code>.assertSucBody(Asserts::assertPet, expected)<\/code><sup>*<\/sup><\/p>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_HeaderAsserter\"><\/a>  <\/p>\n<h4 id=\"header-asserter\">Header Asserter<\/h4>\n<p>  <\/p>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>assertHeaderNotPresent(String headerName)<\/code><\/li>\n<li><code>assertHeaderIsPresent(String headerName)<\/code><\/li>\n<li><code>assertHeaderIs(String headerName, String expected)<\/code><\/li>\n<li><code>assertHeaderContains(String headerName, String expected)<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li>Access-Control-Allow-Origin<\/li>\n<li>Connection<\/li>\n<li>Content-Type<\/li>\n<li>Etag<\/li>\n<li>Keep-Alive<\/li>\n<li>Server<\/li>\n<li>Set-Cookie<\/li>\n<li>Content-Encoding<\/li>\n<li>Transfer-Encoding<\/li>\n<li>Vary<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public static class ExampleTests {     \/\/ \u044f\u0432\u043d\u043e \u0432 \u0442\u0435\u0441\u0442\u0435   public void test1639328754881() {     CLIENT.get().assertResponse(respAsserter -> respAsserter         .assertHeaders(headersAsserter -> headersAsserter             .contentTypeIs(\"application\/json; charset=utf-8\")             .assertHeaderIsPresent(\"X-Request-Id\")             .accessControlAllowOriginIs(\"*\")));   }    \/\/ \u0438\u043b\u0438 \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434   public void example1639330184783() {     CLIENT.get().assertResponse(respAsserter -> respAsserter             .assertHeaders(Asserts::assertHeaders));   }  }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_BodyAsserter\"><\/a>  <\/p>\n<h3 id=\"body-asserter\">Body Asserter<\/h3>\n<p>  <\/p>\n<p>\u042f \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u044d\u0442\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u0438 \u043b\u043e\u0433\u0438\u0447\u043d\u043e. \u041c\u044b\u0441\u043b\u044e \u0442\u0430\u043a: \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0432 \u043c\u043e\u0434\u0435\u043b\u0438 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>equals(Object)<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u0430, \u0442\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043d\u0435 \u0438\u043c\u0435\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>match(Model)<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f? \u041f\u043e-\u043c\u043e\u0435\u043c\u0443, \u0437\u0432\u0443\u0447\u0438\u0442 \u0437\u0434\u0440\u0430\u0432\u043e, \u0434\u0430 \u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441\u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class Category implements AssertableModel&lt;Category> {      private Long id = null;     private String name = null;      @Override     public Category match(Category expected) {         try (final SoftlyAsserter asserter = SoftlyAsserter.get()) {             asserter.softly(() -> assertThat(this.id()).as(\"category.id\").isNotNull().isPositive());             asserter.softly(() -> assertThat(this.name()).as(\"category.name\").isEqualTo(expected.name()));         }         return this;     }  }  public interface AssertableModel&lt;DTO> {    DTO match(DTO expected);  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0442\u0435\u043b\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>.assertSucBody(actual -> actual.match(expected))<\/code><\/li>\n<li><code>.assertSucBody(Category::match, expected)<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 <a href=\"#anchor_CustomResponseAssertion\">\u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a<\/a>, \u0442\u043e \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0441\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430, \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 CRUD (\u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043f\u043e\u0432\u043e\u0434 \u043f\u043b\u044e\u043d\u0443\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0443 \u0432 \u043b\u0438\u0446\u043e \u0437\u0430 \u0442\u0430\u043a\u0443\u044e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044e).<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a:<br \/>  <code>.assertSucResponse(Category::assertPOST, expected);<\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class Category implements AssertableModel&lt;Category> {    private Long id = null;   private String name = null;    @Override   public Category match(Category expected) {       \/\/ collapsed   }    public static void assertGET(ResponseAsserter&lt;Category, ?, HeadersAsserter> asserter,                                Category expected) {     asserter.assertHttpStatusCodeIs(200).assertSucBody(actual -> actual.match(expected));   }    public static void assertPOST(ResponseAsserter&lt;Category, ?, HeadersAsserter> asserter,                                  Category expected) {     asserter.assertHttpStatusCodeIs(200).assertSucBody(actual -> actual.match(expected));   }    public static void assertPATCH(ResponseAsserter&lt;Category, ?, HeadersAsserter> asserter) {     asserter.assertHttpStatusCodeIs(204).assertSucBodyIsNull().assertErrBodyIsNull();   }  }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_CustomResponseAssertion\"><\/a>  <\/p>\n<h3 id=\"kastomizaciya-vstroennyh-proverok\">\u041a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a<\/h3>\n<p>  <\/p>\n<p><code>DualResponse<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <code>CustomResponse<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d \u043e\u0442 <code>BaseDualResponse<\/code> \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>public IResponseAsserter getResponseAsserter();<\/code> \u0433\u0434\u0435 <code>IResponseAsserter<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0441\u0441\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041b\u0443\u0447\u0448\u0435 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 <code>ResponseAsserter<\/code>.<\/li>\n<li><code>public IHeadersAsserter getHeadersAsserter();<\/code> \u0433\u0434\u0435 <code>IHeadersAsserter<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0441\u0441\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432. \u041b\u0443\u0447\u0448\u0435 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 <code>HeadersAsserter<\/code>.<\/li>\n<\/ul>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0414\u043b\u044f \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e\u0441\u0442\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p><a href=\"https:\/\/habrastorage.org\/webt\/8v\/dy\/-k\/8vdy-kp5hkjo3rcohz13-0ppegu.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/8v\/dy\/-k\/8vdy-kp5hkjo3rcohz13-0ppegu.png\"\/><\/a><\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 <a href=\"#anchor_Client\">\u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/a> retrofit, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 <code>IDualResponse<\/code>.<br \/>  \u041c\u0435\u0442\u043e\u0434 <code>.addCallAdapterFactory(CallAdapter.Factory)<\/code>: <\/p>\n<p>  <\/p>\n<ul>\n<li><code>new UniversalCallAdapterFactory(CustomResponse::new)<\/code> default<\/li>\n<li><code>new AllureCallAdapterFactory(CustomResponse::new)<\/code> allure<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432\u0430\u043c \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0443\u043b \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u0447\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e <code>IResponseAsserter<\/code>.<br \/>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>PetStoreAsserter<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public static class ExampleTests {     public void test1639328754881() {     Pet expected = Pet.generate();     CLIENT.addPet(expected);     CLIENT.getPet(expected.getId())         \/\/ \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 assertResponse(Consumer)         .assertResponse(asserter -> asserter.assertGetPet(expected))          \/\/ \u0438\u043b\u0438 c assertSucResponse(BiConsumer, SUC_DTO)         .assertResponse(PetStoreAsserter::assertGetPet, expected);   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0437\u0430\u043c\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u044b\u043d\u043e\u0441\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432 \u0430\u0441\u0441\u0435\u0440\u0442\u0435\u0440\u044b, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432 <code>CustomResponse<\/code>. <\/p>\n<p>  <\/p>\n<p>\u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440, \u0438\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c <code>ResponseAsserter<\/code>, \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u044f\u0433\u043a\u0438\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a (\u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0432\u0430\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u044b).<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public static class ExampleTests {     public void test1639328754881() {     Pet expected = Pet.generate();     CLIENT.addPet(expected);     CLIENT.getPet(expected.getId()).assertGetPet(expected);   } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Models\"><\/a>  <\/p>\n<h2 id=\"modeli\">\u041c\u043e\u0434\u0435\u043b\u0438<\/h2>\n<p>  <a name=\"anchor_RawBody\"><\/a>  <\/p>\n<h2 id=\"rawbody-model\">RawBody \u043c\u043e\u0434\u0435\u043b\u044c<\/h2>\n<p>  <\/p>\n<p><code>RawBody<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432. \u0425\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043b\u043e \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438.<br \/>  \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 &#171;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&#187; \u0432 \u043e\u0431\u0445\u043e\u0434 MIME \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432. \u0412 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043d\u0430\u0440\u0443\u0448\u0430\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0431\u0438\u0442\u044b\u0439 JSON. <\/p>\n<p>  <\/p>\n<p>\u041d\u0435 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u0435\u043d \u043a \u043e\u0442\u0432\u0435\u0442\u0430\u043c \u0431\u0435\u0437 \u0442\u0435\u043b\u0430 (HTTP status code 204\/205). \u0422.\u0435. \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432 \u043e\u0442\u0432\u0435\u0442\u0430\u0445 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <code>null<\/code> (\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430).<br \/>  \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438: <\/p>\n<p>  <\/p>\n<ul>\n<li><code>assertBodyIsNotNull()<\/code><\/li>\n<li><code>assertBodyIsNull()<\/code><\/li>\n<li><code>assertBodyIsNotEmpty()<\/code><\/li>\n<li><code>assertBodyIsEmpty()<\/code><\/li>\n<li><code>assertStringBodyContains(String... expectedStrings)<\/code><\/li>\n<li><code>assertStringBodyContainsIgnoreCase(String... expectedStrings)<\/code><\/li>\n<li><code>assertStringBodyIs(String expected)<\/code><\/li>\n<li><code>assertStringBodyIsIgnoreCase(String expected)<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_ResourceFile\"><\/a>  <\/p>\n<h2 id=\"resourcefile-model\">ResourceFile \u043c\u043e\u0434\u0435\u043b\u044c<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. <\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 API \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u043e\u043c\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043c\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438. <\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0438 \u0435\u0433\u043e \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u043a\u043e\u0440\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo\/issues\/4\" rel=\"nofollow noopener noreferrer\">\u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0430<\/a> \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 fluent API. <\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class AddPetTests extends BasePetTest {    @Test   public void test1640455066880() {     final ResourceFile resourceFile = new ResourceFile(\"PetPositive.json\");     PET_API.addPet(resourceFile);    } }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Jackson2Model\"><\/a>  <\/p>\n<h2 id=\"jackson2-modeli\">Jackson2 \u043c\u043e\u0434\u0435\u043b\u0438<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e <code>Jackson2<\/code> \u0432\u0435\u0440\u0441\u0438\u0438 <code>2.13.1<\/code>. <\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 Gson \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <code>Jackson2<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u043e\u043b\u044f, \u043d\u0435 \u0432\u044b\u0434\u0430\u0432\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0440\u0438 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438. <\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u044f <strong>\u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e<\/strong> \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Jackson2<\/code> \u0434\u043b\u044f \u0432\u0430\u0448\u0438\u0445 json\/yaml \u043c\u043e\u0434\u0435\u043b\u0435\u0439. <\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043b\u0438\u0448\u043d\u0438\u0445 \u043f\u043e\u043b\u0435\u0439 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>JacksonModelAdditionalProperties<\/code> \u0438 \u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. <\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f \u0438 \u043f\u0440\u0438\u0448\u0435\u043b \u043e\u0442\u0432\u0435\u0442 \u0441 \u043d\u043e\u0432\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438, \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u044d\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <code>assertNoAdditionalProperties()<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <strong>\u0432\u043c\u0435\u043d\u044f\u0435\u043c\u0443\u044e<\/strong> \u043e\u0448\u0438\u0431\u043a\u0443. <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">The presence of extra fields in the model: Pet Expected: no extra fields   Actual: {nickname=Puffy}<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class AddPetTests {      @Test     @DisplayName(\"Pet model complies with API contract\")     public void test1640455066880() {         PET_API.addPet(generatePet()).assertResponse(response -> response                 .assertHttpStatusCodeIs(200)                 .assertSucBody(Pet::assertNoAdditionalProperties));     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 <code>additionalProperties<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c &#171;\u0431\u0438\u0442\u044b\u0435&#187; \u0434\u0430\u043d\u043d\u044b\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u043c\u043e\u0434\u0435\u043b\u0438 <code>Pet<\/code> \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 <code>id<\/code> \u0441 \u0442\u0438\u043f\u043e\u043c <code>Long<\/code> \u0438 \u043c\u044b \u0445\u043e\u0434\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043a\u0430\u043a \u0441\u0435\u0431\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440, \u0435\u0441\u043b\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u0447\u0435\u043c <code>Long.MAX_VALUE<\/code> \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u043c\u0435\u0441\u0442\u043e <code>Long<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class AddPetTests {    @Test    public void test1640455066881() {     Pet pet = generatePet();     \/\/ id > Long.MAX_VALUE     pet.id(null).additionalProperty(\"id\", new BigInteger(Long.MAX_VALUE + \"000\"));     \/\/ id != Long     pet.id(null).additionalProperty(\"id\", \"fooBar\");     PET_API.addPet(pet);   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0442\u043e-\u0442\u043e \u0441\u043a\u0430\u0436\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e Gson \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0435 \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044f. \u041e\u0434\u043d\u0430\u043a\u043e <code>Jackson2<\/code> \u0442\u0430\u043a\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u0436\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e. \u0427\u0442\u043e\u0431 \u043d\u0435 \u0432\u0435\u0448\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@JsonProperty<\/code> \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043d\u0430\u0432\u0435\u0441\u0438\u0442\u044c \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@JsonAutoDetect(creatorVisibility = ANY, fieldVisibility = ANY)<\/code>. \u0422\u0430\u043a \u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@JsonNaming(PropertyNamingStrategies.LowerCamelCaseStrategy.class)<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c lombok \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434).<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">\/\/ \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0441 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 @Getter @Setter @ToString @EqualsAndHashCode(callSuper = true) @Accessors(chain = true, fluent = true) @JsonNaming(PropertyNamingStrategies.LowerCamelCaseStrategy.class) @JsonAutoDetect(creatorVisibility = ANY, fieldVisibility = ANY) public class Tag extends JacksonModelAdditionalProperties&lt;Tag> {      private Long id = null;     private String name = null;  }<\/code><\/pre>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_BeanValidationModel\"><\/a>  <\/p>\n<h2 id=\"jakarta-bean-validation\">Jakarta Bean Validation<\/h2>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u043e\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>BeanValidationModel<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 (\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438) JSR 303 (\u043c\u0435\u0442\u043e\u0434 <code>assertConsistency()<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u0441\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class AddPetTests {      @Test     @DisplayName(\"Pet model complies with API contract\")     public void test1640455066880() {         PET_API.addPet(generatePet()).assertResponse(response -> response                 .assertHttpStatusCodeIs(200)                 .assertSucBody(Pet::assertConsistency));     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0438 c JSR 303 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/habrastorage.org\/webt\/jo\/xd\/qe\/joxdqemtiw9qg2ubbgivup2nida.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/jo\/xd\/qe\/joxdqemtiw9qg2ubbgivup2nida.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Client\"><\/a>  <\/p>\n<h2 id=\"klient\">\u041a\u043b\u0438\u0435\u043d\u0442<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>TestClient<\/code> \u2014 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>core<\/code>. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e jackson, gson \u0438 allure.<\/li>\n<li><code>JacksonTestClient<\/code> \u2014 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>jackson<\/code>. \u0421\u0442\u0440\u043e\u0438\u0442 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441 jackson \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u043c. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e allure.<\/li>\n<li><code>GsonTestClient<\/code> \u2014 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>gson<\/code>. \u0421\u0442\u0440\u043e\u0438\u0442 \u043a\u043b\u0438\u0435\u043d\u0442 \u0441 gson \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u043c. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u043f\u0440\u043e allure.<\/li>\n<li><code>Veslo4Test<\/code> \u2014 \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>all<\/code>. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e <\/p>\n<p>  <\/p>\n<ul>\n<li>\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442\u0430\u043c, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 https -> http<\/li>\n<li>\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430<br \/> \n<ul>\n<li>\u043d\u0435\u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u0430<\/li>\n<li>\u0441\u0430\u043c\u043e\u043f\u043e\u0434\u043f\u0438\u0441\u043d\u043e\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442<\/li>\n<li>\u043f\u0440\u043e\u0442\u0443\u0445\u0448\u0438\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442<\/li>\n<\/ul>\n<\/li>\n<li><code>CompositeInterceptor<\/code> \u0441\/\u0431\u0435\u0437 allure \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0435\u0439 (<code>Veslo4Test<\/code>)<\/li>\n<\/ul>\n<p>  <a name=\"anchor_ClientMethodDescription\"><\/a>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f API \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u043d\u0443\u0442\u044c \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0435\u043d\u0443\u0436\u043d\u043e\u0435).<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class BaseTest {    protected static final PetApi PET_API = buildClient(PetApi.class);    private static &lt;C> C buildClient(final Class&lt;C> cliClass) {     return new Retrofit.Builder()         .client(new OkHttpClient.Builder()             .followRedirects(true)             .followSslRedirects(true)              .hostnameVerifier(TRUST_ALL_HOSTNAME)             .sslSocketFactory(TRUST_ALL_SSL_SOCKET_FACTORY, TRUST_ALL_CERTS_MANAGER)             .addNetworkInterceptor(new CompositeInterceptor())             .build())         .baseUrl(\"https:\/\/petstore.swagger.io\/\")         .addCallAdapterFactory(new AllureCallAdapterFactory())         \/\/ \u0438\u043b\u0438         .addCallAdapterFactory(new UniversalCallAdapterFactory())         .addConverterFactory(new JacksonConverterFactory())         \/\/ \u0438\u043b\u0438             .addConverterFactory(new GsonConverterFactory())         .build()         .create(cliClass);   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>#followRedirects()<\/code> \u2014 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043f\u043e \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c (301, 302&#8230;);<\/li>\n<li><code>#followSslRedirects()<\/code> \u2014 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 httpS &lt;-> http \u043f\u043e \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430\u043c;<\/li>\n<li><code>#hostnameVerifier()<\/code> \u2014 \u0435\u0441\u043b\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u0434\u043e\u043c\u0435\u043d \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u043e\u043c\u0435\u043d\u0443 \u0432 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0435 (\u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f);<\/li>\n<li><code>#sslSocketFactory()<\/code> \u2014 \u0432\u043c\u0435\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0432 \u0432 keystore (\u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f);<\/li>\n<li><code>#addNetworkInterceptor()<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0430 (\u0432\u0430\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434, \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442\u044b). <code>CompositeInterceptor<\/code> \u043e\u043f\u0438\u0441\u0430\u043d <a href=\"#anchor_CompositeInterceptor\">\u0442\u0443\u0442<\/a>;<\/li>\n<li><code>#addConverterFactory()<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u0430\u0431\u0440\u0438\u043a\u0443 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432;<br \/> \n<ul>\n<li><code>JacksonConverterFactory<\/code> \u0434\u043b\u044f Jackson \u043c\u043e\u0434\u0435\u043b\u0435\u0439 + \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0437 <code>ExtensionConverterFactory<\/code>;<\/li>\n<li><code>GsonConverterFactory<\/code> \u0434\u043b\u044f Gson \u043c\u043e\u0434\u0435\u043b\u0435\u0439 + \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0437 <code>ExtensionConverterFactory<\/code>;<\/li>\n<li><code>ExtensionConverterFactory<\/code> \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0445\/\u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0445 &#171;\u043f\u0440\u043e\u0441\u0442\u044b\u0445&#187; \u0442\u0438\u043f\u043e\u0432 (\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0430\u0437\u0434\u0435\u043b <a href=\"#anchor_Converters\">\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b<\/a>);<\/li>\n<\/ul>\n<\/li>\n<li><code>#addCallAdapterFactory()<\/code> \u2014 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 API \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u0442 <code>retrofit2.Call<\/code>;<br \/> \n<ul>\n<li><code>UniversalCallAdapterFactory<\/code> \u2014 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0434\u043b\u044f <code>DualResponse<\/code>;<\/li>\n<li><code>AllureCallAdapterFactory<\/code> \u2014 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0434\u043b\u044f <code>AResponse<\/code> \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 allure \u0448\u0430\u0433\u043e\u0432;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c allure, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 allure \u043c\u043e\u0434\u0443\u043b\u044c. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 <code>veslo.AResponse<\/code>. \u0422\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 okhttp \u043a\u043b\u0438\u0435\u043d\u0442 (<code>#addNetworkInterceptor()<\/code>) \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 <code>CompositeInterceptor<\/code> \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>AllureAction.INSTANCE<\/code> \u043a\u0430\u043a \u0432 <a href=\"#anchor_CompositeInterceptorExample\">\u043f\u0440\u0438\u043c\u0435\u0440\u0435<\/a>.<br \/>  \u041d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>io.qameta.allure.Description<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface AllureCallAdapterFactoryClient {     @GET(\"\/api\/example\")     @Description(\"Get pet\")     AResponse&lt;Pet, Err> get(); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c allure \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 <code>veslo.client.response.DualResponse<\/code>. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>veslo.client.EndpointInfo<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface UniversalCallAdapterFactoryClient {     @GET(\"\/api\/example\")     @EndpointInfo(\"Get pet\")     DualResponse&lt;Pet, Err> get(); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_CompositeInterceptor\"><\/a>  <\/p>\n<h2 id=\"setevoy-perehvatchik-compositeinterceptor\">\u0421\u0435\u0442\u0435\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a (CompositeInterceptor)<\/h2>\n<p>  <\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0439 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e <code>CompositeInterceptor<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 (\u0434\u0430\u043b\u0435\u0435 <code>Action<\/code>) \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u0447\u0442\u043e \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>retrofit<\/code>. \u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u0432\u044b \u0441\u0430\u043c\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0435 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 <code>Action<\/code> \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0417\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u041e\u0442\u0432\u0435\u0442\u0430. <\/p>\n<p>  <\/p>\n<p><code>Action<\/code> \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0440\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>RequestInterceptAction<\/code> \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>okhttp3.Chain<\/code> \u0438 <code>okhttp3.Request<\/code><\/li>\n<li><code>ResponseInterceptAction<\/code> \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>okhttp3.Response<\/code> \u0438 <code>java.lang.Throwable<\/code> (\u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438)<\/li>\n<li><code>InterceptAction<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f <code>RequestInterceptAction<\/code> \u0438 <code>ResponseInterceptAction<\/code><\/li>\n<\/ul>\n<p>  <a name=\"CompositeInterceptorExample\"><\/a>  <\/p>\n<pre><code class=\"java\">public class PetStoreInterceptor extends CompositeInterceptor {    public PetStoreInterceptor() {     super(LoggerFactory.getLogger(PetStoreInterceptor.class));      \/\/ \u0441\u0442\u0440\u043e\u0433\u0438\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     withRequestInterceptActionsChain(             AuthAction.INSTANCE,             CookieAction.INSTANCE,             LoggingAction.INSTANCE,              AllureAction.INSTANCE);      \/\/ \u0441\u0442\u0440\u043e\u0433\u0438\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430     withResponseInterceptActionsChain(             LoggingAction.INSTANCE,             AllureAction.INSTANCE,             CookieAction.INSTANCE);   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 actions:<\/p>\n<p>  <\/p>\n<p><code>CookieAction<\/code> \u2014 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 cookie-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c\u0438 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435;<br \/>  <code>LoggingAction<\/code> \u2014 \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\/\u043e\u0442\u0432\u0435\u0442 \u0438\u043b\u0438 \u0442\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0434\u0432\u0443\u043c\u044f <code>LogEvent<\/code>;<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">03:40:37.675 INFO  - API call: Logs user into the system 03:40:37.680 INFO  - REQUEST: GET https:\/\/petstore.swagger.io\/v2\/user\/login?password=abc123&amp;username=test Headers:   Host: petstore.swagger.io   Connection: Keep-Alive   Accept-Encoding: gzip   User-Agent: okhttp\/3.14.9 Body: (absent)  03:40:37.831 INFO  - RESPONSE: 200 https:\/\/petstore.swagger.io\/v2\/user\/login?password=abc123&amp;username=test Headers:   date: Tue, 01 Feb 2022 00:40:37 GMT   content-type: application\/json   access-control-allow-origin: *   access-control-allow-methods: GET, POST, DELETE, PUT   access-control-allow-headers: Content-Type, api_key, Authorization   x-expires-after: Tue Feb 01 01:40:37 UTC 2022   x-rate-limit: 5000   server: Jetty(9.2.9.v20150224)   Content-Length: -1 Body: (78-byte body)   {\"code\":200,\"type\":\"unknown\",\"message\":\"logged in user session:1643676037840\"} <\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><code>AllureAction<\/code> \u2014 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u0448\u0430\u0433 \u0432\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043e\u0442\u0432\u0435\u0442\u0430;<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 allure \u043e\u0442\u0447\u0435\u0442\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p><a href=\"https:\/\/habrastorage.org\/webt\/qg\/ub\/6t\/qgub6tsi7xxvdowijfe20u82ioc.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/qg\/ub\/6t\/qgub6tsi7xxvdowijfe20u82ioc.png\"\/><\/a><\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Converters\"><\/a>  <\/p>\n<h2 id=\"konvertery\">\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b<\/h2>\n<p>  <\/p>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>ExtensionConverterFactory<\/code> \u0438 \u0435\u0433\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430\u0445 <code>JacksonConverterFactory<\/code> \u0438 <code>GsonConverterFactory<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0432\u044b\u0431\u043e\u0440\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432.<br \/>  \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430: <code>@Converters<\/code>, <code>@RequestConverter<\/code>, <code>@ResponseConverter<\/code>;<\/li>\n<li>\u043f\u043e &#171;\u0441\u044b\u0440\u043e\u043c\u0443&#187; \u0442\u0438\u043f\u0443 \u0442\u0435\u043b\u0430 (<code>RawBody<\/code>, <code>File<\/code>, <code>ResourceFile<\/code>, <code>Byte[]<\/code>, <code>byte[]<\/code>);<\/li>\n<li>\u043f\u043e java \u043f\u0430\u043a\u0435\u0442\u0443 (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u0433\u043e\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435, \u043d\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 wildcard);<\/li>\n<li>\u043f\u043e <code>Content-Type<\/code> \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 (MIME);<\/li>\n<li>\u043f\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e\u043c\u0443\/\u0441\u0441\u044b\u043b\u043e\u0447\u043d\u043e\u043c\u0443 java \u0442\u0438\u043f\u0443 (<code>Byte<\/code>, <code>Character<\/code>, <code>Double<\/code>, <code>Float<\/code>, <code>Integer<\/code>, <code>Long<\/code>, <code>Short<\/code>, <code>String<\/code>);<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 java \u0442\u0438\u043f\u043e\u0432<\/p>\n<p>  <\/p>\n<ul>\n<li><code>AResponse&lt;String, String> addPet(@Body String body);<\/code><\/li>\n<li><code>AResponse&lt;RawBody, Err> addPet(@Body RawBody body);<\/code><\/li>\n<li><code>AResponse&lt;Byte[], Err> addPet(@Body byte[] body);<\/code><\/li>\n<li><code>AResponse&lt;File, Err> addPet(@Body File body);<\/code><\/li>\n<li><code>AResponse&lt;Pet, Err> addPet(@Body ResourceFile body);<\/code> (\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u0430\u043c\u0438 <code>JacksonConverterFactory<\/code> \u0438 <code>GsonConverterFactory<\/code> \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0430\u0431\u0440\u0438\u043a\u0443 \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u044b \u043f\u043e\u0434 \u0432\u0430\u0448\u0438 \u043d\u0443\u0436\u0434\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public class CustomConverterFactory extends ExtensionConverterFactory {    public CustomConverterFactory() {     super(LoggerFactory.getLogger(CustomConverterFactory.class));     final JacksonConverter&lt;Object> jacksonConverter = new JacksonConverter&lt;>();      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JacksonConverter \u0434\u043b\u044f application\/json, text\/json     registerMimeConverter(jacksonConverter, APP_JSON, APP_JSON_UTF8, TEXT_JSON, TEXT_JSON_UTF8);      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JacksonConverter \u0435\u0441\u043b\u0438 `Content-Type` \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d      registerMimeConverter(jacksonConverter, ContentType.NULL);      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c JacksonConverter \u0434\u043b\u044f Map, List \u0442\u0438\u043f\u043e\u0432     registerJavaTypeConverter(jacksonConverter, Map.class, List.class);      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0441\u044b\u0440\u043e\u0433\u043e \u0442\u0435\u043b\u0430     registerRawConverter(new CustomConverter&lt;>(), CustomBody.class);      \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c GsonConverter \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438      \/\/ \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 \"com.example.model.gson\" (\u0441\u0442\u0440\u043e\u0433\u043e\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435)     registerPackageConverter(new GsonConverter(), \"com.example.model.gson\");   }  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u0435\u043d\u0438\u0438 <strong>\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/strong> \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u0442\u0435\u043b\u043e, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>retrofit2.http.Headers<\/code> c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c <code>Content-Type<\/code>. <\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface PetApi {   @POST(\"\/api\/example\")   @Headers({\"Content-Type: application\/json\"})   AResponse&lt;Pet, Err> addPet(@Body() Object pet); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 <code>Content-Type<\/code> \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u0447\u0435\u0440\u0435\u0437 \u043c\u0430\u043f\u043a\u0443, \u0442\u043e \u0444\u0430\u0431\u0440\u0438\u043a\u0430 <strong>\u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u0442 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440<\/strong> \u0434\u043b\u044f MIME \u0442\u0438\u043f\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface PetApi {   @POST(\"\/api\/example\")   AResponse&lt;Pet, Err> addPet(@HeaderMap Map&lt;String, String> headers, @Body() Object pet);   \/\/ \u043d\u0435 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e \u044d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>retrofit<\/code> \u0438 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434\u0430. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c <code>CustomConverterFactory<\/code> \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0430 \u0438\u043b\u0438 java \u0442\u0438\u043f\u0430.<br \/>  \u0422\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@RequestConverter<\/code>, <code>@ResponseConverter<\/code>. \u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0447\u0430\u0441\u0442\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">public interface PetApi {      @POST(\"\/v2\/pet\")     @RequestConverter(bodyClasses = {Pet.class}, converter = JacksonConverter.class)     @ResponseConverter(bodyClasses = {Pet.class, Err.class}, converter = JacksonConverter.class)     AResponse&lt;Pet, Err> addPet(@Body Object body, @HeaderMap Map&lt;String, String> headers);  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0435 <code>bodyClasses<\/code> \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u0442\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d \u043a\u043e \u0432\u0441\u0435\u043c \u043c\u043e\u0434\u0435\u043b\u044f\u043c \u0438\u0437 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u044b \u043c\u0435\u0442\u043e\u0434\u0430.<br \/>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>@ResponseConverter(converter = JacksonConverter.class)<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043c\u043e\u0434\u0435\u043b\u044c <code>Pet<\/code> \u0438\u043b\u0438 <code>Err<\/code> (\u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430).<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u043e\u0448\u0435\u043d <code>ConverterNotFoundException<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">veslo.ConverterNotFoundException: Converter not found Transport event: RESPONSE Content-Type: null DTO type: class org.touchbit.retrofit.veslo.example.model.Status  SUPPORTED RESPONSE CONVERTERS: &lt;\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432> &lt;\u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043f\u043e\u0439\u043b\u0435\u0440 \u043d\u0438\u0436\u0435><\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0437 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043a\u043b\u0430\u0441\u0441 <code>org.touchbit.retrofit.veslo.example.model.Status<\/code>. \u042d\u0442\u043e json \u043c\u043e\u0434\u0435\u043b\u044c, \u043e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>Content-Type<\/code> \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 (<code>null<\/code>). \u041c\u043e\u0436\u0435\u043c \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u0431\u0430\u0433 \u043d\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 MIME \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 (\u0442\u0430\u043a\u043e\u0435 \u0442\u043e\u0436\u0435 \u0431\u044b\u0432\u0430\u0435\u0442), \u0442\u043e \u0432 \u0432\u0430\u0448\u0435\u043c <code>CustomConverterFactory<\/code> \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>JacksonConverter<\/code> \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \u0442\u0435\u043b\u0430 \u043e\u0442\u0432\u0435\u0442\u0430, \u0435\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>Content-Type<\/code> \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442:<br \/>  <code>registerMimeConverter(JacksonConverter.INSTANCE, ContentType.NULL);<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440\u043e\u0432 \u0432 `JacksonConverterFactory` (\u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430)<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">Raw converters:   veslo.client.converter.defaults.RawBodyTypeConverter       byte[]       java.io.File       java.lang.Byte[]       veslo.client.model.RawBody       veslo.client.model.ResourceFile Content type converters:   veslo.JacksonConverter       application\/json       application\/json; charset=utf-8       text\/json       text\/json; charset=utf-8 Java type converters:   veslo.JacksonConverter       java.util.List       java.util.Map   veslo.client.converter.defaults.JavaPrimitiveTypeConverter       boolean       byte       char       double       float       int       long       short   veslo.client.converter.defaults.JavaReferenceTypeConverter       java.lang.Boolean       java.lang.Byte       java.lang.Character       java.lang.Double       java.lang.Float       java.lang.Integer       java.lang.Long       java.lang.Short       java.lang.String<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Usefulness\"><\/a>  <\/p>\n<h2 id=\"poleznosti\">\u041f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u0438<\/h2>\n<p>  <a name=\"anchor_UsefulnessLogging\"><\/a>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u043c\u043e\u0434\u0443\u043b\u0435 <code>example<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b. \u042d\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e <code>LiveTemplates<\/code> (\u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0438\u0436\u0435) \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>test&lt;timestamp><\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>test1640455066880()<\/code>. \u042f \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@DisplayName(\"\")<\/code> \u0441 \u0432\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043a\u0430\u043a \u0440\u0430\u0437 \u043d\u0435 \u043f\u044b\u0436\u0438\u0442\u044c\u0441\u044f \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u043a\u0435\u0442 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430 \u043b\u043e\u0433\u0430. \u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>JunitExecutionListener.executionStarted()<\/code>.<br \/>  \u0414\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u043d\u0435 \u0431\u0443\u0434\u0443, \u043d\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u043d\u0443\u0442\u044c \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f <code>example<\/code> \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u0441\u0432\u043e\u0438 \u043d\u0443\u0436\u0434\u044b. <\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/habrastorage.org\/webt\/vq\/jh\/ys\/vqjhysyzsx3jklt3tw6tef3d4a0.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/vq\/jh\/ys\/vqjhysyzsx3jklt3tw6tef3d4a0.png\"\/><\/a><\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043b\u043e\u0433\u0430 \u0442\u0435\u0441\u0442\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b\u0430 \u0442\u0435\u0441\u0442\u0430 <code>AddPetTests.test1640455066880()<\/code> <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">14:38:04.786 INFO  - Test started: Checking the Pet model contract (PropertyNamingStrategy.SnakeCaseStrategy) 14:38:05.962 INFO  - API call: Logs user into the system 14:38:05.974 INFO  - REQUEST: GET https:\/\/petstore.swagger.io\/v2\/user\/login?password=abc123&amp;username=test Headers:   Host: petstore.swagger.io   Connection: Keep-Alive   Accept-Encoding: gzip   User-Agent: okhttp\/3.14.9 Body: (absent)  14:38:06.112 INFO  - RESPONSE: 200 https:\/\/petstore.swagger.io\/v2\/user\/login?password=abc123&amp;username=test Headers:   date: Fri, 04 Feb 2022 11:38:06 GMT   content-type: application\/json   access-control-allow-origin: *   access-control-allow-methods: GET, POST, DELETE, PUT   access-control-allow-headers: Content-Type, api_key, Authorization   x-expires-after: Fri Feb 04 12:38:06 UTC 2022   x-rate-limit: 5000   server: Jetty(9.2.9.v20150224)   Content-Length: -1 Body: (78-byte body)   {\"code\":200,\"type\":\"unknown\",\"message\":\"logged in user session:1643974686051\"}  14:38:06.115 INFO  - Response check completed without errors. 14:38:06.206 INFO  - API call: Add a new pet to the store 14:38:06.817 INFO  - REQUEST: POST https:\/\/petstore.swagger.io\/v2\/pet Headers:   Content-Type: application\/json   Content-Length: 291   Host: petstore.swagger.io   Connection: Keep-Alive   Accept-Encoding: gzip   User-Agent: okhttp\/3.14.9   api_key: special-key Body: (291-byte body)   {     \"id\" : 496977483,     \"photoUrls\" : [ \"www.shelba-bogisich.co.uk\" ],     \"category\" : {       \"id\" : 1082547212,       \"name\" : \"erjtrtczfi\"     },     \"name\" : \"gorilla\",     \"tags\" : [ {       \"id\" : 1231521466,       \"name\" : \"ybabllzaxw\"     }, {       \"id\" : 2012930363,       \"name\" : \"vgobbqhmxu\"     } ]   }  14:38:07.132 INFO  - RESPONSE: 200 https:\/\/petstore.swagger.io\/v2\/pet Headers:   date: Fri, 04 Feb 2022 11:38:07 GMT   content-type: application\/json   access-control-allow-origin: *   access-control-allow-methods: GET, POST, DELETE, PUT   access-control-allow-headers: Content-Type, api_key, Authorization   server: Jetty(9.2.9.v20150224)   Content-Length: -1 Body: (209-byte body)   {\"id\":496977483,\"category\":{\"id\":1082547212,\"name\":\"erjtrtczfi\"},\"name\":\"gorilla\",\"photoUrls\":[\"www.shelba-bogisich.co.uk\"],\"tags\":[{\"id\":1231521466,\"name\":\"ybabllzaxw\"},{\"id\":2012930363,\"name\":\"vgobbqhmxu\"}]}  14:38:07.306 INFO  - Response check completed without errors. 14:38:07.386 INFO  - SUCCESSFUL: Checking the Pet model contract (PropertyNamingStrategy.SnakeCaseStrategy)   file:\/\/\/Users\/ra\/repo\/src\/github.com\/touchbit\/retrofit-veslo\/example\/target\/logs\/test\/test1640455066880.log<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0442\u0435\u0441\u0442\u0430 \u0432 Intellij IDEA \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0432\u043e\u0434 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0430\u0434\u0435\u043d\u0438\u044f<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/ez\/fj\/u4\/ezfju4fb9pg_fowurwadhylmlam.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/ez\/fj\/u4\/ezfju4fb9pg_fowurwadhylmlam.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0432 <code>JunitExecutionListener<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0430 \u0442\u0435\u0441\u0442\u0430 \u0432 allure \u043e\u0442\u0447\u0435\u0442. \u0421\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>addTestLogAttachment()<\/code>.<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/7y\/nv\/ns\/7ynvnsvoy7hneulnpnobtr-vh78.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/7y\/nv\/ns\/7ynvnsvoy7hneulnpnobtr-vh78.png\"\/><\/a><\/p>\n<\/div><\/div>\n<p>  <a name=\"anchor_UsefulnessLiveTemplates\"><\/a>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u044b, \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u043d\u0430\u043a\u0438\u0434\u0430\u0442\u044c \u0447\u0435\u043a-\u043b\u0438\u0441\u0442. \u0412 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435, \u044d\u0442\u043e \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0432\u0438\u0434\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\u0423\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 'NEW' \u0423\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 'UNCONFIRMED' \u0423\u0441\u043f\u0435\u0448\u043d\u043e\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 'MEMBER' \u041e\u0448\u0438\u0431\u043a\u0430 (403) \u043f\u0440\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f 'BLOCKED' \u041e\u0448\u0438\u0431\u043a\u0430 (400) \u043f\u0440\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0435, \u0435\u0441\u043b\u0438 username \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043d<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0442\u043e-\u0442\u043e \u0441\u043a\u0430\u0436\u0435\u0442 <code>\u043c\u043d\u043e\u0433\u0430\u0431\u0443\u043a\u043e\u0432<\/code>, \u043d\u043e \u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u044f\u0441\u043d\u043e\u0441\u0442\u0438 \u0432 \u043e\u0442\u0447\u0435\u0442\u0435 \u0438 \u0432 \u043b\u043e\u0433\u0430\u0445 \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442-\u043c\u0435\u0442\u043e\u0434\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e <code>LiveTemplates<\/code> (IntelliJ IDEA). \u041a\u043e\u043f\u0438\u0440\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u0447\u0435\u043a-\u043b\u0438\u0441\u0442\u0430 \u0438 \u043d\u0430\u0431\u0438\u0440\u0430\u044e \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u0430\u0431\u0431\u0440\u0435\u0432\u0438\u0430\u0442\u0443\u0440\u0443 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u0414\u0430\u043b\u0435\u0435 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0432\u043e\u0442 \u0442\u0430\u043a:<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/fd\/n7\/ky\/fdn7kymbug3mq5iozdtscu80j0c.gif\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/n0\/nx\/86\/n0nx86tplplqjow5casy8mcvx6a.gif\"\/><\/a><\/p>\n<p>  <\/p>\n<p>\u0421\u0430\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a:<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/45\/cb\/i6\/45cbi6ip2x5pr044mltk6m86ud8.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/45\/cb\/i6\/45cbi6ip2x5pr044mltk6m86ud8.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043b\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430: <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">@org.junit.jupiter.api.Test @org.junit.jupiter.api.DisplayName(\"$DESCRIPTION$\") public void test$ID$() {     $END$ }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430: <\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">DESCRIPTION - clipboard() ID - groovyScript(\"return new Date().getTime();\")<\/code><\/pre>\n<\/div><\/div>\n<p>  <a name=\"anchor_UsefulnessPlugins\"><\/a>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043b\u0430\u0433\u0438\u043d\u044b IntelliJ IDEA<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p><strong>RoboPOJOGenerator<\/strong><br \/>  <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/8634-robopojogenerator\" rel=\"nofollow noopener noreferrer\">Homepage<\/a><br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 POJO \u043a\u043b\u0430\u0441\u0441\u044b \u043f\u043e JSON \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043f\u043e\u0434 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0444\u0440\u044d\u0439\u043c\u0432\u043e\u0440\u043a\u0438.<br \/>  File -> New -> Generate POJO from JSON<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/p9\/9k\/g2\/p99kg2mex26fgqctkhq63zi8qek.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/p9\/9k\/g2\/p99kg2mex26fgqctkhq63zi8qek.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p><strong>String Manipulation<\/strong><br \/>  <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/2162-string-manipulation\" rel=\"nofollow noopener noreferrer\">Homepage<\/a><br \/>  \u041c\u043e\u0449\u043d\u0435\u0439\u0448\u0438\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u043f\u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0442\u0440\u043e\u043a. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043b\u043e\u0441\u0441\u0430\u043b\u044c\u043d\u044b\u0435. \u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430.<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/kw\/ck\/_z\/kwck_z3t5ct4xwsnxgrsykfxqxs.gif\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/kw\/ck\/_z\/kwck_z3t5ct4xwsnxgrsykfxqxs.gif\"\/><\/a> <\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/habrastorage.org\/webt\/x9\/sz\/cs\/x9szcspxzqs5b-pucbzefz6fwcq.gif\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/x9\/sz\/cs\/x9szcspxzqs5b-pucbzefz6fwcq.gif\"\/><\/a> <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0445\u043e\u0442\u043a\u0435\u0435\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p><a href=\"https:\/\/habrastorage.org\/webt\/jj\/cs\/av\/jjcsavmmkrrep6ppl9efr_tpqok.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/jj\/cs\/av\/jjcsavmmkrrep6ppl9efr_tpqok.png\"\/><\/a><\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p><strong>Rainbow Brackets<\/strong><br \/>  <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/10080-rainbow-brackets\" rel=\"nofollow noopener noreferrer\">Homepage<\/a><br \/>  \u0426\u0432\u0435\u0442\u043e\u0432\u0430\u044f \u0434\u0438\u0444\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u043a\u043e\u0431\u043e\u043a, \u0442\u0435\u0433\u043e\u0432 \u0438 \u0442.\u0434.<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/zx\/h6\/sv\/zxh6svlpm1oevhxkygxm3w5akgg.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/zx\/h6\/sv\/zxh6svlpm1oevhxkygxm3w5akgg.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p><strong>Archive Browser<\/strong><br \/>  <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/9491-archive-browser\" rel=\"nofollow noopener noreferrer\">Homepage<\/a><br \/>  \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0432\u044b \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435.<br \/>  <a href=\"https:\/\/habrastorage.org\/webt\/be\/2v\/pk\/be2vpkqjqawsmhcz35js2u2be38.png\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/be\/2v\/pk\/be2vpkqjqawsmhcz35js2u2be38.png\"\/><\/a><\/p>\n<p>  <\/p>\n<p><strong>Fluent setter generator<\/strong><br \/>  <a href=\"https:\/\/plugins.jetbrains.com\/plugin\/7903-fluent-setter-generator\" rel=\"nofollow noopener noreferrer\">Homepage<\/a><br \/>  \u0421\u0442\u0430\u0440\u0435\u043d\u044c\u043a\u0438\u0439, \u043d\u043e \u0432\u0441\u0435 \u0435\u0449\u0435 \u0431\u0435\u0437\u043e\u0442\u043a\u0430\u0437\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 fluent \u0441\u0435\u0442\u0442\u0435\u0440\u043e\u0432. \u042d\u0442\u043e \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0432\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435\u0441\u044c lombok. <\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/habrastorage.org\/webt\/uw\/md\/jw\/uwmdjwgih5avtb5gsyykkczppcu.gif\" rel=\"nofollow noopener noreferrer\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/uw\/md\/jw\/uwmdjwgih5avtb5gsyykkczppcu.gif\"\/><\/a><\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<p>  <a name=\"anchor_Finally\"><\/a>  <\/p>\n<h2 id=\"v-zaklyuchenie\">\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a\u0438\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0432\u044b\u0432\u043e\u0434\u044b \u044f \u0441\u0434\u0435\u043b\u0430\u043b<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0420\u0435\u0448\u0438\u043b\u0441\u044f \u043d\u0430 OpenSource \u043f\u0440\u043e\u0435\u043a\u0442 \u2014 \u0434\u0435\u043b\u0430\u0439 \u0434\u043b\u044f \u043b\u044e\u0434\u0435\u0439, \u0430 \u043d\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f.<\/li>\n<li>OpenSource \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043f\u0438\u0441\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0447\u0435\u043c \u0434\u043b\u044f \u043b\u0438\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0432 \u043e\u0434\u043d\u043e \u043b\u0438\u0446\u043e.<\/li>\n<li>\u041f\u0440\u043e\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u043a\u0440\u0430\u0439\u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/li>\n<li>\u0425\u043e\u0442\u044c \u044f \u043f\u0430\u0440\u0435\u043d\u044c \u043e\u043f\u044b\u0442\u043d\u044b\u0439, \u043d\u043e \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u0438\u043b\u0435\u0442\u0430\u043d\u0442.<\/li>\n<li>\u0418\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c \u043f\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b. \u0410 \u043b\u0443\u0447\u0448\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0438\u0445 \u043d\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432 \u043f\u043e\u043c\u043e\u0449\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c.<\/li>\n<li>\u0421\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f \u0432 100% code coverage \u0434\u0435\u043b\u043e \u043a\u0440\u0430\u0439\u043d\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0435, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u043f\u0438\u0448\u0435\u0448\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u0430\u0437\u0435 \u0434\u0440\u0443\u0433\u043e\u0433\u043e.<\/li>\n<li>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432\u0441\u0435 \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0448\u044c. \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0432\u044b\u043b\u0435\u0437\u0435\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e\/\u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u0440\u0438\u0447\u0435\u043c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438.<\/li>\n<li>\u0421\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u043e \u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043c\u0438\u043d\u043e\u0440\u043d\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445.<\/li>\n<li>\u041f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0433\u0434\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u043e \u2014 \u0431\u043e\u043b\u044c\u043d\u043e, \u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u044f\u0435\u0442.<\/li>\n<li>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u0442\u043e\u0438\u043b\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c <code>retrofit<\/code> \u043a\u043b\u0438\u0435\u043d\u0442, \u0430 \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435.<\/li>\n<li>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0439 \u0441\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 java.<\/li>\n<li>\u0421 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u0434\u0430 \u043d\u0435 \u0432\u0441\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 \u0440\u0430\u0437\u043e\u0432\u0430\u044f.<\/li>\n<li>\u041f\u0438\u0448\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u043a\u0430\u043a \u0434\u043b\u044f \u0434\u0435\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0445, \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0441\u0435\u0431\u0435 \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0441\u043a\u0430\u0436\u0435\u0448\u044c.<\/li>\n<li>\u0424\u0438\u043a\u0441\u0438\u0440\u0443\u0439 \u0438\u0434\u0435\u0438 \u0432 \u0442\u0440\u0435\u043a\u0435\u0440\u0435, \u0430 \u043d\u0435 \u043d\u0430 \u0431\u0443\u043c\u0430\u0436\u043a\u0435, \u0438\u043d\u0430\u0447\u0435 \u043b\u044e\u0431\u0438\u043c\u044b\u0439 \u043f\u0438\u0442\u043e\u043c\u0435\u0446 \u0431\u0443\u043c\u0430\u0436\u043a\u0443 \u0441\u044a\u0435\u0441\u0442.<\/li>\n<li>\u041f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0431\u0443\u0434\u0443\u0447\u0438 \u0431\u0435\u0437\u0440\u0430\u0431\u043e\u0442\u043d\u044b\u043c (\u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b).<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432, \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0437\u0430\u043d\u044f\u043b\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 2 \u043c\u0435\u0441\u044f\u0446\u0430 \u0447\u0438\u0441\u0442\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u0418 \u044d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0435\u043b, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u043e\u0434\u0443\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0438\u043b\u0443 \u043c\u043e\u0435\u0439 \u0441\u0444\u0435\u0440\u044b \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u0438.<br \/>  \u0418\u0437 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043b\u0430\u043d\u043e\u0432 \u2014 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440 \u0434\u043b\u044f xml \u0438 protobuf, \u043f\u0440\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 SOAP \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u043e\u043c \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u0433\u0430\u0439\u0434.<br \/>  \u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u0434\u0435\u0438 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0442\u043e \u043f\u0440\u043e\u0448\u0443 <a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo\/issues\" rel=\"nofollow noopener noreferrer\">\u0441\u044e\u0434\u0430<\/a>.<br \/>  \u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0431\u0435 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0447\u0430\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0442\u043e \u043d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439 <a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo\/blob\/main\/LICENSE\" rel=\"nofollow noopener noreferrer\">Apache 2.0<\/a>. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/shaburov.github.io\/\" rel=\"nofollow noopener noreferrer\">\u0410\u0432\u0442\u043e\u0440 \u0441\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/touchbit\/retrofit-veslo\" rel=\"nofollow noopener noreferrer\">Git \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a><\/li>\n<li><a href=\"https:\/\/mvnrepository.com\/artifact\/org.touchbit.retrofit.veslo\" rel=\"nofollow noopener noreferrer\">\u041f\u0440\u043e\u0435\u043a\u0442 \u0432 maven central<\/a><\/li>\n<li><a href=\"https:\/\/t.me\/veslo_retrofit\" rel=\"nofollow noopener noreferrer\">TG \u0433\u0440\u0443\u043f\u043f\u0430: Veslo Q&amp;A (retrofit)<\/a><\/li>\n<li><a href=\"https:\/\/t.me\/qa_automation\" rel=\"nofollow noopener noreferrer\">TG \u0433\u0440\u0443\u043f\u043f\u0430: QA \u2014 Automation<\/a><\/li>\n<li><a href=\"https:\/\/t.me\/qa_ru\" rel=\"nofollow noopener noreferrer\">TG \u0433\u0440\u0443\u043f\u043f\u0430: QA \u2014 \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e\u0432\u043e\u0440\u044f\u0449\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e<\/a><\/li>\n<li><a href=\"https:\/\/t.me\/qa_jobs\" rel=\"nofollow noopener noreferrer\">TG \u0433\u0440\u0443\u043f\u043f\u0430: QA \u2014 \u0432\u0430\u043a\u0430\u043d\u0441\u0438\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0440\u044b\u043d\u043a\u0430 \u0432\u0430\u043a\u0430\u043d\u0441\u0438\u0439<\/a><\/li>\n<li><a href=\"https:\/\/t.me\/qa_resumes\" rel=\"nofollow noopener noreferrer\">TG \u0433\u0440\u0443\u043f\u043f\u0430: QA \u2014 \u0420\u0435\u0437\u044e\u043c\u0435<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u043e\u0442, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438 \u0432\u0441\u0435. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0444\u0438\u0434\u0431\u044d\u043a\u0443.<\/p>\n<p>  <\/p>\n<p><a href=\"#anchor_TOC\">\u041a \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044e<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/647499\/\"> https:\/\/habr.com\/ru\/post\/647499\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442 \u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0438 \u0434\u043b\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e HTTP \u043a\u043b\u0438\u0435\u043d\u0442\u0430 <a href=\"https:\/\/square.github.io\/retrofit\/\" rel=\"nofollow noopener noreferrer\">retrofit<\/a> \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0432 \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f API. \u0421\u043e\u0437\u0434\u0430\u043d \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 API \u0442\u0435\u0441\u0442\u043e\u0432. \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043e\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0437\u0438\u0442\u0438\u0432\u043d\u044b\u0445 \u0438 \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0435\u0440, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043c\u044f\u0433\u043a\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 (softly assert) \u0438 \u0435\u0449\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u044f\u043a\u0438\u0445 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/ol\/lf\/aw\/ollfawiswjqiyiznfkmiyylu3rq.gif\"\/><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-329217","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=329217"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329217\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=329217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=329217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=329217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}