001/* 002 * Copyright 2002-2012 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 * https://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 org.springframework.web.portlet.bind; 018 019import javax.portlet.PortletRequest; 020 021import org.springframework.beans.MutablePropertyValues; 022import org.springframework.validation.BindException; 023import org.springframework.web.bind.WebDataBinder; 024import org.springframework.web.multipart.MultipartRequest; 025import org.springframework.web.portlet.util.PortletUtils; 026 027/** 028 * Special {@link org.springframework.validation.DataBinder} to perform data binding 029 * from portlet request parameters to JavaBeans, including support for multipart files. 030 * 031 * <p>See the DataBinder/WebDataBinder superclasses for customization options, 032 * which include specifying allowed/required fields, and registering custom 033 * property editors. 034 * 035 * <p>Can also be used for manual data binding in custom web controllers: 036 * for example, in a plain Portlet Controller implementation. Simply instantiate 037 * a PortletRequestDataBinder for each binding process, and invoke {@code bind} 038 * with the current PortletRequest as argument: 039 * 040 * <pre class="code"> 041 * MyBean myBean = new MyBean(); 042 * // apply binder to custom target object 043 * PortletRequestDataBinder binder = new PortletRequestDataBinder(myBean); 044 * // register custom editors, if desired 045 * binder.registerCustomEditor(...); 046 * // trigger actual binding of request parameters 047 * binder.bind(request); 048 * // optionally evaluate binding errors 049 * Errors errors = binder.getErrors(); 050 * ...</pre> 051 * 052 * @author Juergen Hoeller 053 * @author John A. Lewis 054 * @since 2.0 055 * @see #bind(javax.portlet.PortletRequest) 056 * @see #registerCustomEditor 057 * @see #setAllowedFields 058 * @see #setRequiredFields 059 * @see #setFieldMarkerPrefix 060 */ 061public class PortletRequestDataBinder extends WebDataBinder { 062 063 /** 064 * Create a new PortletRequestDataBinder instance, with default object name. 065 * @param target the target object to bind onto (or {@code null} 066 * if the binder is just used to convert a plain parameter value) 067 * @see #DEFAULT_OBJECT_NAME 068 */ 069 public PortletRequestDataBinder(Object target) { 070 super(target); 071 } 072 073 /** 074 * Create a new PortletRequestDataBinder instance. 075 * @param target the target object to bind onto (or {@code null} 076 * if the binder is just used to convert a plain parameter value) 077 * @param objectName the name of the target object 078 */ 079 public PortletRequestDataBinder(Object target, String objectName) { 080 super(target, objectName); 081 } 082 083 084 /** 085 * Bind the parameters of the given request to this binder's target, 086 * also binding multipart files in case of a multipart request. 087 * <p>This call can create field errors, representing basic binding 088 * errors like a required field (code "required"), or type mismatch 089 * between value and bean property (code "typeMismatch"). 090 * <p>Multipart files are bound via their parameter name, just like normal 091 * HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property, 092 * invoking a "setUploadedFile" setter method. 093 * <p>The type of the target property for a multipart file can be MultipartFile, 094 * byte[], or String. The latter two receive the contents of the uploaded file; 095 * all metadata like original file name, content type, etc are lost in those cases. 096 * @param request request with parameters to bind (can be multipart) 097 * @see org.springframework.web.portlet.multipart.MultipartActionRequest 098 * @see org.springframework.web.multipart.MultipartFile 099 * @see #bind(org.springframework.beans.PropertyValues) 100 */ 101 public void bind(PortletRequest request) { 102 MutablePropertyValues mpvs = new PortletRequestParameterPropertyValues(request); 103 MultipartRequest multipartRequest = PortletUtils.getNativeRequest(request, MultipartRequest.class); 104 if (multipartRequest != null) { 105 bindMultipart(multipartRequest.getMultiFileMap(), mpvs); 106 } 107 doBind(mpvs); 108 } 109 110 /** 111 * Treats errors as fatal. 112 * <p>Use this method only if it's an error if the input isn't valid. 113 * This might be appropriate if all input is from dropdowns, for example. 114 * @throws PortletRequestBindingException subclass of PortletException on any binding problem 115 */ 116 public void closeNoCatch() throws PortletRequestBindingException { 117 if (getBindingResult().hasErrors()) { 118 throw new PortletRequestBindingException( 119 "Errors binding onto object '" + getBindingResult().getObjectName() + "'", 120 new BindException(getBindingResult())); 121 } 122 } 123 124}