SpringBoot - UriComponentsBuilder 拼装 url

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

Maven包:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.14.RELEASE</version>
</dependency>

实例化静态方法:

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<String, String> queryParams = new LinkedMultiValueMap<String, String>();

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

### 使用 MyBatis 动态拼装 SQL 语句的最佳实践 在 Spring Boot 中集成 MyBatis 进行动态 SQL 构建是一项常见需求,这有助于提高查询灵活性并减少硬编码。通过合理利用 MyBatis 提供的功能可以实现高效且易于维护的动态 SQL。 #### 利用 XML 配置文件构建复杂条件查询 对于较为复杂的业务逻辑,推荐采用 XML 方式的 Mapper 文件来定义 SQL 映射规则。这种方式允许更直观地编写带有多种分支判断的 SQL 片段,并能方便地管理较长的 SQL 表达式[^1]。 ```xml <select id="findUsersByConditions" parameterType="map" resultType="User"> SELECT * FROM users WHERE 1=1 <if test="name != null and name != '' "> AND name LIKE CONCAT('%', #{name}, '%') </if> <if test="age != null"> AND age = #{age} </if> </select> ``` 上述例子展示了如何基于传入参数的存在与否有条件地加入不同的过滤子句到最终执行的 SQL 命令中去。 #### 应用注解方式简化简单场景下的映射关系 当面对相对简单的 CRUD 操作或是小型项目时,则可以选择更为简洁明了的方式——即直接在接口方法上添加 `@Select`, `@Insert` 等注解完成基本功能开发。不过需要注意的是,在涉及大量动态变化的情况下仍建议优先考虑XML配置方案以保持良好的可读性和扩展性. ```java public interface UserMapper { @Select("<script>" + "SELECT * FROM users WHERE 1=1 " + "<if test='name != null'>AND name=#{name}</if> " + "</script>") List<User> selectByName(@Param("name") String name); } ``` 这里使用 `<script>` 标签包裹整个 SQL 字符串使得其中能够嵌套 MyBatis 的标签语法用于处理变量替换等问题。 #### 结合 LambdaQueryWrapper 或 QueryWrapper 类增强表达力 MyBatis Plus 扩展库提供了诸如 `LambdaQueryWrapper` 和 `QueryWrapper` 这样的工具类帮助开发者更加优雅地构造查询条件对象。这些封装后的 API 不仅让代码看起来更加现代化同时也降低了手写错误的可能性. ```java // 创建一个带有多重条件组合的 Wrapper 对象实例 LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>(); wrapper.like(User::getName, userName).eq(User::getAge, userAge); // 调用 mapper 方法传递该包装器作为参数即可自动解析成对应的 SQL 并执行相应操作 List<User> userList = userMapper.selectList(wrapper); ``` 这种编程风格特别适合那些需要频繁调整筛选标准的应用程序部分,因为它既保留了一定程度上的声明性质又不失灵活性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Demon-HY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值