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

com.wl4g.component.common.remoting.uri.UriUtils Maven / Gradle / Ivy

/*
 * Copyright 2017 ~ 2025 the original author or authors. 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wl4g.component.common.remoting.uri;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;
import com.wl4g.component.common.collection.multimap.LinkedMultiValueMap;
import com.wl4g.component.common.collection.multimap.MultiValueMap;
import com.wl4g.component.common.lang.StringUtils2;

/**
 * Utility class for URI encoding and decoding based on RFC 3986. Offers
 * encoding methods for the various URI components.
 *
 * 

* All {@code encode*(String, String)} methods in this class operate in a * similar way: *

    *
  • Valid characters for the specific URI component as defined in RFC 3986 * stay the same.
  • *
  • All other characters are converted into one or more bytes in the given * encoding scheme. Each of the resulting bytes is written as a hexadecimal * string in the "%xy" format.
  • *
* */ public abstract class UriUtils { /** * Encode the given URI scheme with the given encoding. * * @param scheme * the scheme to be encoded * @param encoding * the character encoding to encode to * @return the encoded scheme */ public static String encodeScheme(String scheme, String encoding) { return encode(scheme, encoding, HierarchicalUriComponents.Type.SCHEME); } /** * Encode the given URI scheme with the given encoding. * * @param scheme * the scheme to be encoded * @param charset * the character encoding to encode to * @return the encoded scheme * @since 5.0 */ public static String encodeScheme(String scheme, Charset charset) { return encode(scheme, charset, HierarchicalUriComponents.Type.SCHEME); } /** * Encode the given URI authority with the given encoding. * * @param authority * the authority to be encoded * @param encoding * the character encoding to encode to * @return the encoded authority */ public static String encodeAuthority(String authority, String encoding) { return encode(authority, encoding, HierarchicalUriComponents.Type.AUTHORITY); } /** * Encode the given URI authority with the given encoding. * * @param authority * the authority to be encoded * @param charset * the character encoding to encode to * @return the encoded authority * @since 5.0 */ public static String encodeAuthority(String authority, Charset charset) { return encode(authority, charset, HierarchicalUriComponents.Type.AUTHORITY); } /** * Encode the given URI user info with the given encoding. * * @param userInfo * the user info to be encoded * @param encoding * the character encoding to encode to * @return the encoded user info */ public static String encodeUserInfo(String userInfo, String encoding) { return encode(userInfo, encoding, HierarchicalUriComponents.Type.USER_INFO); } /** * Encode the given URI user info with the given encoding. * * @param userInfo * the user info to be encoded * @param charset * the character encoding to encode to * @return the encoded user info * @since 5.0 */ public static String encodeUserInfo(String userInfo, Charset charset) { return encode(userInfo, charset, HierarchicalUriComponents.Type.USER_INFO); } /** * Encode the given URI host with the given encoding. * * @param host * the host to be encoded * @param encoding * the character encoding to encode to * @return the encoded host */ public static String encodeHost(String host, String encoding) { return encode(host, encoding, HierarchicalUriComponents.Type.HOST_IPV4); } /** * Encode the given URI host with the given encoding. * * @param host * the host to be encoded * @param charset * the character encoding to encode to * @return the encoded host * @since 5.0 */ public static String encodeHost(String host, Charset charset) { return encode(host, charset, HierarchicalUriComponents.Type.HOST_IPV4); } /** * Encode the given URI port with the given encoding. * * @param port * the port to be encoded * @param encoding * the character encoding to encode to * @return the encoded port */ public static String encodePort(String port, String encoding) { return encode(port, encoding, HierarchicalUriComponents.Type.PORT); } /** * Encode the given URI port with the given encoding. * * @param port * the port to be encoded * @param charset * the character encoding to encode to * @return the encoded port * @since 5.0 */ public static String encodePort(String port, Charset charset) { return encode(port, charset, HierarchicalUriComponents.Type.PORT); } /** * Encode the given URI path with the given encoding. * * @param path * the path to be encoded * @param encoding * the character encoding to encode to * @return the encoded path */ public static String encodePath(String path, String encoding) { return encode(path, encoding, HierarchicalUriComponents.Type.PATH); } /** * Encode the given URI path with the given encoding. * * @param path * the path to be encoded * @param charset * the character encoding to encode to * @return the encoded path * @since 5.0 */ public static String encodePath(String path, Charset charset) { return encode(path, charset, HierarchicalUriComponents.Type.PATH); } /** * Encode the given URI path segment with the given encoding. * * @param segment * the segment to be encoded * @param encoding * the character encoding to encode to * @return the encoded segment */ public static String encodePathSegment(String segment, String encoding) { return encode(segment, encoding, HierarchicalUriComponents.Type.PATH_SEGMENT); } /** * Encode the given URI path segment with the given encoding. * * @param segment * the segment to be encoded * @param charset * the character encoding to encode to * @return the encoded segment * @since 5.0 */ public static String encodePathSegment(String segment, Charset charset) { return encode(segment, charset, HierarchicalUriComponents.Type.PATH_SEGMENT); } /** * Encode the given URI query with the given encoding. * * @param query * the query to be encoded * @param encoding * the character encoding to encode to * @return the encoded query */ public static String encodeQuery(String query, String encoding) { return encode(query, encoding, HierarchicalUriComponents.Type.QUERY); } /** * Encode the given URI query with the given encoding. * * @param query * the query to be encoded * @param charset * the character encoding to encode to * @return the encoded query * @since 5.0 */ public static String encodeQuery(String query, Charset charset) { return encode(query, charset, HierarchicalUriComponents.Type.QUERY); } /** * Encode the given URI query parameter with the given encoding. * * @param queryParam * the query parameter to be encoded * @param encoding * the character encoding to encode to * @return the encoded query parameter */ public static String encodeQueryParam(String queryParam, String encoding) { return encode(queryParam, encoding, HierarchicalUriComponents.Type.QUERY_PARAM); } /** * Encode the given URI query parameter with the given encoding. * * @param queryParam * the query parameter to be encoded * @param charset * the character encoding to encode to * @return the encoded query parameter * @since 5.0 */ public static String encodeQueryParam(String queryParam, Charset charset) { return encode(queryParam, charset, HierarchicalUriComponents.Type.QUERY_PARAM); } /** * Encode the query parameters from the given {@code MultiValueMap} with * UTF-8. *

* This can be used with * {@link UriComponentsBuilder#queryParams(MultiValueMap)} when building a * URI from an already encoded template. * *

	 * MultiValueMap<String, String> params = new LinkedMultiValueMap<>(2);
	 * // add to params...
	 *
	 * ServletUriComponentsBuilder.fromCurrentRequest().queryParams(UriUtils.encodeQueryParams(params)).build(true).toUriString();
	 * 
* * @param params * the parameters to encode * @return a new {@code MultiValueMap} with the encoded names and values * @since 5.2.3 */ public static MultiValueMap encodeQueryParams(MultiValueMap params) { Charset charset = StandardCharsets.UTF_8; MultiValueMap result = new LinkedMultiValueMap<>(params.size()); for (Map.Entry> entry : params.entrySet()) { for (String value : entry.getValue()) { result.add(encodeQueryParam(entry.getKey(), charset), encodeQueryParam(value, charset)); } } return result; } /** * Encode the given URI fragment with the given encoding. * * @param fragment * the fragment to be encoded * @param encoding * the character encoding to encode to * @return the encoded fragment */ public static String encodeFragment(String fragment, String encoding) { return encode(fragment, encoding, HierarchicalUriComponents.Type.FRAGMENT); } /** * Encode the given URI fragment with the given encoding. * * @param fragment * the fragment to be encoded * @param charset * the character encoding to encode to * @return the encoded fragment * @since 5.0 */ public static String encodeFragment(String fragment, Charset charset) { return encode(fragment, charset, HierarchicalUriComponents.Type.FRAGMENT); } /** * Variant of {@link #encode(String, Charset)} with a String charset. * * @param source * the String to be encoded * @param encoding * the character encoding to encode to * @return the encoded String */ public static String encode(String source, String encoding) { return encode(source, encoding, HierarchicalUriComponents.Type.URI); } /** * Encode all characters that are either illegal, or have any reserved * meaning, anywhere within a URI, as defined in * RFC 3986. This is * useful to ensure that the given String will be preserved as-is and will * not have any o impact on the structure or meaning of the URI. * * @param source * the String to be encoded * @param charset * the character encoding to encode to * @return the encoded String * @since 5.0 */ public static String encode(String source, Charset charset) { return encode(source, charset, HierarchicalUriComponents.Type.URI); } /** * Convenience method to apply {@link #encode(String, Charset)} to all given * URI variable values. * * @param uriVariables * the URI variable values to be encoded * @return the encoded String * @since 5.0 */ public static Map encodeUriVariables(Map uriVariables) { Map result = new LinkedHashMap<>(uriVariables.size()); uriVariables.forEach((key, value) -> { String stringValue = (value != null ? value.toString() : ""); result.put(key, encode(stringValue, StandardCharsets.UTF_8)); }); return result; } /** * Convenience method to apply {@link #encode(String, Charset)} to all given * URI variable values. * * @param uriVariables * the URI variable values to be encoded * @return the encoded String * @since 5.0 */ public static Object[] encodeUriVariables(Object... uriVariables) { return Arrays.stream(uriVariables).map(value -> { String stringValue = (value != null ? value.toString() : ""); return encode(stringValue, StandardCharsets.UTF_8); }).toArray(); } private static String encode(String scheme, String encoding, HierarchicalUriComponents.Type type) { return HierarchicalUriComponents.encodeUriComponent(scheme, encoding, type); } private static String encode(String scheme, Charset charset, HierarchicalUriComponents.Type type) { return HierarchicalUriComponents.encodeUriComponent(scheme, charset, type); } /** * Decode the given encoded URI component. *

* See {@link StringUtils#uriDecode(String, Charset)} for the decoding * rules. * * @param source * the encoded String * @param encoding * the character encoding to use * @return the decoded value * @throws IllegalArgumentException * when the given source contains invalid encoded sequences * @see StringUtils#uriDecode(String, Charset) * @see java.net.URLDecoder#decode(String, String) */ public static String decode(String source, String encoding) { return StringUtils2.uriDecode(source, Charset.forName(encoding)); } /** * Decode the given encoded URI component. *

* See {@link StringUtils#uriDecode(String, Charset)} for the decoding * rules. * * @param source * the encoded String * @param charset * the character encoding to use * @return the decoded value * @throws IllegalArgumentException * when the given source contains invalid encoded sequences * @since 5.0 * @see StringUtils#uriDecode(String, Charset) * @see java.net.URLDecoder#decode(String, String) */ public static String decode(String source, Charset charset) { return StringUtils2.uriDecode(source, charset); } /** * Extract the file extension from the given URI path. * * @param path * the URI path (e.g. "/products/index.html") * @return the extracted file extension (e.g. "html") * @since 4.3.2 */ @Nullable public static String extractFileExtension(String path) { int end = path.indexOf('?'); int fragmentIndex = path.indexOf('#'); if (fragmentIndex != -1 && (end == -1 || fragmentIndex < end)) { end = fragmentIndex; } if (end == -1) { end = path.length(); } int begin = path.lastIndexOf('/', end) + 1; int paramIndex = path.indexOf(';', begin); end = (paramIndex != -1 && paramIndex < end ? paramIndex : end); int extIndex = path.lastIndexOf('.', end); if (extIndex != -1 && extIndex > begin) { return path.substring(extIndex + 1, end); } return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy