SpringMVC 教程 - URI 链接
原文链接:https://www.codemore.top/cates/Backend/post/2018-04-22/spring-mvc-uri-links
这一节主要讲的是Spring Framework组成URI的各种选项。
UriComponents
UriComponents
和java.net.URI
类似。但是UriComponents
有一个专用的UriComponentsBuilder
来构建,并且支持模版变量。例如
String uriTemplate = "http://example.com/hotels/{hotel}";
UriComponents uriComponents = UriComponentsBuilder.fromUriString(uriTemplate) 1
.queryParam("q", "{q}") 2
.build(); 3
URI uri = uriComponents.expand("Westin", "123").encode().toUri(); 4
解释:
- 包含URI模版的静态工厂方法
- 添加或者替代URI组件
- 构建
UriComponents
- 扩展URI变量,编码获取URI变量
上述步骤合起来可以如下表示:
String uriTemplate = "http://example.com/hotels/{hotel}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate)
.queryParam("q", "{q}")
.buildAndExpand("Westin", "123")
.encode()
.toUri();
UriBuilder
UriComponentsBuilder
是UriBuilder
的子类。UriBuilderFactory
和UriBuilder
合在一起提供了通过URI模版获取URI
的一套可插拔的机制,同样也提供了一种共享公共属性,基础URI,编码策略等的方式。 RestTemplate
和WebClient
都可以通过UriBuilderFactory
配置。默认实现依赖于内部的UriComponentsBuilder
,同时提供选项配置基础URI,编码策略等。 RestTemplate
方式:
String baseUrl = "http://example.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(factory);
WebClient
方式:
String baseUrl = "http://exaplme.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl);
// Configure the UriBuilderFactory..
WebClient client = WebClient.builder().uriBuilderFactory(factory).build();
// Or use shortcut on builder..
WebClient client = WebClient.builder().baseUrl(baseUrl).build();
// Or use create shortcut...
WebClient client = WebClient.create(baseUrl);
同样像直接使用UriComponentsBuilder
一样,也可以直接使用DefaultUriBuilderFactory
。唯一的区别是DefaultUriBuilderFactory
是无状态的,并且可以重用。例如:
String baseUrl = "http://example.com";
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory(baseUrl);
URI uri = uriBuilderFactory.uriString("/hotels/{hotel}")
.queryParam("q", "{q}")
.build("Westin", "123"); // encoding strategy applied..
URI 编码
在UriComponets
中编码URI的步骤如下:
- 扩展URI变量
- 每个URI组件(path,query等)都单独编码
编码规则如下:对所有非法字符应用百分号编码方式,包括非ASCII的字符和在RFC 3986中定义的非法字符。 上述编码规则并没有对有保留意义的字符编码,只是对URI组件中的非法字符尽心编码,如果想要对其编码,可以修改编码策略使其全部编码。 当使用 DefaultUriBuilderFactory
(在WebClient
,RestTemplate
中使用或者直接使用)时可以如下选择编码方式:
String baseUrl = "http://example.com";
DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(baseUrl)
factory.setEncodingMode(EncodingMode.VALUES_ONLY);
Servlet 请求
可以使用ServletUriComponentsBuilder
来创建相对于当前请求的URI,例如:
HttpServletRequest request = ...
// Re-uses host, scheme, port, path and query string...
ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request)
.replaceQueryParam("accountId", "{id}").build()
.expand("123")
.encode();
创建相对于当前context的URI
// Re-uses host, port and context path...
ServletUriComponentsBuilder ucb =
ServletUriCompontentsBuilder.fromContextPath(request)
.path("/accounts").build();
创建相对于Servlet(例如:/main/*)的URI
// Re-uses host, port, context path, and Servlet prefix...
ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromServletMapping(request)
.path("/accounts").build()
controller的链接
Spring MVC使用MvcUriComponentsBuilder
为controller创建链接,例如由如下一个controller:
@Controller
@RequestMapping("/hotels/{hotel}")
public class BookingController {
@GetMapping("/bookings/{booking}")
public String getBooking(@PathVariable Long booking) {
// ...
}
}
可以根据名字来生成一个链接:
UriComponents uriComponents = MvcUriComponentsBuilder
.fromMethodName(BookingController.class, "getBooking", 21).buildAndExpand(42);
URI uri = uriComponents.encode().toUri();
在上面这个例子中,直接提供了函数的参数值,21被赋值给路径变量,42赋值给从类的@RequestMapping
继承过来的查询参数{hotel}
。 MvcUriComponentsBuilder
的另一个用处是可以mock一个测试,例如:
UriComponents uriComponents = MvcUriComponentsBuilder
.fromMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);
URI uri = uriComponents.encode().toUri();
上面的例子大多数情况下运行良好,但是也有不足,例如:可能会在request上下文外创建uri,或者是需要插入一个路径前缀(比如测试的时候通过前缀测试,但是正式上线后直接是根(/))。对于这种情况可以使用静态函数fromXxx
这种进行处理:
UriComponentsBuilder base = ServletUriComponentsBuilder.fromCurrentContextPath().path("/en");
MvcUriComponentsBuilder builder = MvcUriComponentsBuilder.relativeTo(base);
builder.withMethodCall(on(BookingController.class).getBooking(21)).buildAndExpand(42);
URI uri = uriComponents.encode().toUri();
视图中的链接
可以通过MvcUriComponentsBuilder
的fromMappingName
在视图(例如:JSP,Thymleaf,FreeMarker等)中构建指向controller的链接。 每个@RequestMapping
的方法都会有一个名字,这个名字基于controller类名的大些字母加上‘#’号再加上方法名构成,例如,FooController
类中的getFoo
方法的名字就是FC#getFoo
。当然这个可以通过修改HandlerMethodMappingNamingStrategy
来定制其名字。默认策略同样也会去查找@RequestMapping
中设置名字的属性,如果提供了,则会使用其设置的名字。 Spring JSP的tag库提供了一个mvcUrl
的方法,这个可以用来构建指向controller的方法。例如有如下controller:
@RequestMapping("/people/{id}/addresses")
public class PersonAddressController {
@RequestMapping("/{country}")
public HttpEntity getAddress(@PathVariable String country) { ... }
}
JSP中可以如下来构建指向其URI
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
...
<a href="${s:mvcUrl('PAC#getAddress').arg(0,'US').buildAndExpand('123')}">Get Address</a>
SpringMVC 教程 - URI 链接的更多相关文章
- SpringMVC教程3
SpringMVC教程2 一.文件上传 1.引入相关jar包 maven坐标 <!-- fileUpload 解析上传的文件用到的jar --> <dependency> &l ...
- SpringMVC教程1
一.SpringMVC介绍 1.MVC介绍 ==模型-视图-控制器(MVC== 是一个众所周知的以设计界面应用程序为基础的设计模式.它主要通过分离模型.视图及控制器在应用程序中的角色将业务逻辑从界面中 ...
- Java系列教程-SpringMVC教程
SpringMVC教程 1.SpringMVC概述 1.回顾MVC 1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务 ...
- SpringMVC教程4
SpringMVC教程3 一.数据回写 数据回写:在做数据更新的时候服务端查询的数据自动填充到表单中. 1.1默认方式 通过前面讲解的 Map Mode ModelMap绑定数据 @RequestMa ...
- SpringMVC教程2
接上篇文章-SpringMVC教程1 五.基本操作 1.响应请求的方式 1.1ModeAndView /** * 查询方法 * @return */ @RequestMapping("/qu ...
- SpringMvc Controller请求链接忽略大小写(包含拦截器)及@ResponseBody返回String中文乱码处理
SpringMvc Controller请求链接忽略大小写(包含拦截器)及@ResponseBody返回String中文乱码处理... @RequestMapping(value = "/t ...
- SpringMVC 解析(五)URI链接处理
URI在网络请求中必不可少,Spring提供了一些工具类用于解析或者生成URL,比如根据参数生成GET的URL等.本文会对Spring MVC中的URI工具进行介绍,本文主要参考Spring官方文档. ...
- SpringMVC 教程 - Handler Method
原文链接:https://www.codemore.top/cates/Backend/post/2018-04-21/spring-mvc-handler-methods 由注解@RequestMa ...
- JMeter 教程汇总链接
http://www.360doc.com/content/14/0318/23/16361380_361732630.shtml 可以作为入门系列教程. 尽管网页也给出了视频链接,但是我不建议看视频 ...
随机推荐
- Win10下, TortoiseGit安装及配合Gitee使用完整版
Windows10下, TortoiseGit的安装及使用, 并配合Gitee码云使用! 1) 安装TortoiseGit 官网, 32位, 64位, 自选 https://tortoisegit.o ...
- AngularJS1.X学习笔记7-过滤器
最近参加笔试被虐成狗了,感觉自己的算法太弱了.但是还是先花点事件将这个AngularJS学习完.今天学习filter 一.内置过滤器 (1)过滤单个数据值 <!DOCTYPE html> ...
- Struts2 之值栈
值栈(ValueStack) http://www.cnblogs.com/bgzyy/p/8639893.html 这是我的有关 struts2 的第一篇文章,对于里面我们说到的一个 struts2 ...
- 【iOS】 含tableView的ViewController基类的实现
上篇博客写了ViewController的基类的实现,这篇博客主要写在BaseViewController的基础上实现一个含tableView控件的基类的实现,主要给包含tableView的页面来继承 ...
- python全栈开发-hashlib模块(数据加密)、suprocess模块、xml模块
一.hashlib模块 1.什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 ...
- Linux下wget获取ftp下目录下文件
如果某个目录下有一个文件可以使用ftp命令: get xxx 如果是某个目录下有多个文件(且不需要获取目录下子文件夹下的内容): mget * 如果是某个目录下有子目录希望获取所有子目录: wget ...
- Array方面Js底层代码学习记录
一..clear() →Array function clear() { this.length = 0; return this; } 返回清除item的空数组. 例子: var fruits = ...
- 使用Vertx构建微服务
Vertx Vert.x is a tool-kit for building reactive applications on the JVM.(Vertx是运行在JVM上用来构建reactive ...
- chm 转 txt
CHM格式转TXT,如果在Windows下可使用命令行实现,为叙述方便,以笔者机器为例,在 E:\11 文件夹下有 123.chm 这个文件,按如下操作将这个 CHM 转成 TXT 文件. 第一步: ...
- 解决-Django使用filter过滤时间,无法获取月份的问题
django中的filter日期查询属性有:year.month.day.week_day.hour.minute.second 但是但我在使用过滤查询是却总是无法过滤出月份,各种查资料,最后才发现是 ...