1 /* 2 * #%L 3 * wcm.io 4 * %% 5 * Copyright (C) 2014 wcm.io 6 * %% 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * #L% 19 */ 20 package io.wcm.sling.commons.request; 21 22 import java.nio.charset.StandardCharsets; 23 import java.util.Map; 24 25 import javax.servlet.ServletRequest; 26 27 import org.apache.commons.lang3.BooleanUtils; 28 import org.apache.commons.lang3.StringUtils; 29 import org.apache.commons.lang3.math.NumberUtils; 30 import org.jetbrains.annotations.NotNull; 31 import org.jetbrains.annotations.Nullable; 32 import org.osgi.annotation.versioning.ProviderType; 33 34 /** 35 * Several helper methods for getting parameters from the servlet request. 36 * This class automatically converts string parameters from ISO-8859-1 to UTF-8, because UTF-8 form data 37 * is expected by default. This is only done if no request parameter "_charset_" with an explicit encoding is set. 38 * If it is set, the {@link org.apache.sling.api.SlingHttpServletRequest} automatically converts the parameter data. 39 */ 40 @ProviderType 41 public final class RequestParam { 42 43 /** 44 * The name of the form encoding parameter. 45 * If such a form parameter is set in a request the {@link org.apache.sling.api.SlingHttpServletRequest} automatically 46 * transcodes all parameters to this encoding. 47 */ 48 public static final @NotNull String PARAMETER_FORMENCODING = "_charset_"; 49 50 private RequestParam() { 51 // Utility class - no instancing allowed 52 } 53 54 /** 55 * Returns a request parameter.<br> 56 * In addition the method fixes problems with incorrect UTF-8 characters returned by the servlet engine. 57 * All character data is converted from ISO-8859-1 to UTF-8 if not '_charset_' parameter is provided. 58 * @param request Request. 59 * @param param Parameter name. 60 * @return Parameter value or null if it is not set. 61 */ 62 public static @Nullable String get(@NotNull ServletRequest request, @NotNull String param) { 63 return get(request, param, null); 64 } 65 66 /** 67 * Returns a request parameter.<br> 68 * In addition the method fixes problems with incorrect UTF-8 characters returned by the servlet engine. 69 * All character data is converted from ISO-8859-1 to UTF-8 if not '_charset_' parameter is provided. 70 * @param request Request. 71 * @param param Parameter name. 72 * @param defaultValue Default value. 73 * @return Parameter value or the default value if it is not set. 74 */ 75 public static @Nullable String get(@NotNull ServletRequest request, @NotNull String param, @Nullable String defaultValue) { 76 String value = request.getParameter(param); 77 if (value != null) { 78 // convert encoding to UTF-8 if not form encoding parameter is set 79 if (!hasFormEncodingParam(request)) { 80 value = convertISO88591toUTF8(value); 81 } 82 return value; 83 } 84 else { 85 return defaultValue; 86 } 87 } 88 89 /** 90 * Returns a request parameter array.<br> 91 * The method fixes problems with incorrect UTF-8 characters returned by the servlet engine. 92 * All character data is converted from ISO-8859-1 to UTF-8. 93 * @param request Request. 94 * @param param Parameter name. 95 * @return Parameter value array value or null if it is not set. 96 */ 97 public static String @Nullable [] getMultiple(@NotNull ServletRequest request, @NotNull String param) { 98 String[] values = request.getParameterValues(param); 99 if (values == null) { 100 return null; 101 } 102 // convert encoding to UTF-8 if not form encoding parameter is set 103 if (!hasFormEncodingParam(request)) { 104 String[] convertedValues = new String[values.length]; 105 for (int i = 0; i < values.length; i++) { 106 if (values[i] != null) { 107 convertedValues[i] = convertISO88591toUTF8(values[i]); 108 } 109 } 110 return convertedValues; 111 } 112 else { 113 return values; 114 } 115 } 116 117 /** 118 * Returns a request parameter.<br> 119 * In addition the method fixes problems with incorrect UTF-8 characters returned by the servlet engine. 120 * All character data is converted from ISO-8859-1 to UTF-8. 121 * @param requestMap Request Parameter map. 122 * @param param Parameter name. 123 * @return Parameter value or null if it is not set. 124 */ 125 public static @Nullable String get(@NotNull Map<String, String[]> requestMap, @NotNull String param) { 126 String value = null; 127 String[] valueArray = requestMap.get(param); 128 if (valueArray != null && valueArray.length > 0) { 129 value = valueArray[0]; 130 } 131 // convert encoding to UTF-8 if not form encoding parameter is set 132 if (value != null && !hasFormEncodingParam(requestMap)) { 133 value = convertISO88591toUTF8(value); 134 } 135 return value; 136 } 137 138 /** 139 * Returns a request parameter as integer. 140 * @param request Request. 141 * @param param Parameter name. 142 * @return Parameter value or 0 if it does not exist or is not a number. 143 */ 144 public static int getInt(@NotNull ServletRequest request, @NotNull String param) { 145 return getInt(request, param, 0); 146 } 147 148 /** 149 * Returns a request parameter as integer. 150 * @param request Request. 151 * @param param Parameter name. 152 * @param defaultValue Default value. 153 * @return Parameter value or default value if it does not exist or is not a number. 154 */ 155 public static int getInt(@NotNull ServletRequest request, @NotNull String param, int defaultValue) { 156 String value = request.getParameter(param); 157 return NumberUtils.toInt(value, defaultValue); 158 } 159 160 /** 161 * Returns a request parameter as long. 162 * @param request Request. 163 * @param param Parameter name. 164 * @return Parameter value or 0 if it does not exist or is not a number. 165 */ 166 public static long getLong(@NotNull ServletRequest request, @NotNull String param) { 167 return getLong(request, param, 0L); 168 } 169 170 /** 171 * Returns a request parameter as long. 172 * @param request Request. 173 * @param param Parameter name. 174 * @param defaultValue Default value. 175 * @return Parameter value or default value if it does not exist or is not a number. 176 */ 177 public static long getLong(@NotNull ServletRequest request, @NotNull String param, long defaultValue) { 178 String value = request.getParameter(param); 179 return NumberUtils.toLong(value, defaultValue); 180 } 181 182 /** 183 * Returns a request parameter as float. 184 * @param request Request. 185 * @param param Parameter name. 186 * @return Parameter value or 0 if it does not exist or is not a number. 187 */ 188 public static float getFloat(@NotNull ServletRequest request, @NotNull String param) { 189 return getFloat(request, param, 0f); 190 } 191 192 /** 193 * Returns a request parameter as float. 194 * @param request Request. 195 * @param param Parameter name. 196 * @param defaultValue Default value. 197 * @return Parameter value or default value if it does not exist or is not a number. 198 */ 199 public static float getFloat(@NotNull ServletRequest request, @NotNull String param, float defaultValue) { 200 String value = request.getParameter(param); 201 return NumberUtils.toFloat(value, defaultValue); 202 } 203 204 /** 205 * Returns a request parameter as double. 206 * @param request Request. 207 * @param param Parameter name. 208 * @return Parameter value or 0 if it does not exist or is not a number. 209 */ 210 public static double getDouble(@NotNull ServletRequest request, @NotNull String param) { 211 return getDouble(request, param, 0d); 212 } 213 214 /** 215 * Returns a request parameter as double. 216 * @param request Request. 217 * @param param Parameter name. 218 * @param defaultValue Default value. 219 * @return Parameter value or default value if it does not exist or is not a number. 220 */ 221 public static double getDouble(@NotNull ServletRequest request, @NotNull String param, double defaultValue) { 222 String value = request.getParameter(param); 223 return NumberUtils.toDouble(value, defaultValue); 224 } 225 226 /** 227 * Returns a request parameter as boolean. 228 * @param request Request. 229 * @param param Parameter name. 230 * @return Parameter value or <code>false</code> if it does not exist or cannot be interpreted as boolean. 231 */ 232 public static boolean getBoolean(@NotNull ServletRequest request, @NotNull String param) { 233 return getBoolean(request, param, false); 234 } 235 236 /** 237 * Returns a request parameter as boolean. 238 * @param request Request. 239 * @param param Parameter name. 240 * @param defaultValue Default value. 241 * @return Parameter value or default value if it does not exist or <code>false</code> if it cannot be interpreted as 242 * boolean. 243 */ 244 public static boolean getBoolean(@NotNull ServletRequest request, @NotNull String param, boolean defaultValue) { 245 String value = request.getParameter(param); 246 Boolean boolValue = BooleanUtils.toBooleanObject(value); 247 if (boolValue != null) { 248 return boolValue.booleanValue(); 249 } 250 return defaultValue; 251 } 252 253 /** 254 * Returns a request parameter as enum value. 255 * @param <T> Enum type 256 * @param request Request. 257 * @param param Parameter name. 258 * @param enumClass Enum class 259 * @return Parameter value or null if it is not set or an invalid enum value. 260 */ 261 public static <T extends Enum> @Nullable T getEnum(@NotNull ServletRequest request, @NotNull String param, @NotNull Class<T> enumClass) { 262 return getEnum(request, param, enumClass, null); 263 } 264 265 /** 266 * Returns a request parameter as enum value. 267 * @param <T> Enum type 268 * @param request Request. 269 * @param param Parameter name. 270 * @param enumClass Enum class 271 * @param defaultValue Default value. 272 * @return Parameter value or the default value if it is not set or an invalid enum value. 273 */ 274 @SuppressWarnings("unchecked") 275 public static <T extends Enum> @Nullable T getEnum(@NotNull ServletRequest request, @NotNull String param, @NotNull Class<T> enumClass, 276 @Nullable T defaultValue) { 277 String value = get(request, param); 278 if (StringUtils.isNotEmpty(value)) { 279 try { 280 return (T)Enum.valueOf(enumClass, value); 281 } 282 catch (IllegalArgumentException ex) { 283 // ignore, return default 284 } 285 } 286 return defaultValue; 287 } 288 289 /** 290 * @param request Servlet request 291 * @return Checks if form encoding parameter is set 292 */ 293 private static boolean hasFormEncodingParam(@NotNull ServletRequest request) { 294 return StringUtils.isNotEmpty(request.getParameter(PARAMETER_FORMENCODING)); 295 } 296 297 /** 298 * @param requestMap Request map 299 * @return Checks if form encoding parameter is set 300 */ 301 private static boolean hasFormEncodingParam(@NotNull Map<String, String[]> requestMap) { 302 String[] valueArray = requestMap.get(PARAMETER_FORMENCODING); 303 return valueArray != null && valueArray.length > 0; 304 } 305 306 /** 307 * Converts a string from ISO-8559-1 encoding to UTF-8. 308 * @param value ISO-8559-1 value 309 * @return UTF-8 value 310 */ 311 private static String convertISO88591toUTF8(String value) { 312 return new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); 313 } 314 315 }