Skip to content

Commit 64fc4c2

Browse files
committed
revised EvalTag implementation
1 parent 4ae1709 commit 64fc4c2

File tree

6 files changed

+81
-79
lines changed

6 files changed

+81
-79
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import org.springframework.validation.Validator;
3939
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
4040
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
41-
import org.springframework.web.servlet.handler.ConversionServiceHandlerInterceptor;
41+
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
4242
import org.springframework.web.servlet.handler.MappedInterceptor;
4343
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
4444
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
@@ -112,7 +112,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) {
112112
annAdapterDef.getPropertyValues().add("messageConverters", getMessageConverters(source));
113113
String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef);
114114

115-
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceHandlerInterceptor.class);
115+
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
116116
csInterceptorDef.setSource(source);
117117
csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
118118
RootBeanDefinition mappedCsInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2008 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@
1717
package org.springframework.web.servlet.handler;
1818

1919
import java.io.IOException;
20-
2120
import javax.servlet.ServletException;
2221
import javax.servlet.http.HttpServletRequest;
2322
import javax.servlet.http.HttpServletResponse;
@@ -26,28 +25,35 @@
2625
import org.springframework.util.Assert;
2726

2827
/**
29-
* Interceptor that places the configured {@link ConversionService} in request scope so it's available during request processing.
30-
* Mainly for use within JSP tags such as the spring:eval tag.
31-
* The request attribute name is "org.springframework.core.convert.ConversionService", the value of ConversionService.class.getName();
28+
* Interceptor that places the configured {@link ConversionService} in request scope
29+
* so it's available during request processing. The request attribute name is
30+
* "org.springframework.core.convert.ConversionService", the value of
31+
* <code>ConversionService.class.getName()</code>.
32+
*
33+
* <p>Mainly for use within JSP tags such as the spring:eval tag.
34+
*
3235
* @author Keith Donald
3336
* @since 3.0.1
3437
*/
35-
public class ConversionServiceHandlerInterceptor extends HandlerInterceptorAdapter {
38+
public class ConversionServiceExposingInterceptor extends HandlerInterceptorAdapter {
3639

3740
private final ConversionService conversionService;
3841

42+
3943
/**
40-
* Creates a new {@link ConversionServiceHandlerInterceptor}.
41-
* @param conversionService the conversion service to export to request scope when this interceptor is invoked.
44+
* Creates a new {@link ConversionServiceExposingInterceptor}.
45+
* @param conversionService the conversion service to export to request scope when this interceptor is invoked
4246
*/
43-
public ConversionServiceHandlerInterceptor(ConversionService conversionService) {
47+
public ConversionServiceExposingInterceptor(ConversionService conversionService) {
4448
Assert.notNull(conversionService, "The ConversionService may not be null");
4549
this.conversionService = conversionService;
4650
}
4751

52+
4853
@Override
49-
public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
54+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
5055
throws ServletException, IOException {
56+
5157
request.setAttribute(ConversionService.class.getName(), this.conversionService);
5258
return true;
5359
}
Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,12 +17,9 @@
1717
package org.springframework.web.servlet.tags;
1818

1919
import java.io.IOException;
20-
2120
import javax.servlet.jsp.JspException;
2221
import javax.servlet.jsp.PageContext;
23-
import javax.servlet.jsp.el.ELException;
2422

25-
import org.springframework.beans.BeansException;
2623
import org.springframework.core.convert.ConversionService;
2724
import org.springframework.expression.AccessException;
2825
import org.springframework.expression.EvaluationContext;
@@ -41,27 +38,36 @@
4138
/**
4239
* JSP tag for evaluating expressions with the Spring Expression Language (SpEL).
4340
* Supports the standard JSP evaluation context consisting of implicit variables and scoped attributes.
44-
*
41+
*
4542
* @author Keith Donald
4643
* @since 3.0.1
4744
*/
4845
public class EvalTag extends HtmlEscapingAwareTag {
4946

50-
private ExpressionParser expressionParser;
51-
52-
private String expression;
47+
private final ExpressionParser expressionParser = new SpelExpressionParser();
48+
49+
private EvaluationContext evaluationContext;
50+
51+
private Expression expression;
5352

5453
private String var;
5554

5655
private int scope = PageContext.PAGE_SCOPE;
5756

5857
private boolean javaScriptEscape = false;
5958

59+
60+
@Override
61+
public void setPageContext(PageContext pageContext) {
62+
super.setPageContext(pageContext);
63+
this.evaluationContext = createEvaluationContext(pageContext);
64+
}
65+
6066
/**
6167
* Set the expression to evaluate.
6268
*/
6369
public void setExpression(String expression) {
64-
this.expression = expression;
70+
this.expression = this.expressionParser.parseExpression(expression);
6571
}
6672

6773
/**
@@ -89,55 +95,51 @@ public void setJavaScriptEscape(String javaScriptEscape) throws JspException {
8995
ExpressionEvaluationUtils.evaluateBoolean("javaScriptEscape", javaScriptEscape, this.pageContext);
9096
}
9197

98+
9299
@Override
93100
public int doStartTagInternal() throws JspException {
94-
this.expressionParser = new SpelExpressionParser();
95101
return EVAL_BODY_INCLUDE;
96102
}
97103

98104
@Override
99105
public int doEndTag() throws JspException {
100-
Expression expression = this.expressionParser.parseExpression(this.expression);
101-
EvaluationContext context = createEvaluationContext();
102106
if (this.var == null) {
103107
try {
104-
String result = expression.getValue(context, String.class);
108+
String result = this.expression.getValue(this.evaluationContext, String.class);
105109
result = isHtmlEscape() ? HtmlUtils.htmlEscape(result) : result;
106110
result = this.javaScriptEscape ? JavaScriptUtils.javaScriptEscape(result) : result;
107111
pageContext.getOut().print(result);
108112
}
109-
catch (IOException e) {
110-
throw new JspException(e);
113+
catch (IOException ex) {
114+
throw new JspException(ex);
111115
}
112116
}
113117
else {
114-
Object result = expression.getValue(context);
115-
pageContext.setAttribute(var, result, scope);
118+
Object result = this.expression.getValue(this.evaluationContext);
119+
pageContext.setAttribute(this.var, result, this.scope);
116120
}
117121
return EVAL_PAGE;
118122
}
119-
120-
private EvaluationContext createEvaluationContext() {
123+
124+
125+
private EvaluationContext createEvaluationContext(PageContext pageContext) {
121126
StandardEvaluationContext context = new StandardEvaluationContext();
122-
context.addPropertyAccessor(new JspPropertyAccessor(this.pageContext));
123-
ConversionService conversionService = getConversionService();
127+
context.addPropertyAccessor(new JspPropertyAccessor(pageContext));
128+
ConversionService conversionService = getConversionService(pageContext);
124129
if (conversionService != null) {
125130
context.setTypeConverter(new StandardTypeConverter(conversionService));
126131
}
127132
return context;
128133
}
129134

130-
private ConversionService getConversionService() {
131-
try {
132-
return (ConversionService) this.pageContext.getRequest().getAttribute(ConversionService.class.getName());
133-
} catch (BeansException e) {
134-
return null;
135-
}
135+
private ConversionService getConversionService(PageContext pageContext) {
136+
return (ConversionService) pageContext.getRequest().getAttribute(ConversionService.class.getName());
136137
}
137-
138+
139+
138140
private static class JspPropertyAccessor implements PropertyAccessor {
139141

140-
private PageContext pageContext;
142+
private final PageContext pageContext;
141143

142144
public JspPropertyAccessor(PageContext pageContext) {
143145
this.pageContext = pageContext;
@@ -147,42 +149,35 @@ public Class<?>[] getSpecificTargetClasses() {
147149
return null;
148150
}
149151

150-
public boolean canRead(EvaluationContext context, Object target,
151-
String name) throws AccessException {
152-
Object implicitVar = resolveImplicitVariable(name);
153-
if (implicitVar != null) {
154-
return true;
155-
}
156-
return this.pageContext.findAttribute(name) != null;
152+
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
153+
return (resolveImplicitVariable(name) != null || this.pageContext.findAttribute(name) != null);
157154
}
158155

159-
public TypedValue read(EvaluationContext context, Object target,
160-
String name) throws AccessException {
156+
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
161157
Object implicitVar = resolveImplicitVariable(name);
162158
if (implicitVar != null) {
163159
return new TypedValue(implicitVar);
164160
}
165161
return new TypedValue(this.pageContext.findAttribute(name));
166162
}
167163

168-
public boolean canWrite(EvaluationContext context, Object target,
169-
String name) throws AccessException {
164+
public boolean canWrite(EvaluationContext context, Object target, String name) {
170165
return false;
171166
}
172167

173-
public void write(EvaluationContext context, Object target,
174-
String name, Object newValue) throws AccessException {
168+
public void write(EvaluationContext context, Object target, String name, Object newValue) {
175169
throw new UnsupportedOperationException();
176170
}
177171

178172
private Object resolveImplicitVariable(String name) throws AccessException {
179173
try {
180174
return this.pageContext.getVariableResolver().resolveVariable(name);
181-
} catch (ELException e) {
182-
throw new AccessException("Unexpected exception occurred accessing '" + name + "' as an implicit variable", e);
175+
}
176+
catch (Exception ex) {
177+
throw new AccessException(
178+
"Unexpected exception occurred accessing '" + name + "' as an implicit variable", ex);
183179
}
184180
}
185-
186181
}
187182

188-
}
183+
}

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/tags/RequestContextAwareTag.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
2-
* Copyright 2002-2006 the original author or authors.
3-
*
2+
* Copyright 2002-2010 the original author or authors.
3+
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -47,9 +47,10 @@
4747
*/
4848
public abstract class RequestContextAwareTag extends TagSupport implements TryCatchFinally {
4949

50-
/** {@link javax.servlet.jsp.PageContext} attribute for page-level
50+
/**
51+
* {@link javax.servlet.jsp.PageContext} attribute for page-level
5152
* {@link RequestContext} instance.
52-
* */
53+
*/
5354
public static final String REQUEST_CONTEXT_PAGE_ATTRIBUTE =
5455
"org.springframework.web.servlet.tags.REQUEST_CONTEXT";
5556

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2010 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -53,7 +53,7 @@
5353
import org.springframework.web.context.support.GenericWebApplicationContext;
5454
import org.springframework.web.servlet.HandlerExecutionChain;
5555
import org.springframework.web.servlet.ModelAndView;
56-
import org.springframework.web.servlet.handler.ConversionServiceHandlerInterceptor;
56+
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
5757
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
5858
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
5959
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@@ -115,8 +115,8 @@ public void testDefaultConfig() throws Exception {
115115

116116
HandlerExecutionChain chain = mapping.getHandler(request);
117117
assertEquals(2, chain.getInterceptors().length);
118-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
119-
ConversionServiceHandlerInterceptor interceptor = (ConversionServiceHandlerInterceptor) chain.getInterceptors()[1];
118+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
119+
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[1];
120120
interceptor.preHandle(request, response, handler);
121121
assertSame(appContext.getBean(ConversionService.class), request.getAttribute(ConversionService.class.getName()));
122122

@@ -144,8 +144,8 @@ public void testCustomConversionService() throws Exception {
144144

145145
HandlerExecutionChain chain = mapping.getHandler(request);
146146
assertEquals(2, chain.getInterceptors().length);
147-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
148-
ConversionServiceHandlerInterceptor interceptor = (ConversionServiceHandlerInterceptor) chain.getInterceptors()[1];
147+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
148+
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[1];
149149
interceptor.preHandle(request, response, handler);
150150
assertSame(appContext.getBean("conversionService"), request.getAttribute(ConversionService.class.getName()));
151151

@@ -194,7 +194,7 @@ public void testInterceptors() throws Exception {
194194

195195
HandlerExecutionChain chain = mapping.getHandler(request);
196196
assertEquals(4, chain.getInterceptors().length);
197-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
197+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
198198
assertTrue(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor);
199199
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
200200

@@ -225,7 +225,7 @@ public void testBeanDecoration() throws Exception {
225225

226226
HandlerExecutionChain chain = mapping.getHandler(request);
227227
assertEquals(4, chain.getInterceptors().length);
228-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
228+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
229229
assertTrue(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor);
230230
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
231231
LocaleChangeInterceptor interceptor = (LocaleChangeInterceptor) chain.getInterceptors()[2];
@@ -249,7 +249,7 @@ public void testViewControllers() throws Exception {
249249

250250
HandlerExecutionChain chain = mapping.getHandler(request);
251251
assertEquals(4, chain.getInterceptors().length);
252-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
252+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
253253
assertTrue(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor);
254254
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
255255

@@ -263,7 +263,7 @@ public void testViewControllers() throws Exception {
263263
request.setMethod("GET");
264264
chain = mapping2.getHandler(request);
265265
assertEquals(4, chain.getInterceptors().length);
266-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
266+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
267267
assertTrue(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor);
268268
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
269269
ModelAndView mv = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());
@@ -272,7 +272,7 @@ public void testViewControllers() throws Exception {
272272
request.setRequestURI("/bar");
273273
chain = mapping2.getHandler(request);
274274
assertEquals(4, chain.getInterceptors().length);
275-
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceHandlerInterceptor);
275+
assertTrue(chain.getInterceptors()[1] instanceof ConversionServiceExposingInterceptor);
276276
assertTrue(chain.getInterceptors()[2] instanceof LocaleChangeInterceptor);
277277
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
278278
ModelAndView mv2 = adapter.handle(request, new MockHttpServletResponse(), chain.getHandler());

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/tags/EvalTagTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
2-
* Copyright 2008 the original author or authors.
3-
*
2+
* Copyright 2002-2010 the original author or authors.
3+
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

0 commit comments

Comments
 (0)