001: /*
002: * Copyright 2002-2007 the original author or authors.
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:
017: package org.springframework.web.bind;
018:
019: import javax.servlet.ServletRequest;
020:
021: /**
022: * Parameter extraction methods, for an approach distinct from data binding,
023: * in which parameters of specific types are required.
024: *
025: * <p>This approach is very useful for simple submissions, where binding
026: * request parameters to a command object would be overkill.
027: *
028: * @author Juergen Hoeller
029: * @author Keith Donald
030: * @since 2.0
031: */
032: public abstract class ServletRequestUtils {
033:
034: private static final IntParser INT_PARSER = new IntParser();
035:
036: private static final LongParser LONG_PARSER = new LongParser();
037:
038: private static final FloatParser FLOAT_PARSER = new FloatParser();
039:
040: private static final DoubleParser DOUBLE_PARSER = new DoubleParser();
041:
042: private static final BooleanParser BOOLEAN_PARSER = new BooleanParser();
043:
044: private static final StringParser STRING_PARSER = new StringParser();
045:
046: /**
047: * Get an Integer parameter, or <code>null</code> if not present.
048: * Throws an exception if it the parameter value isn't a number.
049: * @param request current HTTP request
050: * @param name the name of the parameter
051: * @return the Integer value, or <code>null</code> if not present
052: * @throws ServletRequestBindingException a subclass of ServletException,
053: * so it doesn't need to be caught
054: */
055: public static Integer getIntParameter(ServletRequest request,
056: String name) throws ServletRequestBindingException {
057:
058: if (request.getParameter(name) == null) {
059: return null;
060: }
061: return new Integer(getRequiredIntParameter(request, name));
062: }
063:
064: /**
065: * Get an int parameter, with a fallback value. Never throws an exception.
066: * Can pass a distinguished value as default to enable checks of whether it was supplied.
067: * @param request current HTTP request
068: * @param name the name of the parameter
069: * @param defaultVal the default value to use as fallback
070: */
071: public static int getIntParameter(ServletRequest request,
072: String name, int defaultVal) {
073: if (request.getParameter(name) == null) {
074: return defaultVal;
075: }
076: try {
077: return getRequiredIntParameter(request, name);
078: } catch (ServletRequestBindingException ex) {
079: return defaultVal;
080: }
081: }
082:
083: /**
084: * Get an array of int parameters, return an empty array if not found.
085: * @param request current HTTP request
086: * @param name the name of the parameter with multiple possible values
087: */
088: public static int[] getIntParameters(ServletRequest request,
089: String name) {
090: try {
091: return getRequiredIntParameters(request, name);
092: } catch (ServletRequestBindingException ex) {
093: return new int[0];
094: }
095: }
096:
097: /**
098: * Get an int parameter, throwing an exception if it isn't found or isn't a number.
099: * @param request current HTTP request
100: * @param name the name of the parameter
101: * @throws ServletRequestBindingException a subclass of ServletException,
102: * so it doesn't need to be caught
103: */
104: public static int getRequiredIntParameter(ServletRequest request,
105: String name) throws ServletRequestBindingException {
106:
107: return INT_PARSER.parseInt(name, request.getParameter(name));
108: }
109:
110: /**
111: * Get an array of int parameters, throwing an exception if not found or one is not a number..
112: * @param request current HTTP request
113: * @param name the name of the parameter with multiple possible values
114: * @throws ServletRequestBindingException a subclass of ServletException,
115: * so it doesn't need to be caught
116: */
117: public static int[] getRequiredIntParameters(
118: ServletRequest request, String name)
119: throws ServletRequestBindingException {
120:
121: return INT_PARSER.parseInts(name, request
122: .getParameterValues(name));
123: }
124:
125: /**
126: * Get a Long parameter, or <code>null</code> if not present.
127: * Throws an exception if it the parameter value isn't a number.
128: * @param request current HTTP request
129: * @param name the name of the parameter
130: * @return the Long value, or <code>null</code> if not present
131: * @throws ServletRequestBindingException a subclass of ServletException,
132: * so it doesn't need to be caught
133: */
134: public static Long getLongParameter(ServletRequest request,
135: String name) throws ServletRequestBindingException {
136:
137: if (request.getParameter(name) == null) {
138: return null;
139: }
140: return new Long(getRequiredLongParameter(request, name));
141: }
142:
143: /**
144: * Get a long parameter, with a fallback value. Never throws an exception.
145: * Can pass a distinguished value as default to enable checks of whether it was supplied.
146: * @param request current HTTP request
147: * @param name the name of the parameter
148: * @param defaultVal the default value to use as fallback
149: */
150: public static long getLongParameter(ServletRequest request,
151: String name, long defaultVal) {
152: if (request.getParameter(name) == null) {
153: return defaultVal;
154: }
155: try {
156: return getRequiredLongParameter(request, name);
157: } catch (ServletRequestBindingException ex) {
158: return defaultVal;
159: }
160: }
161:
162: /**
163: * Get an array of long parameters, return an empty array if not found.
164: * @param request current HTTP request
165: * @param name the name of the parameter with multiple possible values
166: */
167: public static long[] getLongParameters(ServletRequest request,
168: String name) {
169: try {
170: return getRequiredLongParameters(request, name);
171: } catch (ServletRequestBindingException ex) {
172: return new long[0];
173: }
174: }
175:
176: /**
177: * Get a long parameter, throwing an exception if it isn't found or isn't a number.
178: * @param request current HTTP request
179: * @param name the name of the parameter
180: * @throws ServletRequestBindingException a subclass of ServletException,
181: * so it doesn't need to be caught
182: */
183: public static long getRequiredLongParameter(ServletRequest request,
184: String name) throws ServletRequestBindingException {
185:
186: return LONG_PARSER.parseLong(name, request.getParameter(name));
187: }
188:
189: /**
190: * Get an array of long parameters, throwing an exception if not found or one is not a number.
191: * @param request current HTTP request
192: * @param name the name of the parameter with multiple possible values
193: * @throws ServletRequestBindingException a subclass of ServletException,
194: * so it doesn't need to be caught
195: */
196: public static long[] getRequiredLongParameters(
197: ServletRequest request, String name)
198: throws ServletRequestBindingException {
199:
200: return LONG_PARSER.parseLongs(name, request
201: .getParameterValues(name));
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 HTTP request
208: * @param name the name of the parameter
209: * @return the Float value, or <code>null</code> if not present
210: * @throws ServletRequestBindingException a subclass of ServletException,
211: * so it doesn't need to be caught
212: */
213: public static Float getFloatParameter(ServletRequest request,
214: String name) throws ServletRequestBindingException {
215:
216: if (request.getParameter(name) == null) {
217: return null;
218: }
219: return new Float(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 HTTP request
226: * @param name the name of the parameter
227: * @param defaultVal the default value to use as fallback
228: */
229: public static float getFloatParameter(ServletRequest request,
230: String name, float defaultVal) {
231: if (request.getParameter(name) == null) {
232: return defaultVal;
233: }
234: try {
235: return getRequiredFloatParameter(request, name);
236: } catch (ServletRequestBindingException 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 HTTP request
244: * @param name the name of the parameter with multiple possible values
245: */
246: public static float[] getFloatParameters(ServletRequest request,
247: String name) {
248: try {
249: return getRequiredFloatParameters(request, name);
250: } catch (ServletRequestBindingException 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 HTTP request
258: * @param name the name of the parameter
259: * @throws ServletRequestBindingException a subclass of ServletException,
260: * so it doesn't need to be caught
261: */
262: public static float getRequiredFloatParameter(
263: ServletRequest request, String name)
264: throws ServletRequestBindingException {
265:
266: return FLOAT_PARSER
267: .parseFloat(name, request.getParameter(name));
268: }
269:
270: /**
271: * Get an array of float parameters, throwing an exception if not found or one is not a number.
272: * @param request current HTTP request
273: * @param name the name of the parameter with multiple possible values
274: * @throws ServletRequestBindingException a subclass of ServletException,
275: * so it doesn't need to be caught
276: */
277: public static float[] getRequiredFloatParameters(
278: ServletRequest request, String name)
279: throws ServletRequestBindingException {
280:
281: return FLOAT_PARSER.parseFloats(name, request
282: .getParameterValues(name));
283: }
284:
285: /**
286: * Get a Double parameter, or <code>null</code> if not present.
287: * Throws an exception if it the parameter value isn't a number.
288: * @param request current HTTP request
289: * @param name the name of the parameter
290: * @return the Double value, or <code>null</code> if not present
291: * @throws ServletRequestBindingException a subclass of ServletException,
292: * so it doesn't need to be caught
293: */
294: public static Double getDoubleParameter(ServletRequest request,
295: String name) throws ServletRequestBindingException {
296:
297: if (request.getParameter(name) == null) {
298: return null;
299: }
300: return new Double(getRequiredDoubleParameter(request, name));
301: }
302:
303: /**
304: * Get a double parameter, with a fallback value. Never throws an exception.
305: * Can pass a distinguished value as default to enable checks of whether it was supplied.
306: * @param request current HTTP request
307: * @param name the name of the parameter
308: * @param defaultVal the default value to use as fallback
309: */
310: public static double getDoubleParameter(ServletRequest request,
311: String name, double defaultVal) {
312: if (request.getParameter(name) == null) {
313: return defaultVal;
314: }
315: try {
316: return getRequiredDoubleParameter(request, name);
317: } catch (ServletRequestBindingException ex) {
318: return defaultVal;
319: }
320: }
321:
322: /**
323: * Get an array of double parameters, return an empty array if not found.
324: * @param request current HTTP request
325: * @param name the name of the parameter with multiple possible values
326: */
327: public static double[] getDoubleParameters(ServletRequest request,
328: String name) {
329: try {
330: return getRequiredDoubleParameters(request, name);
331: } catch (ServletRequestBindingException ex) {
332: return new double[0];
333: }
334: }
335:
336: /**
337: * Get a double parameter, throwing an exception if it isn't found or isn't a number.
338: * @param request current HTTP request
339: * @param name the name of the parameter
340: * @throws ServletRequestBindingException a subclass of ServletException,
341: * so it doesn't need to be caught
342: */
343: public static double getRequiredDoubleParameter(
344: ServletRequest request, String name)
345: throws ServletRequestBindingException {
346:
347: return DOUBLE_PARSER.parseDouble(name, request
348: .getParameter(name));
349: }
350:
351: /**
352: * Get an array of double parameters, throwing an exception if not found or one is not a number.
353: * @param request current HTTP request
354: * @param name the name of the parameter with multiple possible values
355: * @throws ServletRequestBindingException a subclass of ServletException,
356: * so it doesn't need to be caught
357: */
358: public static double[] getRequiredDoubleParameters(
359: ServletRequest request, String name)
360: throws ServletRequestBindingException {
361:
362: return DOUBLE_PARSER.parseDoubles(name, request
363: .getParameterValues(name));
364: }
365:
366: /**
367: * Get a Boolean parameter, or <code>null</code> if not present.
368: * Throws an exception if it the parameter value isn't a boolean.
369: * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
370: * treats every other non-empty value as false (i.e. parses leniently).
371: * @param request current HTTP request
372: * @param name the name of the parameter
373: * @return the Boolean value, or <code>null</code> if not present
374: * @throws ServletRequestBindingException a subclass of ServletException,
375: * so it doesn't need to be caught
376: */
377: public static Boolean getBooleanParameter(ServletRequest request,
378: String name) throws ServletRequestBindingException {
379:
380: if (request.getParameter(name) == null) {
381: return null;
382: }
383: return (getRequiredBooleanParameter(request, name) ? Boolean.TRUE
384: : Boolean.FALSE);
385: }
386:
387: /**
388: * Get a boolean parameter, with a fallback value. Never throws an exception.
389: * Can pass a distinguished value as default to enable checks of whether it was supplied.
390: * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
391: * treats every other non-empty value as false (i.e. parses leniently).
392: * @param request current HTTP request
393: * @param name the name of the parameter
394: * @param defaultVal the default value to use as fallback
395: */
396: public static boolean getBooleanParameter(ServletRequest request,
397: String name, boolean defaultVal) {
398: if (request.getParameter(name) == null) {
399: return defaultVal;
400: }
401: try {
402: return getRequiredBooleanParameter(request, name);
403: } catch (ServletRequestBindingException ex) {
404: return defaultVal;
405: }
406: }
407:
408: /**
409: * Get an array of boolean parameters, return an empty array if not found.
410: * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
411: * treats every other non-empty value as false (i.e. parses leniently).
412: * @param request current HTTP request
413: * @param name the name of the parameter with multiple possible values
414: */
415: public static boolean[] getBooleanParameters(
416: ServletRequest request, String name) {
417: try {
418: return getRequiredBooleanParameters(request, name);
419: } catch (ServletRequestBindingException ex) {
420: return new boolean[0];
421: }
422: }
423:
424: /**
425: * Get a boolean parameter, throwing an exception if it isn't found
426: * or isn't a boolean.
427: * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
428: * treats every other non-empty value as false (i.e. parses leniently).
429: * @param request current HTTP request
430: * @param name the name of the parameter
431: * @throws ServletRequestBindingException a subclass of ServletException,
432: * so it doesn't need to be caught
433: */
434: public static boolean getRequiredBooleanParameter(
435: ServletRequest request, String name)
436: throws ServletRequestBindingException {
437:
438: return BOOLEAN_PARSER.parseBoolean(name, request
439: .getParameter(name));
440: }
441:
442: /**
443: * Get an array of boolean parameters, throwing an exception if not found
444: * or one isn't a boolean.
445: * <p>Accepts "true", "on", "yes" (any case) and "1" as values for true;
446: * treats every other non-empty value as false (i.e. parses leniently).
447: * @param request current HTTP request
448: * @param name the name of the parameter
449: * @throws ServletRequestBindingException a subclass of ServletException,
450: * so it doesn't need to be caught
451: */
452: public static boolean[] getRequiredBooleanParameters(
453: ServletRequest request, String name)
454: throws ServletRequestBindingException {
455:
456: return BOOLEAN_PARSER.parseBooleans(name, request
457: .getParameterValues(name));
458: }
459:
460: /**
461: * Get a String parameter, or <code>null</code> if not present.
462: * @param request current HTTP request
463: * @param name the name of the parameter
464: * @return the String value, or <code>null</code> if not present
465: * @throws ServletRequestBindingException a subclass of ServletException,
466: * so it doesn't need to be caught
467: */
468: public static String getStringParameter(ServletRequest request,
469: String name) throws ServletRequestBindingException {
470:
471: if (request.getParameter(name) == null) {
472: return null;
473: }
474: return getRequiredStringParameter(request, name);
475: }
476:
477: /**
478: * Get a String parameter, with a fallback value. Never throws an exception.
479: * Can pass a distinguished value to default to enable checks of whether it was supplied.
480: * @param request current HTTP request
481: * @param name the name of the parameter
482: * @param defaultVal the default value to use as fallback
483: */
484: public static String getStringParameter(ServletRequest request,
485: String name, String defaultVal) {
486: String val = request.getParameter(name);
487: return (val != null ? val : defaultVal);
488: }
489:
490: /**
491: * Get an array of String parameters, return an empty array if not found.
492: * @param request current HTTP request
493: * @param name the name of the parameter with multiple possible values
494: */
495: public static String[] getStringParameters(ServletRequest request,
496: String name) {
497: try {
498: return getRequiredStringParameters(request, name);
499: } catch (ServletRequestBindingException ex) {
500: return new String[0];
501: }
502: }
503:
504: /**
505: * Get a String parameter, throwing an exception if it isn't found.
506: * @param request current HTTP request
507: * @param name the name of the parameter
508: * @throws ServletRequestBindingException a subclass of ServletException,
509: * so it doesn't need to be caught
510: */
511: public static String getRequiredStringParameter(
512: ServletRequest request, String name)
513: throws ServletRequestBindingException {
514:
515: return STRING_PARSER.validateRequiredString(name, request
516: .getParameter(name));
517: }
518:
519: /**
520: * Get an array of String parameters, throwing an exception if not found.
521: * @param request current HTTP request
522: * @param name the name of the parameter
523: * @throws ServletRequestBindingException a subclass of ServletException,
524: * so it doesn't need to be caught
525: */
526: public static String[] getRequiredStringParameters(
527: ServletRequest request, String name)
528: throws ServletRequestBindingException {
529:
530: return STRING_PARSER.validateRequiredStrings(name, request
531: .getParameterValues(name));
532: }
533:
534: private abstract static class ParameterParser {
535:
536: protected final Object parse(String name, String parameter)
537: throws ServletRequestBindingException {
538: validateRequiredParameter(name, parameter);
539: try {
540: return doParse(parameter);
541: } catch (NumberFormatException ex) {
542: throw new ServletRequestBindingException("Required "
543: + getType() + " parameter '" + name
544: + "' with value of '" + parameter
545: + "' is not a valid number", ex);
546: }
547: }
548:
549: protected final void validateRequiredParameter(String name,
550: Object parameter) throws ServletRequestBindingException {
551:
552: if (parameter == null) {
553: throw new MissingServletRequestParameterException(name,
554: getType());
555: }
556: }
557:
558: protected abstract String getType();
559:
560: protected abstract Object doParse(String parameter)
561: throws NumberFormatException;
562: }
563:
564: private static class IntParser extends ParameterParser {
565:
566: protected String getType() {
567: return "int";
568: }
569:
570: protected Object doParse(String s) throws NumberFormatException {
571: return Integer.valueOf(s);
572: }
573:
574: public int parseInt(String name, String parameter)
575: throws ServletRequestBindingException {
576: return ((Number) parse(name, parameter)).intValue();
577: }
578:
579: public int[] parseInts(String name, String[] values)
580: throws ServletRequestBindingException {
581: validateRequiredParameter(name, values);
582: int[] parameters = new int[values.length];
583: for (int i = 0; i < values.length; i++) {
584: parameters[i] = parseInt(name, values[i]);
585: }
586: return parameters;
587: }
588: }
589:
590: private static class LongParser extends ParameterParser {
591:
592: protected String getType() {
593: return "long";
594: }
595:
596: protected Object doParse(String parameter)
597: throws NumberFormatException {
598: return Long.valueOf(parameter);
599: }
600:
601: public long parseLong(String name, String parameter)
602: throws ServletRequestBindingException {
603: return ((Number) parse(name, parameter)).longValue();
604: }
605:
606: public long[] parseLongs(String name, String[] values)
607: throws ServletRequestBindingException {
608: validateRequiredParameter(name, values);
609: long[] parameters = new long[values.length];
610: for (int i = 0; i < values.length; i++) {
611: parameters[i] = parseLong(name, values[i]);
612: }
613: return parameters;
614: }
615: }
616:
617: private static class FloatParser extends ParameterParser {
618:
619: protected String getType() {
620: return "float";
621: }
622:
623: protected Object doParse(String parameter)
624: throws NumberFormatException {
625: return Float.valueOf(parameter);
626: }
627:
628: public float parseFloat(String name, String parameter)
629: throws ServletRequestBindingException {
630: return ((Number) parse(name, parameter)).floatValue();
631: }
632:
633: public float[] parseFloats(String name, String[] values)
634: throws ServletRequestBindingException {
635: validateRequiredParameter(name, values);
636: float[] parameters = new float[values.length];
637: for (int i = 0; i < values.length; i++) {
638: parameters[i] = parseFloat(name, values[i]);
639: }
640: return parameters;
641: }
642: }
643:
644: private static class DoubleParser extends ParameterParser {
645:
646: protected String getType() {
647: return "double";
648: }
649:
650: protected Object doParse(String parameter)
651: throws NumberFormatException {
652: return Double.valueOf(parameter);
653: }
654:
655: public double parseDouble(String name, String parameter)
656: throws ServletRequestBindingException {
657: return ((Number) parse(name, parameter)).doubleValue();
658: }
659:
660: public double[] parseDoubles(String name, String[] values)
661: throws ServletRequestBindingException {
662: validateRequiredParameter(name, values);
663: double[] parameters = new double[values.length];
664: for (int i = 0; i < values.length; i++) {
665: parameters[i] = parseDouble(name, values[i]);
666: }
667: return parameters;
668: }
669: }
670:
671: private static class BooleanParser extends ParameterParser {
672:
673: protected String getType() {
674: return "boolean";
675: }
676:
677: protected Object doParse(String parameter)
678: throws NumberFormatException {
679: return (parameter.equalsIgnoreCase("true")
680: || parameter.equalsIgnoreCase("on")
681: || parameter.equalsIgnoreCase("yes")
682: || parameter.equals("1") ? Boolean.TRUE
683: : Boolean.FALSE);
684: }
685:
686: public boolean parseBoolean(String name, String parameter)
687: throws ServletRequestBindingException {
688: return ((Boolean) parse(name, parameter)).booleanValue();
689: }
690:
691: public boolean[] parseBooleans(String name, String[] values)
692: throws ServletRequestBindingException {
693: validateRequiredParameter(name, values);
694: boolean[] parameters = new boolean[values.length];
695: for (int i = 0; i < values.length; i++) {
696: parameters[i] = parseBoolean(name, values[i]);
697: }
698: return parameters;
699: }
700: }
701:
702: private static class StringParser extends ParameterParser {
703:
704: protected String getType() {
705: return "string";
706: }
707:
708: protected Object doParse(String parameter)
709: throws NumberFormatException {
710: return parameter;
711: }
712:
713: public String validateRequiredString(String name, String value)
714: throws ServletRequestBindingException {
715: validateRequiredParameter(name, value);
716: return value;
717: }
718:
719: public String[] validateRequiredStrings(String name,
720: String[] values) throws ServletRequestBindingException {
721: validateRequiredParameter(name, values);
722: for (int i = 0; i < values.length; i++) {
723: validateRequiredParameter(name, values[i]);
724: }
725: return values;
726: }
727: }
728:
729: }
|