日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UriComponentsBuilder 拼接URL、解析URL

發(fā)布時間:2024/9/19 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UriComponentsBuilder 拼接URL、解析URL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

  • 關(guān)于URI參考這里。
  • springboot 2.1.1.RELEASE

UriComponentsBuilder

  • UriComponentsBuilder 是UriBuilder的實現(xiàn)。針對Servlet,還派生出來ServletUriComponentsBuilder。
  • 使用過UriComponentsBuilder 的都知道,很好用

快速來個示例

String url = UriComponentsBuilder.fromUriString("http://mydomain/api/getToken").queryParam("appid", "123").queryParam("appsecret", "secret123").build().encode().toString(); System.out.println(url);
  • 這段代碼可以得到:http://mydomain/api/getToken?appid=123&appsecret=secret123
  • 這段代碼實際做了幾件事:
  • 實例化 UriComponentsBuilder 。UriComponentsBuilder.fromUriString("http://mydomain/api/getToken")
  • 設(shè)置 UriComponentsBuilder 實例。.queryParam("appid", "123").queryParam("appsecret", "secret123")
  • 創(chuàng)建 UriComponents 實例。.build()
  • 設(shè)置 UriComponents 實例。.encode()
  • UriComponents 實例轉(zhuǎn)成字符串。.toString()

實例化 UriComponentsBuilder 的方法

UriComponentsBuilder 提供的實例化 UriComponentsBuilder 的方法

public static UriComponentsBuilder newInstance(); public static UriComponentsBuilder fromPath(String path); public static UriComponentsBuilder fromUri(URI uri); public static UriComponentsBuilder fromUriString(String uri); public static UriComponentsBuilder fromHttpUrl(String httpUrl); public static UriComponentsBuilder fromHttpRequest(HttpRequest request); public static UriComponentsBuilder fromOriginHeader(String origin);

ServletUriComponentsBuilder 提供的實例化 UriComponentsBuilder 的方法

public static ServletUriComponentsBuilder fromContextPath(HttpServletRequest); public static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest); public static ServletUriComponentsBuilder fromRequest(HttpServletRequest); public static ServletUriComponentsBuilder fromCurrentContextPath(); public static ServletUriComponentsBuilder fromCurrentServletMapping(); public static ServletUriComponentsBuilder fromCurrentRequest();

設(shè)置 UriComponentsBuilder 實例

賦值
.queryParam("appid", "123")
重復(fù)賦值
.queryParam("appid", "123") .queryParam("appid", "234")
  • appid 會變?yōu)閇“123”, “234”]
替換
.queryParam("appid", "123") .replaceQueryParam("appid", "234")
  • appid 變?yōu)?34
路徑
.path("a") .path("b") .path("c")
  • xxx/a/b/c
替換路徑
.path("a") .path("b") .path("c") .replacePath("d")
  • xxx/d
更多

略。

關(guān)于urlencode

前面示例中.build() 中得到的是 UriComponents 派生類(HierarchicalUriComponents)的實例。

HierarchicalUriComponents 類的實例在.encode()時,使用HierarchicalUriComponents.encodeUriComponent() 方法進行 url 編碼。其編碼方式與java.net.URLEncoder的實現(xiàn)不同。

總結(jié)一下(代碼參考測試代碼1):

代碼結(jié)果特征遵循協(xié)議
URLEncoder.encode(“1 + 2 = 3”, “utf-8”);1+%2B+2+%3D+3空格轉(zhuǎn)義成+;+轉(zhuǎn)義成%2BW3C標(biāo)準(zhǔn)規(guī)定
HierarchicalUriComponents.encodeUriComponent(“1 + 2 = 3”, “utf-8”,Type.QUERY_PARAM);1%20+%202%20%3D%203空格轉(zhuǎn)義成%20;+不變RFC 3986

用哪個對呢?都對!!!但,要看提供服務(wù)的應(yīng)用支持哪個。我的建議是,都試試,哪個能用用哪個。

如何讓 URLEncoder 支持 空格轉(zhuǎn)義成%20;+不變呢?

參考這里:https://blog.csdn.net/qq_43566496/article/details/84935364

如何讓 HierarchicalUriComponents 支持 空格轉(zhuǎn)義成+;+轉(zhuǎn)義成%2B呢?

方法1
String url = UriComponentsBuilder.fromUriString("http://mydomain/api/getToken").queryParam("appid", "123").queryParam("appsecret", "secret123").queryParam("q", URLEncoder.encode("1 + 2 = 3")).build(true).encode().toString(); System.out.println(url);
  • .build(true) 告訴 UriComponents 我已經(jīng)做過uri編碼了,你就不要再做uri編碼了。
方法2
String url = UriComponentsBuilder.fromUriString("http://mydomain/api/getToken").queryParam("appid", "123").queryParam("appsecret", "secret123").queryParam("q", URLEncoder.encode("1 + 2 = 3")).build().toString(); System.out.println(url);
  • 去掉.encode() , UriComponents 就不要再做uri編碼了。

spring 提供的支持 RFC 2396、RFC 3986 的類: UriUtils

https://docs.spring.io/spring-framework/docs/3.0.x/javadoc-api/org/springframework/web/util/UriUtils.html

測試代碼1

import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.Charset;import org.springframework.util.Assert; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils;public class Test {public static void main(String[] args) throws UnsupportedEncodingException {System.out.println(URLEncoder.encode("1 + 2 = 3", "utf-8"));System.out.println(encodeUriComponent("1 + 2 = 3", Charset.forName("utf-8"), Type.QUERY_PARAM));}/*HierarchicalUriComponents.encodeUriComponent() 方法的高仿實現(xiàn)*/static String encodeUriComponent(String source, Charset charset, Type type) {if (!StringUtils.hasLength(source)) {return source;}Assert.notNull(charset, "Charset must not be null");Assert.notNull(type, "Type must not be null");byte[] bytes = source.getBytes(charset);boolean original = true;for (byte b : bytes) {if (!type.isAllowed(b)) {original = false;break;}}if (original) {return source;}ByteArrayOutputStream baos = new ByteArrayOutputStream(bytes.length);for (byte b : bytes) {if (type.isAllowed(b)) {baos.write(b);}else {baos.write('%');char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16));char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16));baos.write(hex1);baos.write(hex2);}}return StreamUtils.copyToString(baos, charset);}enum Type {QUERY {@Overridepublic boolean isAllowed(int c) {return isPchar(c) || '/' == c || '?' == c;}},QUERY_PARAM {@Overridepublic boolean isAllowed(int c) {if ('=' == c || '&' == c) {return false;}else {return isPchar(c) || '/' == c || '?' == c;}}};/*** Indicates whether the given character is allowed in this URI component.* @return {@code true} if the character is allowed; {@code false} otherwise*/public abstract boolean isAllowed(int c);/*** Indicates whether the given character is in the {@code ALPHA} set.* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>*/protected boolean isAlpha(int c) {return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');}/*** Indicates whether the given character is in the {@code DIGIT} set.* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>*/protected boolean isDigit(int c) {return (c >= '0' && c <= '9');}/*** Indicates whether the given character is in the {@code sub-delims} set.* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>*/protected boolean isSubDelimiter(int c) {return ('!' == c || '$' == c || '&' == c || '\'' == c || '(' == c || ')' == c || '*' == c || '+' == c ||',' == c || ';' == c || '=' == c);}/*** Indicates whether the given character is in the {@code unreserved} set.* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>*/protected boolean isUnreserved(int c) {return (isAlpha(c) || isDigit(c) || '-' == c || '.' == c || '_' == c || '~' == c);}/*** Indicates whether the given character is in the {@code pchar} set.* @see <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986, appendix A</a>*/protected boolean isPchar(int c) {return (isUnreserved(c) || isSubDelimiter(c) || ':' == c || '@' == c);}} } String url = UriComponentsBuilder.fromUriString("http://api.fanyi.baidu.com/api/trans/vip/translate").queryParam("appid", appid).queryParam("q", encode(query)).queryParam("from", from).queryParam("to", to).queryParam("salt", salt).queryParam("sign", sign).build(true).encode().toString();

參考

https://www.cnblogs.com/zhengxl5566/p/10783422.html
https://www.cnblogs.com/zhengxl5566/p/13492602.html
https://www.cnblogs.com/siqi/p/10070926.html

總結(jié)

以上是生活随笔為你收集整理的UriComponentsBuilder 拼接URL、解析URL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。