001/* 002 * Copyright 2002-2018 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.bind; 018 019import java.util.Arrays; 020import java.util.Iterator; 021import java.util.List; 022import java.util.Map; 023 024import org.springframework.util.Assert; 025import org.springframework.util.ObjectUtils; 026import org.springframework.util.StringUtils; 027 028/** 029 * {@link ServletRequestBindingException} subclass that indicates an unsatisfied 030 * parameter condition, as typically expressed using an {@code @RequestMapping} 031 * annotation at the {@code @Controller} type level. 032 * 033 * @author Juergen Hoeller 034 * @since 3.0 035 * @see org.springframework.web.bind.annotation.RequestMapping#params() 036 */ 037@SuppressWarnings("serial") 038public class UnsatisfiedServletRequestParameterException extends ServletRequestBindingException { 039 040 private final List<String[]> paramConditions; 041 042 private final Map<String, String[]> actualParams; 043 044 045 /** 046 * Create a new UnsatisfiedServletRequestParameterException. 047 * @param paramConditions the parameter conditions that have been violated 048 * @param actualParams the actual parameter Map associated with the ServletRequest 049 */ 050 public UnsatisfiedServletRequestParameterException(String[] paramConditions, Map<String, String[]> actualParams) { 051 super(""); 052 this.paramConditions = Arrays.<String[]>asList(paramConditions); 053 this.actualParams = actualParams; 054 } 055 056 /** 057 * Create a new UnsatisfiedServletRequestParameterException. 058 * @param paramConditions all sets of parameter conditions that have been violated 059 * @param actualParams the actual parameter Map associated with the ServletRequest 060 * @since 4.2 061 */ 062 public UnsatisfiedServletRequestParameterException(List<String[]> paramConditions, 063 Map<String, String[]> actualParams) { 064 065 super(""); 066 Assert.notEmpty(paramConditions, "Parameter conditions must not be empty"); 067 this.paramConditions = paramConditions; 068 this.actualParams = actualParams; 069 } 070 071 072 @Override 073 public String getMessage() { 074 StringBuilder sb = new StringBuilder("Parameter conditions "); 075 int i = 0; 076 for (String[] conditions : this.paramConditions) { 077 if (i > 0) { 078 sb.append(" OR "); 079 } 080 sb.append("\""); 081 sb.append(StringUtils.arrayToDelimitedString(conditions, ", ")); 082 sb.append("\""); 083 i++; 084 } 085 sb.append(" not met for actual request parameters: "); 086 sb.append(requestParameterMapToString(this.actualParams)); 087 return sb.toString(); 088 } 089 090 /** 091 * Return the parameter conditions that have been violated or the first group 092 * in case of multiple groups. 093 * @see org.springframework.web.bind.annotation.RequestMapping#params() 094 */ 095 public final String[] getParamConditions() { 096 return this.paramConditions.get(0); 097 } 098 099 /** 100 * Return all parameter condition groups that have been violated. 101 * @since 4.2 102 * @see org.springframework.web.bind.annotation.RequestMapping#params() 103 */ 104 public final List<String[]> getParamConditionGroups() { 105 return this.paramConditions; 106 } 107 108 /** 109 * Return the actual parameter Map associated with the ServletRequest. 110 * @see javax.servlet.ServletRequest#getParameterMap() 111 */ 112 public final Map<String, String[]> getActualParams() { 113 return this.actualParams; 114 } 115 116 117 private static String requestParameterMapToString(Map<String, String[]> actualParams) { 118 StringBuilder result = new StringBuilder(); 119 for (Iterator<Map.Entry<String, String[]>> it = actualParams.entrySet().iterator(); it.hasNext();) { 120 Map.Entry<String, String[]> entry = it.next(); 121 result.append(entry.getKey()).append('=').append(ObjectUtils.nullSafeToString(entry.getValue())); 122 if (it.hasNext()) { 123 result.append(", "); 124 } 125 } 126 return result.toString(); 127 } 128 129}