Android Url的一些常见处置处罚

手机游戏开发者 2024-8-31 01:34:19 197 0 来自 中国
一样平常开发的时间,会碰到各种各样的Url.这里就总结一些常见的Url碰到的一些题目,以及对应的处置处罚方式
常见题目


  • 参数题目
  • 重定向题目
  • Url长度题目
  • Url通报过程中编码题目
1.Url 参数处置处罚

1.1 获取Url 指定参数的值
/**     * 获取Url的原来参数值     */    fun getQueryParameterValue(url: String, key: String): String? {        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(key)) return url        var uri = Uri.parse(url)        if (uri.isOpaque()) {            return url        }        //利用Map的唯一性拼接参数        var parameterMap = getParameterMap(url)        return parameterMap.get(key)    }    /**     *  获取Url参数的值(Decode之后的)     *     *  getQueryParameter()  方法是默认Decode的     *     */    fun getQueryParameterDecodeValue(url: String, key: String): String? {        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(key)) return ""        var uri = Uri.parse(url)        if (uri.isOpaque()) {            return ""        } else {            return Uri.parse(url).getQueryParameter(key)        }    }  /**     * 把url 的参数转为Map存储     */    private fun getParameterMap(        url: String    ): HashMap<String, String> {        var map: HashMap<String, String> = HashMap<String, String>()        // 参数名字的列表        var parameter = Uri.parse(url).queryParameterNames        parameter.forEach {            if (getQueryParameterDecodeValue(url, it) != null)                map.put(it, getQueryParameterDecodeValue(url, it)!!)        }        return map    }1.2 添加和删除指定参数
/**     * 删除Encode 的参数     */    fun deleteQueryParameterDecodeValue(url: String, key: String): String {        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(key)) return url        var uri = Uri.parse(url)        if (uri.isOpaque()) {            return url        }        if (!url.contains("?")) {            url + "?"        }        var urlStart = url.split("?").get(0)        //利用Map的唯一性拼接参数        var parameterMap = getParameterMap(url)        //利用map的唯一性 存储大概更新值        if (parameterMap.containsKey(key)){            parameterMap.remove(key)        }        //参数的map        var appendUrl = appendMapParameter(parameterMap)        var division = "?"        return "$urlStart$division$appendUrl"    }   /**     * 添加 Encode 的参数     */    fun addQueryParameterDecodeValue(url: String, key: String, value: String): String {        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(key)) return url        var uri = Uri.parse(url)        if (uri.isOpaque()) {            return url        }        if (!url.contains("?")) {            url + "?"        }        var urlStart = url.split("?").get(0)        //利用Map的唯一性拼接参数        var parameterMap = getParameterMap(url)        //利用map的唯一性 存储大概更新值        parameterMap.put(key, Uri.encode(value))        //参数的map        var appendUrl = appendMapParameter(parameterMap)        var division = "?"        return "$urlStart$division$appendUrl"    } /**     * url 添加参数     */    fun addQueryParameterValue(url: String, key: String, value: String): String {        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(key)) return url        var uri = Uri.parse(url)        if (uri.isOpaque()) {            return url        }        if (url.contains("#")) {            url.replace("#", "%23")        }        if (!url.contains("?")) {            url + "?"        }        var urlStart = url.split("?").get(0)        //利用Map的唯一性拼接参数        var parameterMap = getParameterMap(url)        //利用map的唯一性 存储大概更新值        parameterMap.put(key, value)        //参数的map        var appendUrl = appendMapParameter(parameterMap)        var division = "?"        return "$urlStart$division$appendUrl"    }/**     * map 拼接成字符串     */    private fun appendMapParameter(parameterMap: HashMap<String, String>): String {        var stringBuilder = StringBuilder()        parameterMap.keys.forEach {            stringBuilder.append(it).append("=").append(parameterMap.get(it)).append("&")        }        if (stringBuilder.length > 0) {            stringBuilder.deleteCharAt(stringBuilder.length - 1)        }        return stringBuilder.toString()    }    /**     * 把url 的参数转为Map存储     */    private fun getParameterMap(        url: String    ): HashMap<String, String> {        var map: HashMap<String, String> = HashMap<String, String>()        // 参数名字的列表        var parameter = Uri.parse(url).queryParameterNames        parameter.forEach {            if (getQueryParameterDecodeValue(url, it) != null)                map.put(it, getQueryParameterDecodeValue(url, it)!!)        }        return map    }2.获取重定向地点的真实地点

package com.wu.base.util;import android.text.TextUtils;import java.io.IOException;import java.net.HttpURLConnection;import java.net.URLDecoder;import java.net.URLEncoder;import java.util.concurrent.TimeUnit;import io.reactivex.Observable;import io.reactivex.ObservableOnSubscribe;import io.reactivex.ObservableSource;import io.reactivex.Observer;import io.reactivex.android.schedulers.AndroidSchedulers;import io.reactivex.disposables.Disposable;import io.reactivex.functions.Function;import io.reactivex.schedulers.Schedulers;import okhttp3.Call;import okhttp3.Callback;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;/** * @author wkq * @date 2022年07月22日 16:15 * @des 重定向Url处置处罚工具 */public class UrlRedirectUrlUtil {    //是否Encode    private static boolean isEncode = false;    private static Disposable callDisposable;    //获取重定向后的真实地点    public static String getRedirectUrl(String path) {        boolean isEncode = false;        if (TextUtils.isEmpty(path)) {            return "";        }        if (findEnd(path)) {            return path;        }        if (isShortUrl(path))            return path;        try {            if (path.contains("#")) {                path = path.replace("#", URLEncoder.encode("#"));                isEncode = true;            }            OkHttpClient mOkHttpClient = new OkHttpClient();            Request request = new Request.Builder()                    .addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")                    .addHeader("Accept-Encoding", "gzip, deflate, br")                    .addHeader("Accept-Language", "zh-CN,zh;q=0.9")                    .addHeader("Connection", "keep-alive")                    .addHeader("User-Agent", "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36")                    .url(path)                    .build();            Call mCall = mOkHttpClient.newCall(request);            Response response = mCall.execute();            String backUrl = response.header("Location");            if (response.code() != HttpURLConnection.HTTP_MOVED_TEMP && response.code() != HttpURLConnection.HTTP_MOVED_PERM) {                String requestPath = response.request().url().toString();                if (isEncode) {                    requestPath = requestPath.replace("%23", URLDecoder.decode("%23"));                    isEncode = false;                }                return requestPath;            } else {                return getRedirectUrl(backUrl);            }        } catch (Exception e) {            e.printStackTrace();            return path;        }    }    //处置处罚重定向的Url    public static void getRedirectUrl(String url, ResponseCallBack callBack) {        if (callBack == null) return;        //取消上一个哀求        cancelRequest();        if (TextUtils.isEmpty(url)) {            callBack.getRedirectFail();            return;        }        if (findEnd(url)) {            callBack.getRedirectSuccess(url);            return;        }        if (isShortUrl(url)) {            callBack.getRedirectSuccess(url);            return;        }        callDisposable = Observable                .create((ObservableOnSubscribe<String>) emitter -> {                    if (url.contains("#")) {                        isEncode = true;                        emitter.onNext(url.replace("#", URLEncoder.encode("#")));                    } else {                        emitter.onNext(url);                    }                    emitter.onComplete();                })                .flatMap((Function<String, ObservableSource<String>>) s -> new Observable<String>() {                    @Override                    protected void subscribeActual(Observer<? super String> observer) {                        Request.Builder builder = new Request.Builder();                        builder.header("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");                        builder.header("Accept-Encoding", "gzip, deflate, br");                        builder.header("Accept-Language", "zh-CN,zh;q=0.9");                        builder.header("Connection", "keep-alive");                        builder.header("User-Agent", "Mozilla/5.0 (Linux; Android 5.0; AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Mobile Safari/537.36");                        Request request = builder.url(s).get().build();                        OkHttpClient client = new OkHttpClient()                                .newBuilder()                                .followRedirects(false)                                .connectTimeout(10, TimeUnit.SECONDS)//设置毗连超时时间                                .writeTimeout(10, TimeUnit.SECONDS)                                .readTimeout(10, TimeUnit.SECONDS)//设置读取超时时间                                .build();                        client.writeTimeoutMillis();                        client.newCall(request).enqueue(new Callback() {                            @Override                            public void onFailure(Call call, IOException e) {                                observer.onError(new Throwable("分析失败"));                            }                            @Override                            public void onResponse(Call call, Response response) throws IOException {                                String path = url;                                if (response.code() == HttpURLConnection.HTTP_MOVED_TEMP || response.code() == HttpURLConnection.HTTP_MOVED_PERM) {                                    String location = response.headers().get("Location");                                    if (!TextUtils.isEmpty(location)) {                                        path = location;                                    }                                    if (isEncode) {                                        path = path.replace("%23", URLDecoder.decode("%23"));                                        isEncode = false;                                    }                                }                                observer.onNext(path);                                observer.onComplete();                            }                        });                    }                })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(                        path -> callBack.getRedirectSuccess(path),                        throwable -> callBack.getRedirectFail());    }    //    取消哀求    public static void cancelRequest() {        if (callDisposable != null && !callDisposable.isDisposed()) {            callDisposable.dispose();        }    }    /**     * 判断是否是是讯云短毗连     *     * @param url     * @return     */    public static boolean isShortUrl(String url) {        return false;    }    /**     * 判断外部链接.MP4末端     */    public static boolean findEnd(String url) {        if (url.endsWith(".mp4")) {            return true;        }        return false;    }    public interface ResponseCallBack {        void getRedirectSuccess(String url);        void getRedirectFail();    }}3.处置处罚地点过长题目

一样平常开发的时间有一些三方SDK对Url的长度做出了限定,再加上一样平常利用过程中Url贼长让须要对Url做利用的同事非常反感,这个时间就须要对很长的Url做处置处罚,以下是个人对长毗连做的处置处罚

  • 紧缩器:配景来个长变短的服务,实在也就是一个字符串变短的算法,移动端哀求接口即可
  • 对Url的参数举行编码使参数变短
4.Url参数编码题目

Url在分享,欣赏器打开的时间中文大概特别字符会影响Url的利用,以是在给Url处置处罚参数的时间,给参数做统一编码(Encode)显得特别紧张.如果是复杂和长期维护的项目,发起项目架构的时间就处置处罚掉这个题目,不然后期会疯(切身履历).
总结

一样平常开发中,会碰到各种各样的Url,以是涉及到的Url处置处罚也就各种各样,发起将Url做一个统一收支的工具 统一管理各种Url的利用.此中涉及到的Url参数转码题目要慎重,要提前和H5和IOS沟通好防止出现Url处置处罚差异意题目.
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2025-2-6 05:41, Processed in 0.164237 second(s), 32 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表