SpringBoot - UriComponentsBuilder 拼装 url

UriComponentsBuilder 是 Spring 提供的一个 UriComponents 类的构建类,通过他可以方便的构建我们请求的 url

Maven包:


    org.springframework
    spring-web
    4.3.14.RELEASE

实例化静态方法:

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);

UriComponentsBuilder 提供了7中实例化的方法,看方法名就知道大概的用法了,里面几个方法做了一些其他的处理

fromUriString(String uri)

这个方法按照字面一些,里面传入的应该是:http://www.baidu.com/ 这样的字符串,打开源码我们发现,里面其实传入的是一个完整的GET请求链接:[协议]://[域名]:[端口]/[路径]?[参数]

    public static UriComponentsBuilder fromUriString(String uri) {
		Assert.notNull(uri, "URI must not be null");
		Matcher matcher = URI_PATTERN.matcher(uri);
		if (matcher.matches()) {
			UriComponentsBuilder builder = new UriComponentsBuilder();
			String scheme = matcher.group(2);
			String userInfo = matcher.group(5);
			String host = matcher.group(6);
			String port = matcher.group(8);
			String path = matcher.group(9);
			String query = matcher.group(11);
			String fragment = matcher.group(13);
			boolean opaque = false;
			if (StringUtils.hasLength(scheme)) {
				String rest = uri.substring(scheme.length());
				if (!rest.startsWith(":/")) {
					opaque = true;
				}
			}
			builder.scheme(scheme);
			if (opaque) {
				String ssp = uri.substring(scheme.length()).substring(1);
				if (StringUtils.hasLength(fragment)) {
					ssp = ssp.substring(0, ssp.length() - (fragment.length() + 1));
				}
				builder.schemeSpecificPart(ssp);
			}
			else {
				builder.userInfo(userInfo);
				builder.host(host);
				if (StringUtils.hasLength(port)) {
					builder.port(port);
				}
				builder.path(path);
				builder.query(query);
			}
			if (StringUtils.hasText(fragment)) {
				builder.fragment(fragment);
			}
			return builder;
		}
		else {
			throw new IllegalArgumentException("[" + uri + "] is not a valid URI");
		}
	}

并且他里面是通过正则去匹配的,这样你可以直接通过这个方法就完成一个url的拼装,后面的参数是可以省略的,这个方法的应用场景:当你拿到一个url,想修改其中某个部分的时候使用:

    public static void main(String[] args) {
        // 添加参数: http://www.test.com/test?query1=1&query2=2
        System.out.println(UriComponentsBuilder.fromUriString("http://www.test.com/test?query1=1")
                .queryParam("query2", 2)
                .build().toString());

        // 更换域名: http://www.test2.com/test?query1=1
        System.out.println(UriComponentsBuilder.fromUriString("http://www.test.com/test?query1=1")
                .host("www.test2.com")
                .build().toString());
    }

fromHttpUrl(String httpUrl)

这个方法和上面方法的用法基本是一样的

fromOriginHeader(String origin)

origin 里面放的是跨域访问的域名地址,比如 www.a.com 访问 www.b.com会形成跨域,这个时候访问 www.b.com 的时候,

请求头里会携带 origin:www.a.com, b服务需要通过这个来判断是否允许a服务跨域访问.

fromOriginHeader()方法可以获取到协议,域名和端口,个人觉得这个方法没什么卵用

主要属性

// 协议: http/https
private String scheme;
// 协议特定部分,用来处理一些特殊协议,http协议用不到
private String ssp;
// 还没搞懂
private String userInfo;
// 域名
private String host;
// 端口
private String port;
// path 路径
private CompositePathComponentBuilder pathBuilder;
// 参数
private final MultiValueMap queryParams = new LinkedMultiValueMap();

private String fragment;

示例

构建一个完整的url

UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .scheme("http")
        .host("www.test2.com")
        .path("/test")
        .queryParam("query", "a")
        .build();

构建编码的 url

UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .scheme("http")
        .host("www.test2.com")
        .path("/test")
        .queryParam("query", "a")
        .build().encode("UTF-8");

模板构建 url

UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .scheme("http")
        .host("www.test2.com")
        .path("/{template}")
        .queryParam("query", "a")
        .build().expand("test");
System.out.println(uriComponents.toString()); // http://www.test2.com/test?query=a

expand 有多个实现,支持传入可变参数和Map

你可能感兴趣的:(SpringBoot,Java)