zoukankan      html  css  js  c++  java
  • UriComponentsBuilder和UriComponents url编码

    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;
        }
    }
  • 相关阅读:
    Python开发环境Spyder介绍
    Python干货整理之数据结构篇
    通过Python爬虫按关键词抓取相关的新闻
    疫情后来场说走就走的旅行,Python制作一份可视化的旅行攻略
    详细介绍去一年在 PyPI 上下载次数最多的 Python 包
    Python错误与异常
    python爬虫爬取2020年中国大学排名
    微信史上最短的一行功能代码:拍一拍
    Python爬取某宝商品数据案例:100页的价格、购买人数等数据
    我的SAS菜鸟之路7
  • 原文地址:https://www.cnblogs.com/47Gamer/p/13226185.html
Copyright © 2011-2022 走看看