All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.net.url.UrlBuilder Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.core.net.url;

import cn.hutool.core.builder.Builder;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.net.RFC3986;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.nio.charset.Charset;

/**
 * URL 生成器,格式形如:
 * 
 * [scheme:]scheme-specific-part[#fragment]
 * [scheme:][//authority][path][?query][#fragment]
 * [scheme:][//host:port][path][?query][#fragment]
 * 
* * @author looly * @see Uniform Resource Identifier * @since 5.3.1 */ public final class UrlBuilder implements Builder { private static final long serialVersionUID = 1L; private static final String DEFAULT_SCHEME = "http"; /** * 协议,例如http */ private String scheme; /** * 主机,例如127.0.0.1 */ private String host; /** * 端口,默认-1 */ private int port = -1; /** * 路径,例如/aa/bb/cc */ private UrlPath path; /** * 查询语句,例如a=1&b=2 */ private UrlQuery query; /** * 标识符,例如#后边的部分 */ private String fragment; /** * 编码,用于URLEncode和URLDecode */ private Charset charset; /** * 是否需要编码`%`
* 区别对待,如果是,则生成URL时需要重新全部编码,否则跳过所有`%` */ private boolean needEncodePercent; /** * 使用URI构建UrlBuilder * * @param uri URI * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder of(URI uri, Charset charset) { return of(uri.getScheme(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getRawQuery(), uri.getFragment(), charset); } /** * 使用URL字符串构建UrlBuilder,当传入的URL没有协议时,按照http协议对待
* 此方法不对URL编码 * * @param httpUrl URL字符串 * @return UrlBuilder * @since 5.4.3 */ public static UrlBuilder ofHttpWithoutEncode(String httpUrl) { return ofHttp(httpUrl, null); } /** * 使用URL字符串构建UrlBuilder,当传入的URL没有协议时,按照http协议对待,编码默认使用UTF-8 * * @param httpUrl URL字符串 * @return UrlBuilder * @since 5.6.3 */ public static UrlBuilder ofHttp(String httpUrl) { return ofHttp(httpUrl, CharsetUtil.CHARSET_UTF_8); } /** * 使用URL字符串构建UrlBuilder,当传入的URL没有协议时,按照http协议对待。 * * @param httpUrl URL字符串 * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder ofHttp(String httpUrl, Charset charset) { Assert.notBlank(httpUrl, "Http url must be not blank!"); httpUrl = StrUtil.trimStart(httpUrl); // issue#I66CIR if(false == StrUtil.startWithAnyIgnoreCase(httpUrl, "http://", "https://")){ httpUrl = "http://" + httpUrl; } return of(URLUtil.toUrlForHttp(httpUrl), charset); } /** * 使用URL字符串构建UrlBuilder,默认使用UTF-8编码 * * @param url URL字符串 * @return UrlBuilder */ public static UrlBuilder of(String url) { return of(url, CharsetUtil.CHARSET_UTF_8); } /** * 使用URL字符串构建UrlBuilder * * @param url URL字符串 * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder of(String url, Charset charset) { Assert.notBlank(url, "Url must be not blank!"); return of(URLUtil.url(StrUtil.trim(url)), charset); } /** * 使用URL构建UrlBuilder * * @param url URL * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder of(URL url, Charset charset) { return of(url.getProtocol(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef(), charset); } /** * 构建UrlBuilder * * @param scheme 协议,默认http * @param host 主机,例如127.0.0.1 * @param port 端口,-1表示默认端口 * @param path 路径,例如/aa/bb/cc * @param query 查询,例如a=1&b=2 * @param fragment 标识符例如#后边的部分 * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder of(String scheme, String host, int port, String path, String query, String fragment, Charset charset) { return of(scheme, host, port, UrlPath.of(path, charset), UrlQuery.of(query, charset, false), fragment, charset); } /** * 构建UrlBuilder * * @param scheme 协议,默认http * @param host 主机,例如127.0.0.1 * @param port 端口,-1表示默认端口 * @param path 路径,例如/aa/bb/cc * @param query 查询,例如a=1&b=2 * @param fragment 标识符例如#后边的部分 * @param charset 编码,用于URLEncode和URLDecode * @return UrlBuilder */ public static UrlBuilder of(String scheme, String host, int port, UrlPath path, UrlQuery query, String fragment, Charset charset) { return new UrlBuilder(scheme, host, port, path, query, fragment, charset); } /** * 创建空的UrlBuilder * * @return UrlBuilder * @deprecated 请使用 {@link #of()} */ @Deprecated public static UrlBuilder create() { return new UrlBuilder(); } /** * 创建空的UrlBuilder * * @return UrlBuilder */ public static UrlBuilder of() { return new UrlBuilder(); } /** * 构造 */ public UrlBuilder() { this.charset = CharsetUtil.CHARSET_UTF_8; } /** * 构造 * * @param scheme 协议,默认http * @param host 主机,例如127.0.0.1 * @param port 端口,-1表示默认端口 * @param path 路径,例如/aa/bb/cc * @param query 查询,例如a=1&b=2 * @param fragment 标识符例如#后边的部分 * @param charset 编码,用于URLEncode和URLDecode,{@code null}表示不编码 */ public UrlBuilder(String scheme, String host, int port, UrlPath path, UrlQuery query, String fragment, Charset charset) { this.charset = charset; this.scheme = scheme; this.host = host; this.port = port; this.path = path; this.query = query; this.setFragment(fragment); // 编码非空情况下做解码 this.needEncodePercent = null != charset; } /** * 获取协议,例如http * * @return 协议,例如http */ public String getScheme() { return scheme; } /** * 获取协议,例如http,如果用户未定义协议,使用默认的http协议 * * @return 协议,例如http */ public String getSchemeWithDefault() { return StrUtil.emptyToDefault(this.scheme, DEFAULT_SCHEME); } /** * 设置协议,例如http * * @param scheme 协议,例如http * @return this */ public UrlBuilder setScheme(String scheme) { this.scheme = scheme; return this; } /** * 获取 主机,例如127.0.0.1 * * @return 主机,例如127.0.0.1 */ public String getHost() { return host; } /** * 设置主机,例如127.0.0.1 * * @param host 主机,例如127.0.0.1 * @return this */ public UrlBuilder setHost(String host) { this.host = host; return this; } /** * 获取端口,默认-1 * * @return 端口,默认-1 */ public int getPort() { return port; } /** * 获取端口,如果未自定义返回协议默认端口 * * @return 端口 */ public int getPortWithDefault() { int port = getPort(); if (port > 0) { return port; } URL url = this.toURL(); return url.getDefaultPort(); } /** * 设置端口,默认-1 * * @param port 端口,默认-1 * @return this */ public UrlBuilder setPort(int port) { this.port = port; return this; } /** * 获得authority部分 * * @return authority部分 */ public String getAuthority() { return (port < 0) ? host : host + ":" + port; } /** * 获取路径,例如/aa/bb/cc * * @return 路径,例如/aa/bb/cc */ public UrlPath getPath() { return path; } /** * 获得路径,例如/aa/bb/cc * * @return 路径,例如/aa/bb/cc */ public String getPathStr() { return null == this.path ? StrUtil.SLASH : this.path.build(charset, this.needEncodePercent); } /** * 是否path的末尾加 / * * @param withEngTag 是否path的末尾加 / * @return this * @since 5.8.5 */ public UrlBuilder setWithEndTag(boolean withEngTag) { if (null == this.path) { this.path = new UrlPath(); } this.path.setWithEndTag(withEngTag); return this; } /** * 设置路径,例如/aa/bb/cc,将覆盖之前所有的path相关设置 * * @param path 路径,例如/aa/bb/cc * @return this */ public UrlBuilder setPath(UrlPath path) { this.path = path; return this; } /** * 增加路径,在现有路径基础上追加路径 * * @param path 路径,例如aaa/bbb/ccc * @return this */ public UrlBuilder addPath(CharSequence path) { UrlPath.of(path, this.charset).getSegments().forEach(this::addPathSegment); return this; } /** * 增加路径节点,路径节点中的"/"会被转义为"%2F" * * @param segment 路径节点 * @return this * @since 5.7.16 */ public UrlBuilder addPathSegment(CharSequence segment) { if (StrUtil.isEmpty(segment)) { return this; } if (null == this.path) { this.path = new UrlPath(); } this.path.add(segment); return this; } /** * 追加path节点 * * @param path path节点 * @return this * @deprecated 方法重复,请使用{@link #addPath(CharSequence)} */ @Deprecated public UrlBuilder appendPath(CharSequence path) { return addPath(path); } /** * 获取查询语句,例如a=1&b=2
* 可能为{@code null} * * @return 查询语句,例如a=1&b=2,可能为{@code null} */ public UrlQuery getQuery() { return query; } /** * 获取查询语句,例如a=1&b=2 * * @return 查询语句,例如a=1&b=2 */ public String getQueryStr() { return null == this.query ? null : this.query.build(this.charset, this.needEncodePercent); } /** * 设置查询语句,例如a=1&b=2,将覆盖之前所有的query相关设置 * * @param query 查询语句,例如a=1&b=2 * @return this */ public UrlBuilder setQuery(UrlQuery query) { this.query = query; return this; } /** * 添加查询项,支持重复键 * * @param key 键 * @param value 值 * @return this */ public UrlBuilder addQuery(String key, Object value) { if (StrUtil.isEmpty(key)) { return this; } if (this.query == null) { this.query = new UrlQuery(); } this.query.add(key, value); return this; } /** * 获取标识符,#后边的部分 * * @return 标识符,例如#后边的部分 */ public String getFragment() { return fragment; } /** * 获取标识符,#后边的部分 * * @return 标识符,例如#后边的部分 */ public String getFragmentEncoded() { final char[] safeChars = this.needEncodePercent ? null : new char[]{'%'}; return RFC3986.FRAGMENT.encode(this.fragment, this.charset, safeChars); } /** * 设置标识符,例如#后边的部分 * * @param fragment 标识符,例如#后边的部分 * @return this */ public UrlBuilder setFragment(String fragment) { if (StrUtil.isEmpty(fragment)) { this.fragment = null; } this.fragment = StrUtil.removePrefix(fragment, "#"); return this; } /** * 获取编码,用于URLEncode和URLDecode * * @return 编码 */ public Charset getCharset() { return charset; } /** * 设置编码,用于URLEncode和URLDecode * * @param charset 编码 * @return this */ public UrlBuilder setCharset(Charset charset) { this.charset = charset; return this; } /** * 创建URL字符串 * * @return URL字符串 */ @Override public String build() { return toURL().toString(); } /** * 转换为{@link URL} 对象 * * @return {@link URL} */ public URL toURL() { return toURL(null); } /** * 转换为{@link URL} 对象 * * @param handler {@link URLStreamHandler},null表示默认 * @return {@link URL} */ public URL toURL(URLStreamHandler handler) { final StringBuilder fileBuilder = new StringBuilder(); // path fileBuilder.append(getPathStr()); // query final String query = getQueryStr(); if (StrUtil.isNotBlank(query)) { fileBuilder.append('?').append(query); } // fragment if (StrUtil.isNotBlank(this.fragment)) { fileBuilder.append('#').append(getFragmentEncoded()); } try { return new URL(getSchemeWithDefault(), host, port, fileBuilder.toString(), handler); } catch (MalformedURLException e) { return null; } } /** * 转换为URI * * @return URI */ public URI toURI() { try { return toURL().toURI(); } catch (URISyntaxException e) { return null; } } @Override public String toString() { return build(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy