1 /* 2 * Copyright 2002-2008 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.web.portlet.bind; 18 19 import javax.portlet.PortletRequest; 20 21 /** 22 * Parameter extraction methods, for an approach distinct from data binding, 23 * in which parameters of specific types are required. 24 * 25 * <p>This approach is very useful for simple submissions, where binding 26 * request parameters to a command object would be overkill. 27 * 28 * @author Juergen Hoeller 29 * @author Keith Donald 30 * @author John A. Lewis 31 * @since 2.0 32 */ 33 public abstract class PortletRequestUtils { 34 35 private static final IntParser INT_PARSER = new IntParser(); 36 37 private static final LongParser LONG_PARSER = new LongParser(); 38 39 private static final FloatParser FLOAT_PARSER = new FloatParser(); 40 41 private static final DoubleParser DOUBLE_PARSER = new DoubleParser(); 42 43 private static final BooleanParser BOOLEAN_PARSER = new BooleanParser(); 44 45 private static final StringParser STRING_PARSER = new StringParser(); 46 47 48 /** 49 * Get an Integer parameter, or <code>null</code> if not present. 50 * Throws an exception if it the parameter value isn't a number. 51 * @param request current portlet request 52 * @param name the name of the parameter 53 * @return the Integer value, or <code>null</code> if not present 54 * @throws PortletRequestBindingException a subclass of PortletException, 55 * so it doesn't need to be caught 56 */ getIntParameter(PortletRequest request, String name)57 public static Integer getIntParameter(PortletRequest request, String name) 58 throws PortletRequestBindingException { 59 60 if (request.getParameter(name) == null) { 61 return null; 62 } 63 return getRequiredIntParameter(request, name); 64 } 65 66 /** 67 * Get an int parameter, with a fallback value. Never throws an exception. 68 * Can pass a distinguished value as default to enable checks of whether it was supplied. 69 * @param request current portlet request 70 * @param name the name of the parameter 71 * @param defaultVal the default value to use as fallback 72 */ getIntParameter(PortletRequest request, String name, int defaultVal)73 public static int getIntParameter(PortletRequest request, String name, int defaultVal) { 74 if (request.getParameter(name) == null) { 75 return defaultVal; 76 } 77 try { 78 return getRequiredIntParameter(request, name); 79 } 80 catch (PortletRequestBindingException ex) { 81 return defaultVal; 82 } 83 } 84 85 /** 86 * Get an array of int parameters, return an empty array if not found. 87 * @param request current portlet request 88 * @param name the name of the parameter with multiple possible values 89 */ getIntParameters(PortletRequest request, String name)90 public static int[] getIntParameters(PortletRequest request, String name) { 91 try { 92 return getRequiredIntParameters(request, name); 93 } 94 catch (PortletRequestBindingException ex) { 95 return new int[0]; 96 } 97 } 98 99 /** 100 * Get an int parameter, throwing an exception if it isn't found or isn't a number. 101 * @param request current portlet request 102 * @param name the name of the parameter 103 * @throws PortletRequestBindingException a subclass of PortletException, 104 * so it doesn't need to be caught 105 */ getRequiredIntParameter(PortletRequest request, String name)106 public static int getRequiredIntParameter(PortletRequest request, String name) 107 throws PortletRequestBindingException { 108 109 return INT_PARSER.parseInt(name, request.getParameter(name)); 110 } 111 112 /** 113 * Get an array of int parameters, throwing an exception if not found or one is not a number.. 114 * @param request current portlet request 115 * @param name the name of the parameter with multiple possible values 116 * @throws PortletRequestBindingException a subclass of PortletException, 117 * so it doesn't need to be caught 118 */ getRequiredIntParameters(PortletRequest request, String name)119 public static int[] getRequiredIntParameters(PortletRequest request, String name) 120 throws PortletRequestBindingException { 121 122 return INT_PARSER.parseInts(name, request.getParameterValues(name)); 123 } 124 125 126 /** 127 * Get a Long parameter, or <code>null</code> if not present. 128 * Throws an exception if it the parameter value isn't a number. 129 * @param request current portlet request 130 * @param name the name of the parameter 131 * @return the Long value, or <code>null</code> if not present 132 * @throws PortletRequestBindingException a subclass of PortletException, 133 * so it doesn't need to be caught 134 */ getLongParameter(PortletRequest request, String name)135 public static Long getLongParameter(PortletRequest request, String name) 136 throws PortletRequestBindingException { 137 138 if (request.getParameter(name) == null) { 139 return null; 140 } 141 return getRequiredLongParameter(request, name); 142 } 143 144 /** 145 * Get a long parameter, with a fallback value. Never throws an exception. 146 * Can pass a distinguished value as default to enable checks of whether it was supplied. 147 * @param request current portlet request 148 * @param name the name of the parameter 149 * @param defaultVal the default value to use as fallback 150 */ getLongParameter(PortletRequest request, String name, long defaultVal)151 public static long getLongParameter(PortletRequest request, String name, long defaultVal) { 152 if (request.getParameter(name) == null) { 153 return defaultVal; 154 } 155 try { 156 return getRequiredLongParameter(request, name); 157 } 158 catch (PortletRequestBindingException ex) { 159 return defaultVal; 160 } 161 } 162 163 /** 164 * Get an array of long parameters, return an empty array if not found. 165 * @param request current portlet request 166 * @param name the name of the parameter with multiple possible values 167 */ getLongParameters(PortletRequest request, String name)168 public static long[] getLongParameters(PortletRequest request, String name) { 169 try { 170 return getRequiredLongParameters(request, name); 171 } 172 catch (PortletRequestBindingException ex) { 173 return new long[0]; 174 } 175 } 176 177 /** 178 * Get a long parameter, throwing an exception if it isn't found or isn't a number. 179 * @param request current portlet request 180 * @param name the name of the parameter 181 * @throws PortletRequestBindingException a subclass of PortletException, 182 * so it doesn't need to be caught 183 */ getRequiredLongParameter(PortletRequest request, String name)184 public static long getRequiredLongParameter(PortletRequest request, String name) 185 throws PortletRequestBindingException { 186 187 return LONG_PARSER.parseLong(name, request.getParameter(name)); 188 } 189 190 /** 191 * Get an array of long parameters, throwing an exception if not found or one is not a number. 192 * @param request current portlet request 193 * @param name the name of the parameter with multiple possible values 194 * @throws PortletRequestBindingException a subclass of PortletException, 195 * so it doesn't need to be caught 196 */ getRequiredLongParameters(PortletRequest request, String name)197 public static long[] getRequiredLongParameters(PortletRequest request, String name) 198 throws PortletRequestBindingException { 199 200 return LONG_PARSER.parseLongs(name, request.getParameterValues(name)); 201 } 202 203 204 /** 205 * Get a Float parameter, or <code>null</code> if not present. 206 * Throws an exception if it the parameter value isn't a number. 207 * @param request current portlet request 208 * @param name the name of the parameter 209 * @return the Float value, or <code>null</code> if not present 210 * @throws PortletRequestBindingException a subclass of PortletException, 211 * so it doesn't need to be caught 212 */ getFloatParameter(PortletRequest request, String name)213 public static Float getFloatParameter(PortletRequest request, String name) 214 throws PortletRequestBindingException { 215 216 if (request.getParameter(name) == null) { 217 return null; 218 } 219 return getRequiredFloatParameter(request, name); 220 } 221 222 /** 223 * Get a float parameter, with a fallback value. Never throws an exception. 224 * Can pass a distinguished value as default to enable checks of whether it was supplied. 225 * @param request current portlet request 226 * @param name the name of the parameter 227 * @param defaultVal the default value to use as fallback 228 */ getFloatParameter(PortletRequest request, String name, float defaultVal)229 public static float getFloatParameter(PortletRequest request, String name, float defaultVal) { 230 if (request.getParameter(name) == null) { 231 return defaultVal; 232 } 233 try { 234 return getRequiredFloatParameter(request, name); 235 } 236 catch (PortletRequestBindingException ex) { 237 return defaultVal; 238 } 239 } 240 241 /** 242 * Get an array of float parameters, return an empty array if not found. 243 * @param request current portlet request 244 * @param name the name of the parameter with multiple possible values 245 */ getFloatParameters(PortletRequest request, String name)246 public static float[] getFloatParameters(PortletRequest request, String name) { 247 try { 248 return getRequiredFloatParameters(request, name); 249 } 250 catch (PortletRequestBindingException ex) { 251 return new float[0]; 252 } 253 } 254 255 /** 256 * Get a float parameter, throwing an exception if it isn't found or isn't a number. 257 * @param request current portlet request 258 * @param name the name of the parameter 259 * @throws PortletRequestBindingException a subclass of PortletException, 260 * so it doesn't need to be caught 261 */ getRequiredFloatParameter(PortletRequest request, String name)262 public static float getRequiredFloatParameter(PortletRequest request, String name) 263 throws PortletRequestBindingException { 264 265 return FLOAT_PARSER.parseFloat(name, request.getParameter(name)); 266 } 267 268 /** 269 * Get an array of float parameters, throwing an exception if not found or one is not a number. 270 * @param request current portlet request 271 * @param name the name of the parameter with multiple possible values 272 * @throws PortletRequestBindingException a subclass of PortletException, 273 * so it doesn't need to be caught 274 */ getRequiredFloatParameters(PortletRequest request, String name)275 public static float[] getRequiredFloatParameters(PortletRequest request, String name) 276 throws PortletRequestBindingException { 277 278 return FLOAT_PARSER.parseFloats(name, request.getParameterValues(name)); 279 } 280 281 282 /** 283 * Get a Double parameter, or <code>null</code> if not present. 284 * Throws an exception if it the parameter value isn't a number. 285 * @param request current portlet request 286 * @param name the name of the parameter 287 * @return the Double value, or <code>null</code> if not present 288 * @throws PortletRequestBindingException a subclass of PortletException, 289 * so it doesn't need to be caught 290 */ getDoubleParameter(PortletRequest request, String name)291 public static Double getDoubleParameter(PortletRequest request, String name) 292 throws PortletRequestBindingException { 293 294 if (request.getParameter(name) == null) { 295 return null; 296 } 297 return getRequiredDoubleParameter(request, name); 298 } 299 300 /** 301 * Get a double parameter, with a fallback value. Never throws an exception. 302 * Can pass a distinguished value as default to enable checks of whether it was supplied. 303 * @param request current portlet request 304 * @param name the name of the parameter 305 * @param defaultVal the default value to use as fallback 306 */ getDoubleParameter(PortletRequest request, String name, double defaultVal)307 public static double getDoubleParameter(PortletRequest request, String name, double defaultVal) { 308 if (request.getParameter(name) == null) { 309 return defaultVal; 310 } 311 try { 312 return getRequiredDoubleParameter(request, name); 313 } 314 catch (PortletRequestBindingException ex) { 315 return defaultVal; 316 } 317 } 318 319 /** 320 * Get an array of double parameters, return an empty array if not found. 321 * @param request current portlet request 322 * @param name the name of the parameter with multiple possible values 323 */ getDoubleParameters(PortletRequest request, String name)324 public static double[] getDoubleParameters(PortletRequest request, String name) { 325 try { 326 return getRequiredDoubleParameters(request, name); 327 } 328 catch (PortletRequestBindingException ex) { 329 return new double[0]; 330 } 331 } 332 333 /** 334 * Get a double parameter, throwing an exception if it isn't found or isn't a number. 335 * @param request current portlet request 336 * @param name the name of the parameter 337 * @throws PortletRequestBindingException a subclass of PortletException, 338 * so it doesn't need to be caught 339 */ getRequiredDoubleParameter(PortletRequest request, String name)340 public static double getRequiredDoubleParameter(PortletRequest request, String name) 341 throws PortletRequestBindingException { 342 343 return DOUBLE_PARSER.parseDouble(name, request.getParameter(name)); 344 } 345 346 /** 347 * Get an array of double parameters, throwing an exception if not found or one is not a number. 348 * @param request current portlet request 349 * @param name the name of the parameter with multiple possible values 350 * @throws PortletRequestBindingException a subclass of PortletException, 351 * so it doesn't need to be caught 352 */ getRequiredDoubleParameters(PortletRequest request, String name)353 public static double[] getRequiredDoubleParameters(PortletRequest request, String name) 354 throws PortletRequestBindingException { 355 356 return DOUBLE_PARSER.parseDoubles(name, request.getParameterValues(name)); 357 } 358 359 360 /** 361 * Get a Boolean parameter, or <code>null</code> if not present. 362 * Throws an exception if it the parameter value isn't a boolean. 363 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 364 * treats every other non-empty value as false (i.e. parses leniently). 365 * @param request current portlet request 366 * @param name the name of the parameter 367 * @return the Boolean value, or <code>null</code> if not present 368 * @throws PortletRequestBindingException a subclass of PortletException, 369 * so it doesn't need to be caught 370 */ getBooleanParameter(PortletRequest request, String name)371 public static Boolean getBooleanParameter(PortletRequest request, String name) 372 throws PortletRequestBindingException { 373 374 if (request.getParameter(name) == null) { 375 return null; 376 } 377 return (getRequiredBooleanParameter(request, name)); 378 } 379 380 /** 381 * Get a boolean parameter, with a fallback value. Never throws an exception. 382 * Can pass a distinguished value as default to enable checks of whether it was supplied. 383 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 384 * treats every other non-empty value as false (i.e. parses leniently). 385 * @param request current portlet request 386 * @param name the name of the parameter 387 * @param defaultVal the default value to use as fallback 388 */ getBooleanParameter(PortletRequest request, String name, boolean defaultVal)389 public static boolean getBooleanParameter(PortletRequest request, String name, boolean defaultVal) { 390 if (request.getParameter(name) == null) { 391 return defaultVal; 392 } 393 try { 394 return getRequiredBooleanParameter(request, name); 395 } 396 catch (PortletRequestBindingException ex) { 397 return defaultVal; 398 } 399 } 400 401 /** 402 * Get an array of boolean parameters, return an empty array if not found. 403 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 404 * treats every other non-empty value as false (i.e. parses leniently). 405 * @param request current portlet request 406 * @param name the name of the parameter with multiple possible values 407 */ getBooleanParameters(PortletRequest request, String name)408 public static boolean[] getBooleanParameters(PortletRequest request, String name) { 409 try { 410 return getRequiredBooleanParameters(request, name); 411 } 412 catch (PortletRequestBindingException ex) { 413 return new boolean[0]; 414 } 415 } 416 417 /** 418 * Get a boolean parameter, throwing an exception if it isn't found 419 * or isn't a boolean. 420 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 421 * treats every other non-empty value as false (i.e. parses leniently). 422 * @param request current portlet request 423 * @param name the name of the parameter 424 * @throws PortletRequestBindingException a subclass of PortletException, 425 * so it doesn't need to be caught 426 */ getRequiredBooleanParameter(PortletRequest request, String name)427 public static boolean getRequiredBooleanParameter(PortletRequest request, String name) 428 throws PortletRequestBindingException { 429 430 return BOOLEAN_PARSER.parseBoolean(name, request.getParameter(name)); 431 } 432 433 /** 434 * Get an array of boolean parameters, throwing an exception if not found 435 * or one isn't a boolean. 436 * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true; 437 * treats every other non-empty value as false (i.e. parses leniently). 438 * @param request current portlet request 439 * @param name the name of the parameter 440 * @throws PortletRequestBindingException a subclass of PortletException, 441 * so it doesn't need to be caught 442 */ getRequiredBooleanParameters(PortletRequest request, String name)443 public static boolean[] getRequiredBooleanParameters(PortletRequest request, String name) 444 throws PortletRequestBindingException { 445 446 return BOOLEAN_PARSER.parseBooleans(name, request.getParameterValues(name)); 447 } 448 449 450 /** 451 * Get a String parameter, or <code>null</code> if not present. 452 * Throws an exception if it the parameter value is empty. 453 * @param request current portlet request 454 * @param name the name of the parameter 455 * @return the String value, or <code>null</code> if not present 456 * @throws PortletRequestBindingException a subclass of PortletException, 457 * so it doesn't need to be caught 458 */ getStringParameter(PortletRequest request, String name)459 public static String getStringParameter(PortletRequest request, String name) 460 throws PortletRequestBindingException { 461 462 if (request.getParameter(name) == null) { 463 return null; 464 } 465 return getRequiredStringParameter(request, name); 466 } 467 468 /** 469 * Get a String parameter, with a fallback value. Never throws an exception. 470 * Can pass a distinguished value to default to enable checks of whether it was supplied. 471 * @param request current portlet request 472 * @param name the name of the parameter 473 * @param defaultVal the default value to use as fallback 474 */ getStringParameter(PortletRequest request, String name, String defaultVal)475 public static String getStringParameter(PortletRequest request, String name, String defaultVal) { 476 String val = request.getParameter(name); 477 return (val != null ? val : defaultVal); 478 } 479 480 /** 481 * Get an array of String parameters, return an empty array if not found. 482 * @param request current portlet request 483 * @param name the name of the parameter with multiple possible values 484 */ getStringParameters(PortletRequest request, String name)485 public static String[] getStringParameters(PortletRequest request, String name) { 486 try { 487 return getRequiredStringParameters(request, name); 488 } 489 catch (PortletRequestBindingException ex) { 490 return new String[0]; 491 } 492 } 493 494 /** 495 * Get a String parameter, throwing an exception if it isn't found or is empty. 496 * @param request current portlet request 497 * @param name the name of the parameter 498 * @throws PortletRequestBindingException a subclass of PortletException, 499 * so it doesn't need to be caught 500 */ getRequiredStringParameter(PortletRequest request, String name)501 public static String getRequiredStringParameter(PortletRequest request, String name) 502 throws PortletRequestBindingException { 503 504 return STRING_PARSER.validateRequiredString(name, request.getParameter(name)); 505 } 506 507 /** 508 * Get an array of String parameters, throwing an exception if not found or one is empty. 509 * @param request current portlet request 510 * @param name the name of the parameter 511 * @throws PortletRequestBindingException a subclass of PortletException, 512 * so it doesn't need to be caught 513 */ getRequiredStringParameters(PortletRequest request, String name)514 public static String[] getRequiredStringParameters(PortletRequest request, String name) 515 throws PortletRequestBindingException { 516 517 return STRING_PARSER.validateRequiredStrings(name, request.getParameterValues(name)); 518 } 519 520 521 private abstract static class ParameterParser<T> { 522 parse(String name, String parameter)523 protected final T parse(String name, String parameter) throws PortletRequestBindingException { 524 validateRequiredParameter(name, parameter); 525 try { 526 return doParse(parameter); 527 } 528 catch (NumberFormatException ex) { 529 throw new PortletRequestBindingException( 530 "Required " + getType() + " parameter '" + name + "' with value of '" + 531 parameter + "' is not a valid number", ex); 532 } 533 } 534 validateRequiredParameter(String name, Object parameter)535 protected final void validateRequiredParameter(String name, Object parameter) 536 throws PortletRequestBindingException { 537 538 if (parameter == null) { 539 throw new MissingPortletRequestParameterException(name, getType()); 540 } 541 } 542 getType()543 protected abstract String getType(); 544 doParse(String parameter)545 protected abstract T doParse(String parameter) throws NumberFormatException; 546 } 547 548 549 private static class IntParser extends ParameterParser<Integer> { 550 551 @Override getType()552 protected String getType() { 553 return "int"; 554 } 555 556 @Override doParse(String s)557 protected Integer doParse(String s) throws NumberFormatException { 558 return Integer.valueOf(s); 559 } 560 parseInt(String name, String parameter)561 public int parseInt(String name, String parameter) throws PortletRequestBindingException { 562 return parse(name, parameter); 563 } 564 parseInts(String name, String[] values)565 public int[] parseInts(String name, String[] values) throws PortletRequestBindingException { 566 validateRequiredParameter(name, values); 567 int[] parameters = new int[values.length]; 568 for (int i = 0; i < values.length; i++) { 569 parameters[i] = parseInt(name, values[i]); 570 } 571 return parameters; 572 } 573 } 574 575 576 private static class LongParser extends ParameterParser<Long> { 577 578 @Override getType()579 protected String getType() { 580 return "long"; 581 } 582 583 @Override doParse(String parameter)584 protected Long doParse(String parameter) throws NumberFormatException { 585 return Long.valueOf(parameter); 586 } 587 parseLong(String name, String parameter)588 public long parseLong(String name, String parameter) throws PortletRequestBindingException { 589 return parse(name, parameter); 590 } 591 parseLongs(String name, String[] values)592 public long[] parseLongs(String name, String[] values) throws PortletRequestBindingException { 593 validateRequiredParameter(name, values); 594 long[] parameters = new long[values.length]; 595 for (int i = 0; i < values.length; i++) { 596 parameters[i] = parseLong(name, values[i]); 597 } 598 return parameters; 599 } 600 } 601 602 603 private static class FloatParser extends ParameterParser<Float> { 604 605 @Override getType()606 protected String getType() { 607 return "float"; 608 } 609 610 @Override doParse(String parameter)611 protected Float doParse(String parameter) throws NumberFormatException { 612 return Float.valueOf(parameter); 613 } 614 parseFloat(String name, String parameter)615 public float parseFloat(String name, String parameter) throws PortletRequestBindingException { 616 return parse(name, parameter); 617 } 618 parseFloats(String name, String[] values)619 public float[] parseFloats(String name, String[] values) throws PortletRequestBindingException { 620 validateRequiredParameter(name, values); 621 float[] parameters = new float[values.length]; 622 for (int i = 0; i < values.length; i++) { 623 parameters[i] = parseFloat(name, values[i]); 624 } 625 return parameters; 626 } 627 } 628 629 630 private static class DoubleParser extends ParameterParser<Double> { 631 632 @Override getType()633 protected String getType() { 634 return "double"; 635 } 636 637 @Override doParse(String parameter)638 protected Double doParse(String parameter) throws NumberFormatException { 639 return Double.valueOf(parameter); 640 } 641 parseDouble(String name, String parameter)642 public double parseDouble(String name, String parameter) throws PortletRequestBindingException { 643 return parse(name, parameter); 644 } 645 parseDoubles(String name, String[] values)646 public double[] parseDoubles(String name, String[] values) throws PortletRequestBindingException { 647 validateRequiredParameter(name, values); 648 double[] parameters = new double[values.length]; 649 for (int i = 0; i < values.length; i++) { 650 parameters[i] = parseDouble(name, values[i]); 651 } 652 return parameters; 653 } 654 } 655 656 657 private static class BooleanParser extends ParameterParser<Boolean> { 658 659 @Override getType()660 protected String getType() { 661 return "boolean"; 662 } 663 664 @Override doParse(String parameter)665 protected Boolean doParse(String parameter) throws NumberFormatException { 666 return (parameter.equalsIgnoreCase("true") || parameter.equalsIgnoreCase("on") || 667 parameter.equalsIgnoreCase("yes") || parameter.equals("1")); 668 } 669 parseBoolean(String name, String parameter)670 public boolean parseBoolean(String name, String parameter) throws PortletRequestBindingException { 671 return parse(name, parameter); 672 } 673 parseBooleans(String name, String[] values)674 public boolean[] parseBooleans(String name, String[] values) throws PortletRequestBindingException { 675 validateRequiredParameter(name, values); 676 boolean[] parameters = new boolean[values.length]; 677 for (int i = 0; i < values.length; i++) { 678 parameters[i] = parseBoolean(name, values[i]); 679 } 680 return parameters; 681 } 682 } 683 684 685 private static class StringParser extends ParameterParser<String> { 686 687 @Override getType()688 protected String getType() { 689 return "string"; 690 } 691 692 @Override doParse(String parameter)693 protected String doParse(String parameter) throws NumberFormatException { 694 return parameter; 695 } 696 validateRequiredString(String name, String value)697 public String validateRequiredString(String name, String value) throws PortletRequestBindingException { 698 validateRequiredParameter(name, value); 699 return value; 700 } 701 validateRequiredStrings(String name, String[] values)702 public String[] validateRequiredStrings(String name, String[] values) throws PortletRequestBindingException { 703 validateRequiredParameter(name, values); 704 for (String value : values) { 705 validateRequiredParameter(name, value); 706 } 707 return values; 708 } 709 } 710 711 } 712