当前位置: 首页 > 后端技术 > Java

Java 使用 HttpClient 发送带用户名密码认证的 GET 和 POST 请求

时间:2023-04-01 21:05:49 Java

Java使用HttpClient发送带用户名密码认证的GET和POST请求/POST/PUT/DELETE等请求;HTTP请求可以附带认证,包括基本的用户名/密码认证,BearerToken认证;requests可以自定义超时时间;HTTP请求可以带参数也可以不带参数;HTTP请求返回的结果可以直接传递给一个Class,这样就不需要对结果进行二次解析;请求的路径可以是url或者Uri;针对以上常见的HTTP请求,在HttpClient的基础上进行了二次封装,可以直接发送HTTP请求,简单高效。本文使用的HttpClient版本为4.5.3,pom依赖如下:org.apache.httpcomponentshttpclient4.5.3/dependency>认证方式在HTTP请求中,常用的认证方式有:用户名+密码认证BearerToken认证其实这些认证的本质都是在HTTPRequestHeader中添加固定参数,如下:Authorization:tokencharacters字符串上面的Authorization是HTTPHeader的key,token字符串是在具体的认证方式中需要传递的参数。我们将所有的认证方法抽象到Auth类中,定义方法getAuth方法,由具体的子类实现,返回自定义认证方法中需要的token字符串。基本认证AuthpublicinterfaceAuth{StringgetAuth();}用户名密码认证BasicAuth,用于用户名密码认证,代码如下:publicclassBasicAuthimplementsAuth{privateStringusername;私有字符串密码;publicBasicAuth(Stringusername,Stringpassword){this.username=username;this.password=密码;}@OverridepublicStringgetAuth(){Stringauth=String.format("%s:%s",this.username,this.password);byte[]encodedAuth=Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));返回“基本”+新字符串(encodedAuth);}}BearerToken认证BearerAuth,用于BearerToken认证,代码如下:publicclassBearerAuthimplementsAuth{privateStringtoken;publicBearerAuth(Stringtoken){this.token=token;}@OverridepublicStringgetAuth(){return"Bearer"+this.token;}}上面介绍了两种常用的认证方式。对于其他的认证方式,只需实现Auth接口的getAuth方法即可。我们将在实际发送HTTP请求时使用此Auth。配置超时HttpClient,通过setDefaultRequestConfig设置请求的参数配置,包括请求超时时间等生成RequestConfig/***设置HTTP请求超时时间**@paramconnectTimeouttcp连接超时时间*@paramreadTimeout读取数据超时时间time*@return*/privateRequestConfiggetRequestConfig(intconnectTimeout,intreadTimeout){returnRequestConfig.custom().setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).setSocketTimeout(readTimeout).build();}设置超时时间HttpClientBuilder。创建().setDefaultRequestConfig(requestConfig).build();到这里,HttpClient需要做的一些配置,基本就结束了,下面会给出完整的代码示例。完整代码HttpRequestClientimportcom.google.gson.Gson;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.lang3.StringUtils;importorg.apache.http.HttpHeaders;importorg.apache.http.HttpResponse;importorg.apache.http.client.HttpClient;导入org.apache.http.client.config.RequestConfig;导入org.apache.http.client.methods.RequestBuilder;导入org.apache.http.entity.ContentType;导入org.apache.http.entity.StringEntity;导入org.apache.http.impl.client.HttpClientBuilder;导入org.apache.http.util.EntityUtils;导入org.springframework.http.HttpMethod;导入java.io.IOException;导入java.net.URI;importjava.nio.charset.StandardCharsets;importjava.util.HashMap;importjava.util.Map;/***@authorwxweven*/@Slf4jpublicclassHttpRequestClient{//默认连接/读取数据超时时间都是10sprivatestaticfinalintDEFAULT_CONNECT_TIMEOUT=10_000;privatestaticfinalintDEFAULT_READ_TIMEOUT=10_000;私有静态最终GsonGSON=newGson();私人授权授权;私有HttpClienthttpClient;//用户名密码认证,默认超时时间(10s)publicHttpRequestClient(Stringusername,Stringpassword){this(username,password,DEFAULT_CONNECT_TIMEOUT,DEFAULT_READ_TIMEOUT);}//用户名密码认证,自定义超时时间this.httpClient=HttpClientBuilder.create().setDefaultRequestConfig(getRequestConfig(connectTimeout,Timeout)).build();}//BearerToken认证,默认超时(10s)publicHttpRequestClient(StringbearerToken){this(bearerToken,DEFAULT_CONNECT_TIMEOUT,DEFAULT_READ_TIMEOUT);}//BearerToken认证,自定义超时时间publicHttpRequestClient(StringbearerToken,intconnectTimeout,intreadTimeout){this.auth=newBearerAuth(bearerToken);this.httpClient=HttpClientBuilder.create().setDefaultRequestConfig(getRequestConfig(connectTimeout,readTimeout)).build();}/***设置HTTP请求超时**@paramconnectTimeouttcp连接超时时间*@paramreadTimeout读取数据超时时间*@return*/privateRequestConfiggetRequestConfig(intconnectTimeout,intreadTimeout){returnRequestConfig.custom().setConnectTimeout(connectTimeout).setConnectionRequestTimeout(connectTimeout).setSocketTimeout(readTimeout).build();}/***发送不带参数的GET请求**@paramurl*@return*/publicStringdoGet(Stringurl){returndoGet(url,newHashMap<>());}/***发送不带参数的GET请求**@paramuri*@return*/publicStringdoGet(URIuri){re转doGet(uri,newHashMap<>());}/***发送GET请求,K-V格式参数**@paramurl*@paramparams*@return*/publicStringdoGet(Stringurl,Mapparams){RequestBuilderreqBuilder=RequestBuilder.get(url);返回doGet(reqBuilder,参数);}/***发送GET请求,K-V格式参数**@paramuri*@paramparams*@return*/publicStringdoGet(URIuri,Mapparams){RequestBuilderreqBuilder=RequestBuilder.get(uri);返回doGet(reqBuilder,参数);}publicStringdoGet(RequestBuilderreqBuilder,Mapparams){reqBuilder.addHeader(HttpHeaders.AUTHORIZATION,auth.getAuth());for(Map.Entryentry:params.entrySet()){reqBuilder.addParameter(entry.getKey(),entry.getValue());}尝试{HttpResponseresp=httpClient.execute(reqBuilder.build());返回EntityUtils.toString(resp.getEntity(),StandardCharsets.UTF_8);}catch(IOExceptione){log.error("doGet异常:reqBuilder={},params={}",reqBuilder,params,e);返回空值;}}/****发送不带参数的GET请求,返回指定类型的类*@paramurl请求的url*@paramresponseType返回类型*@param*@return*/publicTgetForObject(Stringurl,ClassresponseType){RequestBuilderreqBuilder=RequestBuilder.get(url);返回getForObject(reqBuilder,responseType);}/****发送GET请求,不带参数,返回指定类型的类*@paramuri请求uri*@paramresponseType返回类型*@param*@return*/publicTgetForObject(URIuri,ClassresponseType){RequestBuilderreqBuilder=RequestBuilder.get(uri);返回getForObject(reqBuilder,responseType);}公共TgetForObject(RequestBuilderreqBuilder,ClassresponseType){reqBuilder.addHeader(HttpHeaders.AUTHORIZATION,auth.getAuth());尝试{HttpResponseresp=httpClient.execute(reqBuilder.build());字符串结果=EntityUtils.toString(resp.getEntity(),StandardCharsets.UTF_8);返回GSON.fromJson(result,responseType);}catch(IOExceptione){log.error("getForObject异常:reqBuilder={},responseType={}",reqBuilder,responseType,e);返回空值;}}/***发送POST请求,JSON格式**@paramurl*@paramjsonjson字符串*@return*/publicStringdoPost(Stringurl,Stringjson){try{HttpResponseresp=this.exchange(HttpMethod.POST、网址、json);返回EntityUtils.toString(resp.getEntity(),StandardCharsets.UTF_8);}catch(IOExceptione){log.error("doPost异常:url={},json={}",url,json,e);returnnull;}}/***以JSON形式发送POST请求,返回HttpResponse**@paramurl*@paramjsonjsonstring*@return*/publicHttpResponsedoPostResp(Stringurl,Stringjson){returnthis.exchange(HttpMethod.POST,url,json);}/***以JSON格式发送PUT请求**@paramurl*@paramjsonjsonstring*@return*/publicHttpResponsedoPut(Stringurl,Stringjson){returnthis.exchange(HttpMethod.PUT,url,json);}/***以JSON格式发送PUT请求**@paramurl*@paramjsonjsonString*@return*/publicHttpResponsedoDelete(Stringurl,Stringjson){returnthis.exchange(HttpMethod.DELETE,url,json);}publicHttpResponseexchange(HttpMethodmethod,Stringurl,Stringjson){RequestBuilderreqBuilder=RequestBuilder.create复制代码(方法.toString()).setUri(url).addHeader(HttpHeaders.AUTHORIZATION,auth.getAuth()).addHeader("接受",ContentType.APPLICATION_JSON.toString()).addHeader("内容类型",ContentType.APPLICATION_JSON.toString());如果(StringUtils.isNotBlank(json)){reqBuilder.setEntity(newStringEntity(json,ContentType.APPLICATION_JSON));}try{returnhttpClient.execute(reqBuilder.build());}catch(IOExceptione){log.error("doPost异常:url={},json={}",url,json,e);返回空值;}}}我是梅小希,最近在东南亚一家电商公司从事DevOps相关工作。从这一期开始,我会继续分享基于Jenkins的CI/CD工作流程,包括JenkinsOnk8s等。如果你对Java或者Jenkins感兴趣,请联系我:wxweven(注意DevOps),公众号:这个文章由博客群发等运营工具平台OpenWrite发布