001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.util.common.string; 018 019import java.io.UnsupportedEncodingException; 020import java.net.URLEncoder; 021import java.util.Map; 022import javax.servlet.http.HttpServletRequest; 023import javax.servlet.http.HttpServletResponse; 024 025public class UrlUtils { 026 027 private UrlUtils() { 028 super(); 029 } 030 031 private static class UrlUtilsHolder { 032 static UrlUtils instance = new UrlUtils(); 033 } 034 035 public static UrlUtils getInstance() { 036 return UrlUtilsHolder.instance; 037 } 038 039 public StringBuilder buildBaseUrl(HttpServletRequest request) { 040 var scheme = request.getScheme(); 041 var serverName = request.getServerName(); 042 var serverPort = request.getServerPort(); 043 var contextPath = request.getContextPath(); 044 var servletPath = request.getServletPath(); 045 var includeServerPort = (scheme.equals("http") && serverPort != 80) || (scheme.equals("https") && serverPort != 443); 046 047 return new StringBuilder(scheme).append("://").append(serverName).append(includeServerPort? ":" + serverPort: "").append(contextPath).append(servletPath); 048 } 049 050 public StringBuilder buildParams(StringBuilder url, Map<String, String> params) { 051 if(params != null && params.size() > 0) { 052 var entrySet = params.entrySet(); 053 var isFirst = true; 054 055 for(var entry : entrySet) { 056 url.append(isFirst ? '?' : '&'); 057 try { 058 url.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), "UTF-8")); 059 } catch(UnsupportedEncodingException uee) { 060 // If UTF-8 isn't a supported encoding, then there are severe problems. 061 throw new RuntimeException(uee); 062 } 063 isFirst = false; 064 } 065 } 066 067 return url; 068 } 069 070 public String buildUrl(HttpServletRequest request, HttpServletResponse response, String path, Map<String, String> params) { 071 return response.encodeURL(buildParams(buildBaseUrl(request).append(path), params).toString()); 072 } 073 074}