18
18
*/
19
19
package org .apache .struts2 .interceptor ;
20
20
21
+ import org .apache .logging .log4j .Level ;
21
22
import org .apache .logging .log4j .LogManager ;
22
23
import org .apache .logging .log4j .Logger ;
23
24
import org .apache .struts2 .ActionInvocation ;
24
25
import org .apache .struts2 .config .entities .ExceptionMappingConfig ;
25
26
import org .apache .struts2 .dispatcher .HttpParameters ;
27
+ import org .apache .struts2 .inject .Inject ;
28
+ import org .apache .struts2 .ognl .ThreadAllowlist ;
26
29
27
30
import java .util .List ;
28
31
import java .util .Map ;
42
45
* you make this interceptor the first interceptor on the stack, ensuring that it has full access to catch any
43
46
* exception, even those caused by other interceptors.
44
47
* </p>
45
- *
48
+ * <p>
46
49
* <!-- END SNIPPET: description -->
47
50
*
48
51
* <p><u>Interceptor parameters:</u></p>
49
- *
52
+ * <p>
50
53
* <!-- START SNIPPET: parameters -->
51
54
*
52
55
* <ul>
64
67
* The parameters above enables us to log all thrown exceptions with stacktace in our own logfile,
65
68
* and present a friendly webpage (with no stacktrace) to the end user.
66
69
* </p>
67
- *
70
+ * <p>
68
71
* <!-- END SNIPPET: parameters -->
69
72
*
70
73
* <p><u>Extending the interceptor:</u></p>
71
- *
74
+ * <p>
72
75
* <!-- START SNIPPET: extending -->
73
76
* <p>
74
77
* If you want to add custom handling for publishing the Exception, you may override
@@ -158,11 +161,17 @@ public class ExceptionMappingInterceptor extends AbstractInterceptor {
158
161
159
162
private static final Logger LOG = LogManager .getLogger (ExceptionMappingInterceptor .class );
160
163
164
+ private transient ThreadAllowlist threadAllowlist ;
165
+
161
166
protected Logger categoryLogger ;
162
167
protected boolean logEnabled = false ;
163
168
protected String logCategory ;
164
169
protected String logLevel ;
165
170
171
+ @ Inject
172
+ public void setThreadAllowlist (ThreadAllowlist threadAllowlist ) {
173
+ this .threadAllowlist = threadAllowlist ;
174
+ }
166
175
167
176
public boolean isLogEnabled () {
168
177
return logEnabled ;
@@ -173,20 +182,20 @@ public void setLogEnabled(boolean logEnabled) {
173
182
}
174
183
175
184
public String getLogCategory () {
176
- return logCategory ;
177
- }
185
+ return logCategory ;
186
+ }
178
187
179
- public void setLogCategory (String logCatgory ) {
180
- this .logCategory = logCatgory ;
181
- }
188
+ public void setLogCategory (String logCategory ) {
189
+ this .logCategory = logCategory ;
190
+ }
182
191
183
- public String getLogLevel () {
184
- return logLevel ;
185
- }
192
+ public String getLogLevel () {
193
+ return logLevel ;
194
+ }
186
195
187
- public void setLogLevel (String logLevel ) {
188
- this .logLevel = logLevel ;
189
- }
196
+ public void setLogLevel (String logLevel ) {
197
+ this .logLevel = logLevel ;
198
+ }
190
199
191
200
@ Override
192
201
public String intercept (ActionInvocation invocation ) throws Exception {
@@ -200,13 +209,16 @@ public String intercept(ActionInvocation invocation) throws Exception {
200
209
}
201
210
List <ExceptionMappingConfig > exceptionMappings = invocation .getProxy ().getConfig ().getExceptionMappings ();
202
211
ExceptionMappingConfig mappingConfig = this .findMappingFromExceptions (exceptionMappings , e );
203
- if (mappingConfig != null && mappingConfig .getResult ()!= null ) {
212
+ if (mappingConfig != null && mappingConfig .getResult () != null ) {
204
213
Map <String , String > mappingParams = mappingConfig .getParams ();
205
214
// create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable
206
215
HttpParameters parameters = HttpParameters .create (mappingParams ).build ();
207
216
invocation .getInvocationContext ().withParameters (parameters );
208
217
result = mappingConfig .getResult ();
209
- publishException (invocation , new ExceptionHolder (e ));
218
+ ExceptionHolder holder = new ExceptionHolder (e );
219
+ threadAllowlist .allowClass (holder .getClass ());
220
+ threadAllowlist .allowClass (e .getClass ());
221
+ publishException (invocation , holder );
210
222
} else {
211
223
throw e ;
212
224
}
@@ -221,55 +233,45 @@ public String intercept(ActionInvocation invocation) throws Exception {
221
233
* @param e the exception to log.
222
234
*/
223
235
protected void handleLogging (Exception e ) {
224
- if (logCategory != null ) {
225
- if (categoryLogger == null ) {
226
- // init category logger
227
- categoryLogger = LogManager .getLogger (logCategory );
228
- }
229
- doLog (categoryLogger , e );
230
- } else {
231
- doLog (LOG , e );
232
- }
236
+ if (logCategory != null ) {
237
+ if (categoryLogger == null ) {
238
+ // init category logger
239
+ categoryLogger = LogManager .getLogger (logCategory );
240
+ }
241
+ doLog (categoryLogger , e );
242
+ } else {
243
+ doLog (LOG , e );
244
+ }
233
245
}
234
246
235
247
/**
236
248
* Performs the actual logging.
237
249
*
238
- * @param logger the provided logger to use.
239
- * @param e the exception to log.
250
+ * @param logger the provided logger to use.
251
+ * @param e the exception to log.
240
252
*/
241
253
protected void doLog (Logger logger , Exception e ) {
242
- if (logLevel == null ) {
243
- logger .debug (e .getMessage (), e );
244
- return ;
245
- }
254
+ if (logLevel == null ) {
255
+ logger .debug (e .getMessage (), e );
256
+ return ;
257
+ }
246
258
247
- if ("trace" .equalsIgnoreCase (logLevel )) {
248
- logger .trace (e .getMessage (), e );
249
- } else if ("debug" .equalsIgnoreCase (logLevel )) {
250
- logger .debug (e .getMessage (), e );
251
- } else if ("info" .equalsIgnoreCase (logLevel )) {
252
- logger .info (e .getMessage (), e );
253
- } else if ("warn" .equalsIgnoreCase (logLevel )) {
254
- logger .warn (e .getMessage (), e );
255
- } else if ("error" .equalsIgnoreCase (logLevel )) {
256
- logger .error (e .getMessage (), e );
257
- } else if ("fatal" .equalsIgnoreCase (logLevel )) {
258
- logger .fatal (e .getMessage (), e );
259
- } else {
260
- throw new IllegalArgumentException ("LogLevel [" + logLevel + "] is not supported" );
261
- }
259
+ Level level = Level .getLevel (logLevel );
260
+ if (level == null ) {
261
+ throw new IllegalArgumentException ("LogLevel [" + logLevel + "] is not supported" );
262
+ }
263
+ logger .log (level , e .getMessage (), e );
262
264
}
263
265
264
266
/**
265
267
* Try to find appropriate {@link ExceptionMappingConfig} based on provided Throwable
266
268
*
267
269
* @param exceptionMappings list of defined exception mappings
268
- * @param t caught exception
270
+ * @param t caught exception
269
271
* @return appropriate mapping or null
270
272
*/
271
273
protected ExceptionMappingConfig findMappingFromExceptions (List <ExceptionMappingConfig > exceptionMappings , Throwable t ) {
272
- ExceptionMappingConfig config = null ;
274
+ ExceptionMappingConfig config = null ;
273
275
// Check for specific exception mappings.
274
276
if (exceptionMappings != null ) {
275
277
int deepest = Integer .MAX_VALUE ;
@@ -288,15 +290,15 @@ protected ExceptionMappingConfig findMappingFromExceptions(List<ExceptionMapping
288
290
* Return the depth to the superclass matching. 0 means ex matches exactly. Returns -1 if there's no match.
289
291
* Otherwise, returns depth. Lowest depth wins.
290
292
*
291
- * @param exceptionMapping the mapping classname
292
- * @param t the cause
293
+ * @param exceptionMapping the mapping classname
294
+ * @param t the cause
293
295
* @return the depth, if not found -1 is returned.
294
296
*/
295
297
public int getDepth (String exceptionMapping , Throwable t ) {
296
298
return getDepth (exceptionMapping , t .getClass (), 0 );
297
299
}
298
300
299
- private int getDepth (String exceptionMapping , Class exceptionClass , int depth ) {
301
+ private int getDepth (String exceptionMapping , Class <?> exceptionClass , int depth ) {
300
302
if (exceptionClass .getName ().contains (exceptionMapping )) {
301
303
// Found it!
302
304
return depth ;
@@ -312,7 +314,7 @@ private int getDepth(String exceptionMapping, Class exceptionClass, int depth) {
312
314
* Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack.
313
315
* Subclasses may override this to customize publishing.
314
316
*
315
- * @param invocation The invocation to publish Exception for.
317
+ * @param invocation The invocation to publish Exception for.
316
318
* @param exceptionHolder The exceptionHolder wrapping the Exception to publish.
317
319
*/
318
320
protected void publishException (ActionInvocation invocation , ExceptionHolder exceptionHolder ) {
0 commit comments