All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.rest.RequestFormData Maven / Gradle / Ivy

There is a newer version: 9.0.1
Show newest version
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.rest;

import static org.apache.juneau.internal.ArrayUtils.*;

import java.lang.reflect.*;
import java.util.*;

import org.apache.juneau.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.urlencoding.*;

/**
 * Represents the parsed form data parameters in an HTTP request.
 */
@SuppressWarnings("unchecked")
public class RequestFormData extends LinkedHashMap {
	private static final long serialVersionUID = 1L;

	private UrlEncodingParser parser;
	private BeanSession beanSession;

	RequestFormData setParser(UrlEncodingParser parser) {
		this.parser = parser;
		return this;
	}

	RequestFormData setBeanSession(BeanSession beanSession) {
		this.beanSession = beanSession;
		return this;
	}

	/**
	 * Adds default entries to these form-data parameters.
	 *
	 * 

* This includes the default form-data parameters defined on the servlet and method levels. * * @param defaultEntries The default entries. Can be null. * @return This object (for method chaining). */ public RequestFormData addDefault(Map defaultEntries) { if (defaultEntries != null) { for (Map.Entry e : defaultEntries.entrySet()) { String key = e.getKey(), value = e.getValue(); String[] v = get(key); if (v == null || v.length == 0 || StringUtils.isEmpty(v[0])) put(key, new String[]{value}); } } return this; } /** * Sets a request form data parameter value. * * @param name The parameter name. * @param value The parameter value. */ public void put(String name, Object value) { super.put(name, new String[]{StringUtils.toString(value)}); } /** * Returns a form data parameter value. * *

* Parameter lookup is case-insensitive (consistent with WAS, but differs from Tomcat). * *

Notes:
*
    *
  • Calling this method on URL-Encoded FORM posts causes the body content to be loaded and parsed by the * underlying servlet API. *
  • This method returns the raw unparsed value, and differs from calling * getFormDataParameter(name, String.class) which will convert the value from UON * notation: *
      *
    • "null" => null *
    • "'null'" => "null" *
    • "'foo bar'" => "foo bar" *
    • "foo~~bar" => "foo~bar" *
    *
* * @param name The form data parameter name. * @return The parameter value, or null if parameter does not exist. */ public String getString(String name) { String[] v = get(name); if (v == null || v.length == 0) return null; // Fix for behavior difference between Tomcat and WAS. // getParameter("foo") on "&foo" in Tomcat returns "". // getParameter("foo") on "&foo" in WAS returns null. if (v.length == 1 && v[0] == null) return ""; return v[0]; } /** * Same as {@link #getString(String)} except returns a default value if null or empty. * * @param name The form data parameter name. * @param def The default value. * @return The parameter value, or the default value if parameter does not exist or is null or empty. */ public String getString(String name, String def) { String s = getString(name); return StringUtils.isEmpty(s) ? def : s; } /** * Same as {@link #getString(String)} but converts the value to an integer. * * @param name The form data parameter name. * @return The parameter value, or 0 if parameter does not exist or is null or empty. */ public int getInt(String name) { return getInt(name, 0); } /** * Same as {@link #getString(String,String)} but converts the value to an integer. * * @param name The form data parameter name. * @param def The default value. * @return The parameter value, or the default value if parameter does not exist or is null or empty. */ public int getInt(String name, int def) { String s = getString(name); return StringUtils.isEmpty(s) ? def : Integer.parseInt(s); } /** * Same as {@link #getString(String)} but converts the value to a boolean. * * @param name The form data parameter name. * @return The parameter value, or false if parameter does not exist or is null or empty. */ public boolean getBoolean(String name) { return getBoolean(name, false); } /** * Same as {@link #getString(String,String)} but converts the value to a boolean. * * @param name The form data parameter name. * @param def The default value. * @return The parameter value, or the default value if parameter does not exist or is null or empty. */ public boolean getBoolean(String name, boolean def) { String s = getString(name); return StringUtils.isEmpty(s) ? def : Boolean.parseBoolean(s); } /** * Returns the specified form data parameter value converted to a POJO using the {@link UrlEncodingParser} * registered with this servlet. * *
Examples:
*

* // Parse into an integer. * int myparam = req.getFormDataParameter("myparam", int.class); * * // Parse into an int array. * int[] myparam = req.getFormDataParameter("myparam", int[].class); * // Parse into a bean. * MyBean myparam = req.getFormDataParameter("myparam", MyBean.class); * * // Parse into a linked-list of objects. * List myparam = req.getFormDataParameter("myparam", LinkedList.class); * * // Parse into a map of object keys/values. * Map myparam = req.getFormDataParameter("myparam", TreeMap.class); *

* *
Notes:
*
    *
  • Calling this method on URL-Encoded FORM posts causes the body content to be loaded and parsed by the * underlying servlet API. *
* * @param name The parameter name. * @param type The class type to convert the parameter value to. * @param The class type to convert the parameter value to. * @return The parameter value converted to the specified class type. * @throws ParseException */ public T get(String name, Class type) throws ParseException { return parse(name, beanSession.getClassMeta(type)); } /** * Same as {@link #get(String, Class)} except returns a default value if not specified. * * @param name The parameter name. * @param def The default value if the parameter was not specified or is null. * @param type The class type to convert the parameter value to. * @param The class type to convert the parameter value to. * @return The parameter value converted to the specified class type. * @throws ParseException */ public T get(String name, T def, Class type) throws ParseException { return parse(name, def, beanSession.getClassMeta(type)); } /** * Same as {@link #get(String, Class)} except for use on multi-part parameters * (e.g. "key=1&key=2&key=3" instead of "key=(1,2,3)") * *

* This method must only be called when parsing into classes of type Collection or array. * * @param name The parameter name. * @param type The class type to convert the parameter value to. * @return The parameter value converted to the specified class type. * @throws ParseException */ public T getAll(String name, Class type) throws ParseException { return parseAll(name, beanSession.getClassMeta(type)); } /** * Returns the specified form data parameter value converted to a POJO using the {@link UrlEncodingParser} * registered with this servlet. * *

Notes:
*
    *
  • Calling this method on URL-Encoded FORM posts causes the body content to be loaded and parsed by the * underlying servlet API. *
  • Use this method if you want to parse into a parameterized Map/Collection object. *
* *
Examples:
*

* // Parse into a linked-list of strings. * List<String> myparam = req.getFormDataParameter("myparam", LinkedList.class, String.class); * * // Parse into a linked-list of linked-lists of strings. * List<List<String>> myparam = req.getFormDataParameter("myparam", LinkedList.class, LinkedList.class, String.class); * * // Parse into a map of string keys/values. * Map<String,String> myparam = req.getFormDataParameter("myparam", TreeMap.class, String.class, String.class); * * // Parse into a map containing string keys and values of lists containing beans. * Map<String,List<MyBean>> myparam = req.getFormDataParameter("myparam", TreeMap.class, String.class, List.class, MyBean.class); *

* * @param name The parameter name. * @param type * The type of object to create. *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} * @param args * The type arguments of the class if it's a collection or map. *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} *
Ignored if the main type is not a map or collection. * @return The parameter value converted to the specified class type. * @throws ParseException */ public T get(String name, Type type, Type...args) throws ParseException { return (T)parse(name, beanSession.getClassMeta(type, args)); } /** * Same as {@link #get(String, Type, Type...)} except for use on multi-part parameters * (e.g. "key=1&key=2&key=3" instead of "key=(1,2,3)") * *

* This method must only be called when parsing into classes of type Collection or array. * * @param name The parameter name. * @param type * The type of object to create. *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} * @param args * The type arguments of the class if it's a collection or map. *
Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, * {@link GenericArrayType} *
Ignored if the main type is not a map or collection. * @return The parameter value converted to the specified class type. * @throws ParseException */ public T getAll(String name, Type type, Type...args) throws ParseException { return (T)parseAll(name, beanSession.getClassMeta(type, args)); } /* Workhorse method */ T parse(String name, T def, ClassMeta cm) throws ParseException { String val = getString(name); if (val == null) return def; return parseValue(val, cm); } /* Workhorse method */ T parse(String name, ClassMeta cm) throws ParseException { String val = getString(name); if (cm.isPrimitive() && (val == null || val.isEmpty())) return cm.getPrimitiveDefault(); return parseValue(val, cm); } /* Workhorse method */ @SuppressWarnings("rawtypes") T parseAll(String name, ClassMeta cm) throws ParseException { String[] p = get(name); if (p == null) return null; if (cm.isArray()) { List c = new ArrayList(); for (int i = 0; i < p.length; i++) c.add(parseValue(p[i], cm.getElementType())); return (T)toArray(c, cm.getElementType().getInnerClass()); } else if (cm.isCollection()) { try { Collection c = (Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new ObjectList()); for (int i = 0; i < p.length; i++) c.add(parseValue(p[i], cm.getElementType())); return (T)c; } catch (ParseException e) { throw e; } catch (Exception e) { // Typically an instantiation exception. throw new ParseException(e); } } throw new ParseException("Invalid call to getParameters(String, ClassMeta). Class type must be a Collection or array."); } private T parseValue(String val, ClassMeta c) throws ParseException { return parser.parse(PartType.FORM_DATA, val, c); } /** * Converts the form data parameters to a readable string. * * @param sorted Sort the form data parameters by name. * @return A JSON string containing the contents of the form data parameters. */ public String toString(boolean sorted) { Map m = (sorted ? new TreeMap() : new LinkedHashMap()); for (Map.Entry e : this.entrySet()) { String[] v = e.getValue(); m.put(e.getKey(), v.length == 1 ? v[0] : v); } return JsonSerializer.DEFAULT_LAX.toString(m); } @Override /* Object */ public String toString() { return toString(false); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy