Spring MVC 提供了一种机制,可以构造和编码URI -- 使用UriComponentsBuilder和UriComponents。
功能相当于 urlencode()函数,对url进行编码, 但同时还支持变量替换。
UriComponents uriComponents = UriComponentsBuilder.fromUriString( "http://example.com/hotels/{hotel}/bookings/{booking}").build(); URI uri = uriComponents.expand("42", "21").encode().toUri();
嗯,expand()是用于替换所有的模板变量,encode默认使用UTF8编码。
注意,UriComponents是不可变的,expand()和encode()都是返回新的实例。
你还可以这样做:
UriComponents uriComponents = UriComponentsBuilder.newInstance() .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build() .expand("42", "21") .encode();
在Servlet环境中,使用子类ServletUriComponentsBuilder提供的静态工厂方法可以从一个Servlet request中获取有用的URI信息:
HttpServletRequest request = ... // Re-use host, scheme, port, path and query string // Replace the "accountId" query param ServletUriComponentsBuilder ucb = ServletUriComponentsBuilder.fromRequest(request) .replaceQueryParam("accountId", "{id}").build() .expand("123") .encode();
以下是应用(你可以直接在项目里使用):
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import javax.annotation.PostConstruct;
import java.net.URI;
import java.util.Map;
import java.util.Set;
/** * @author 47Gamer * @date: 2019/2/27 16:41 * @Description: rest工具类 */ @Component public class RestUtil { private static final Logger LOGGER = LoggerFactory.getLogger(RestUtil.class); public static final String SCHEME_HTTPS = "https"; public static final String SCHEME_HTTP = "http"; private static RestTemplate template; @Autowired private RestTemplate restTemplateValue; @PostConstruct public void init() { template = restTemplateValue; } /** * 发送HTTPS请求 * * @param path path * @param method HTTP请求类型 * @param body body * @param query URL参数 * @param headers header * @param host ip * @param port 端口 * @return */ public static String executeByHttps(String path, HttpMethod method, Object body, Object query, Map<String, String> headers, String host, int port) { return execute(path, method, body, query, headers, host, port, SCHEME_HTTPS); } /** * 发送HTTP请求 * * @param path path * @param method HTTP请求类型 * @param body body * @param query URL参数 * @param headers header * @param host ip * @param port 端口 * @return */ public static String executeByHttp(String path, HttpMethod method, Object body, Object query, Map<String, String> headers, String host, int port) { return execute(path, method, body, query, headers, host, port, SCHEME_HTTP); } /** * 发送请求,返回body * * @param path path * @param method HTTP请求类型 * @param body body * @param query URL参数 * @param headers header * @param host ip * @param port 端口 * @param scheme http协议类型 * @return */ public static String execute(String path, HttpMethod method, Object body, Object query, Map<String, String> headers, String host, int port, String scheme) { String result = ""; ResponseEntity<String> responseEntity = doExecute(path, method, body, query, headers, host, port, scheme); if (null != responseEntity) { if (StringUtils.startsWith(responseEntity.getStatusCodeValue() + "", "2")) { result = responseEntity.getBody() == null ? "" : responseEntity.getBody(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("response", result); } } else { LOGGER.error("request error, error message : ", responseEntity.getBody()); throw new RuntimeException("request error, error message : " + responseEntity.getBody()); } } return result; } /** * 发送请求 * * @param path path * @param method HTTP请求类型 * @param body body * @param query URL参数 * @param headers header * @param host ip * @param port 端口 * @param scheme http协议类型 * @return */ public static ResponseEntity<String> doExecute(String path, HttpMethod method, Object body, Object query, Map<String, String> headers, String host, int port, String scheme) { ResponseEntity<String> responseEntity = null; URI uri = null; try { UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance(); uriComponentsBuilder.scheme(scheme).host(host).port(port).path(path); convertQueryParam(query, uriComponentsBuilder); uri = uriComponentsBuilder.build().encode().toUri(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("URI={}, request body={}", uri.toString(), JSON.toJSONString(body, SerializerFeature.DisableCircularReferenceDetect)); } HttpHeaders httpHeaders = setHeaders(headers); HttpEntity<Object> httpEntity = new HttpEntity<Object>(body, httpHeaders); responseEntity = template.exchange(uri, method, httpEntity, String.class); } catch (Exception e) { LOGGER.error("URI={}, request body={}", uri, JSON.toJSONString(body, SerializerFeature.DisableCircularReferenceDetect)); LOGGER.error("execute http request error: ", e); throw new RuntimeException("execute http request error: " + e.getMessage()); } return responseEntity; } private static void convertQueryParam(Object query, UriComponentsBuilder uriComponentsBuilder) { if (query == null) { return; } if (query instanceof Map) { Set<Map.Entry<String, Object>> entries = ((Map) query).entrySet(); for (Map.Entry entry : entries) { uriComponentsBuilder.queryParam((String) entry.getKey(), entry.getValue()); } } else if (query instanceof String) { uriComponentsBuilder.query((String) query); } } private static HttpHeaders setHeaders(Map<String, String> headers) { HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("Content-Type", "application/json; charset=UTF-8"); httpHeaders.add("Accept-Charset", "UTF-8"); httpHeaders.add("Accept", "application/json; charset=UTF-8"); if (headers != null) { httpHeaders.setAll(headers); } return httpHeaders; } }