HttpKit.java
package space.sunqian.common.net.http;
import space.sunqian.annotations.Nonnull;
import space.sunqian.annotations.Nullable;
import space.sunqian.common.Fs;
import space.sunqian.common.base.chars.CharsKit;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
/**
* Http utilities. The part of the HTTP request is based on {@link HttpCaller}.
*
* @author sunqian
*/
public class HttpKit {
private static final @Nonnull HttpCaller DEFAULT_CALLER = HttpCaller.newHttpCaller();
/**
* Requests the given http request, returns the response.
*
* @param req the given http request
* @return the response
* @throws HttpNetException if an error occurs
*/
public static @Nonnull HttpResp request(@Nonnull HttpReq req) throws HttpNetException {
return DEFAULT_CALLER.request(req);
}
/**
* Requests the given http request, returns the response.
*
* @param req the given http request
* @param proxy the proxy, may be {@code null} if no proxy is needed
* @return the response
* @throws HttpNetException if an error occurs
*/
public static @Nonnull HttpResp request(@Nonnull HttpReq req, @Nullable Proxy proxy) throws HttpNetException {
return HttpCaller.newBuilder().proxy(Fs.nonnull(proxy, Proxy.NO_PROXY)).build().request(req);
}
/**
* Parses the charset from the given http content type, may be {@code null} if the charset is not specified.
*
* @param contentType the given http content type
* @return the charset parsed from the given http content type, may be {@code null} if the charset is not specified
*/
public static @Nullable Charset contentCharset(@Nonnull String contentType) {
String[] parts = contentType.split(";");
for (String part : parts) {
String charsetToken = "charset=";
int charsetIndex = part.indexOf(charsetToken);
if (charsetIndex < 0) {
continue;
}
String charsetName = part.substring(charsetIndex + charsetToken.length()).trim();
return Charset.forName(charsetName);
}
return null;
}
/**
* Builds and returns a url with the query string. The query string is encoded using
* {@link CharsKit#defaultCharset()}.
*
* @param baseUrl the base url
* @param queryString the map represents the query string
* @return a url with the query string
* @throws HttpNetException if an error occurs
*/
public static @Nonnull URL buildUrl(
@Nonnull String baseUrl, @Nonnull Map<String, String> queryString
) throws HttpNetException {
return buildUrl(baseUrl, queryString, CharsKit.defaultCharset());
}
/**
* Builds and returns a url with the query string. The query string is encoded using the specified charset.
*
* @param baseUrl the base url
* @param queryString the map represents the query string
* @param charset the specified charset for encoding the query string
* @return a url with the query string
* @throws HttpNetException if an error occurs
*/
public static @Nonnull URL buildUrl(
@Nonnull String baseUrl, @Nonnull Map<String, String> queryString, @Nonnull Charset charset
) throws HttpNetException {
StringBuilder url = new StringBuilder(baseUrl);
if (!queryString.isEmpty()) {
url.append("?");
queryString.forEach((key, value) -> url.append(
encodeUrl(key, charset)
).append("=").append(
encodeUrl(value, charset)
).append("&"));
}
return Fs.uncheck(() -> new URL(url.toString()), HttpNetException::new);
}
/**
* Translates a string into {@code application/x-www-form-urlencoded} format using
* {@link CharsKit#defaultCharset()}.
*
* @param str the {@code String} to be translated
* @return the translated {@code String}
* @throws HttpNetException if an error occurs
*/
public static @Nonnull String encodeUrl(@Nonnull String str) throws HttpNetException {
return encodeUrl(str, CharsKit.defaultCharset());
}
/**
* Translates a string into {@code application/x-www-form-urlencoded} format using the specific charset.
*
* @param str the {@code String} to be translated
* @param charset the specified charset
* @return the translated {@code String}
* @throws HttpNetException if an error occurs
*/
public static @Nonnull String encodeUrl(@Nonnull String str, @Nonnull Charset charset) throws HttpNetException {
try {
return URLEncoder.encode(str, charset.name()).replace("+", "%20");
} catch (Exception e) {
throw new HttpNetException(e);
}
}
private HttpKit() {
}
}