diff --git a/.gitignore b/.gitignore
index 42889b4..e7ab442 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-.idea/
-target/
+.idea/
+target/
*.iml
/.settings/
/.classpath
diff --git a/README.md b/README.md
index 7f927ea..65378b6 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,34 @@ The following reflects the default settings.
+
+
+## Version 2.3.24 - Spring support & type conversion handling
+Since version 2.3.24 , this plugin provided accessibility for spring bean , and Struts2 type conversion error handling support.
+
+### How to use Spring Bean
+
+* use result type : thymeleaf-spring
+* in html template : ${beans.[BeanName]}
+* struts.properties : struts.thymeleaf.templateEngineName=spring
+
+### Hot to use Type conversion support field.
+
+use this namespace : sth
+this diarect supported value and errorclass such as thymeleaf spring support.
+
+Code example :
+
+
+
+ ...
+
+ ...
+
## License
@@ -84,4 +111,4 @@ The following reflects the default settings.
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.
\ No newline at end of file
+ limitations under the License.
diff --git a/changelog.2.3.22.txt b/changelog.2.3.22.txt
new file mode 100644
index 0000000..3d5f64d
--- /dev/null
+++ b/changelog.2.3.22.txt
@@ -0,0 +1,6 @@
+ChangeLog 2.3.16.3 -> 2.3.22
+
+* Add new result-type : "thymeleaf-spring" , usable to spring beans '${beans.(beanName)}'.
+* Add new diarect for Struts2 Type convertion error output, namespace and attribute 'sth:field'.
+* Add support output Struts2 'Field error' , named 'field'. An example usage ${field['task']}.
+
diff --git a/pom.xml b/pom.xml
index f4d97fe..0c1dfda 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,94 +1,120 @@
- 4.0.0
- org.codework
- struts2-thymeleaf-plugin
- jar
- 2.3.16.3
- struts2-thymeleaf-plugin
- http://www.codework.org/struts2-thymeleaf-plugin
-
- UTF-8
- 2.3.16.3
- 2.1.3.RELEASE
-
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+ org.codework
+ struts2-thymeleaf-plugin
+ jar
+ ${struts2.version}
+ struts2-thymeleaf-plugin
+ http://www.codework.org/struts2-thymeleaf-plugin
+
+ UTF-8
+ 2.3.24
+ 2.1.4.RELEASE
+ 4.1.6.RELEASE
+
-
-
- maven-org-repo
- http://repo1.maven.org/maven2/
-
-
-
-
- javax.servlet
- servlet-api
- 2.5
- provided
-
+
+
+ maven-org-repo
+ http://repo1.maven.org/maven2/
+
+
+ apache.snapshots
+ ASF Maven 2 Snapshot
+ https://repository.apache.org/content/groups/snapshots/
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
+
-
- org.apache.struts
- struts2-core
- ${struts2.version}
-
+
+ org.apache.struts
+ struts2-core
+ ${struts2.version}
+
-
- org.thymeleaf
- thymeleaf
- ${thymeleaf.version}
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- true
- 256m
- 512m
- 1.6
- 1.6
- ${project.build.sourceEncoding}
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
-
-
- attach-sources
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-idea-plugin
- 2.2
-
- true
- true
- 1.6
- 1.6
-
-
-
-
+
+ org.thymeleaf
+ thymeleaf
+ ${thymeleaf.version}
+
+
+ org.thymeleaf
+ thymeleaf-spring4
+ ${thymeleaf.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ org.springframework
+ spring-web
+ ${spring.version}
+
+
+ org.springframework
+ spring-webmvc
+ ${spring.version}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ true
+ 256m
+ 512m
+ 1.6
+ 1.6
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-idea-plugin
+ 2.2
+
+ true
+ true
+ 1.6
+ 1.6
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/codework/struts/plugins/thymeleaf/StrutsContext.java b/src/main/java/org/codework/struts/plugins/thymeleaf/StrutsContext.java
index b4e71e5..81a4cb2 100644
--- a/src/main/java/org/codework/struts/plugins/thymeleaf/StrutsContext.java
+++ b/src/main/java/org/codework/struts/plugins/thymeleaf/StrutsContext.java
@@ -15,17 +15,18 @@
*/
package org.codework.struts.plugins.thymeleaf;
-import com.opensymphony.xwork2.LocaleProvider;
-import org.thymeleaf.context.WebContext;
-
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.thymeleaf.context.WebContext;
+
+import com.opensymphony.xwork2.LocaleProvider;
+
/**
* Extends the {@link org.thymeleaf.context.WebContext} to provide access to the
* Struts action.
- *
+ *
* For actions that implement the {@link com.opensymphony.xwork2.LocaleProvider}
* interface (i.e., actions that extend ActionSupport), the action's locale will
* be used in this context. Otherwise, the context will default to the
diff --git a/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafResult.java b/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafResult.java
index e093974..71b537f 100644
--- a/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafResult.java
+++ b/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafResult.java
@@ -15,17 +15,18 @@
*/
package org.codework.struts.plugins.thymeleaf;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.Result;
-import com.opensymphony.xwork2.inject.Inject;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.codework.struts.plugins.thymeleaf.spi.TemplateEngineProvider;
import org.thymeleaf.TemplateEngine;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.Result;
+import com.opensymphony.xwork2.inject.Inject;
/**
* Renders a Thymeleaf template as the result of invoking a Struts action.
@@ -40,7 +41,7 @@ public class ThymeleafResult implements Result {
/**
* The result parameter name to set the name of the template to.
- *
+ *
* IMPORTANT! Struts2 will look for this field reflectively to determine which
* parameter is the default. This allows us to have a simplified result
* configuration. Don't remove it!
diff --git a/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafSpringResult.java b/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafSpringResult.java
new file mode 100644
index 0000000..fc95a03
--- /dev/null
+++ b/src/main/java/org/codework/struts/plugins/thymeleaf/ThymeleafSpringResult.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2013 Steven Benitez.
+ *
+ * Licensed 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.codework.struts.plugins.thymeleaf;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.ServletActionContext;
+import org.apache.struts2.StrutsConstants;
+import org.codework.struts.plugins.thymeleaf.spi.TemplateEngineProvider;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.context.WebApplicationContext;
+import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.spring4.context.SpringWebContext;
+
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.LocaleProvider;
+import com.opensymphony.xwork2.Result;
+import com.opensymphony.xwork2.inject.Inject;
+
+/**
+ * Renders a Thymeleaf-Spring template as the result of invoking a Struts action.
+ *
+ * @author Steven Benitez ( Update A-pZ )
+ */
+public class ThymeleafSpringResult implements Result {
+ private String defaultEncoding = "UTF-8";
+ private TemplateEngineProvider templateEngineProvider;
+ private String templateName;
+
+ /**
+ * The result parameter name to set the name of the template to.
+ *
+ * IMPORTANT! Struts2 will look for this field reflectively to determine
+ * which parameter is the default. This allows us to have a simplified
+ * result configuration. Don't remove it!
+ */
+ public static final String DEFAULT_PARAM = "templateName";
+
+ /** instance name of struts2-action */
+ public static final String ACTION_VARIABLE_NAME = "action";
+
+ /** field errors */
+ public static final String FIELD_ERRORS_NAME ="field";
+
+ /** struts2 convertion errors fields and value */
+ public static final String OVERRIDES_NAME = "overrides";
+
+ public ThymeleafSpringResult() {
+ }
+
+ public ThymeleafSpringResult(String templateName) {
+ this.templateName = templateName;
+ }
+
+ @Override
+ public void execute(ActionInvocation actionInvocation) throws Exception {
+ TemplateEngine templateEngine = templateEngineProvider.get();
+
+ HttpServletRequest request = ServletActionContext.getRequest();
+ HttpServletResponse response = ServletActionContext.getResponse();
+ ServletContext servletContext = ServletActionContext
+ .getServletContext();
+
+ Object action = actionInvocation.getAction();
+
+ // Action instance put to Thymeleaf context.
+ Map variables = bindStrutsContest(action);
+
+ // Locale by Struts2-Action.
+ Locale locale = ((LocaleProvider) action).getLocale();
+
+ // Spring-ApplicationContext.
+ //ApplicationContext appctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
+ ApplicationContext appctx =
+ (ApplicationContext)servletContext.getAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
+
+ // Use SpringWebContext( by Thymeleaf-spring plugin. )
+ SpringWebContext context = new SpringWebContext(request, response,
+ servletContext, locale, variables, appctx);
+
+ // response to TemplateEngine.
+ response.setContentType("text/html");
+ response.setCharacterEncoding(defaultEncoding);
+ templateEngine.process(templateName, context, response.getWriter());
+ }
+
+ @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
+ public void setDefaultEncoding(String defaultEncoding) {
+ this.defaultEncoding = defaultEncoding;
+ }
+
+ @Inject
+ public void setTemplateEngineProvider(
+ TemplateEngineProvider templateEngineProvider) {
+ this.templateEngineProvider = templateEngineProvider;
+ }
+
+ public void setTemplateName(String templateName) {
+ this.templateName = templateName;
+ }
+
+ /**
+ * Binding Struts2 action and context, and field-errors list binding "field".
+ * @param action Action instance
+ * @return ContextMap
+ */
+ Map bindStrutsContest(Object action) {
+ Map variables = new HashMap();
+ variables.put(ACTION_VARIABLE_NAME, action);
+
+ if ( action instanceof ActionSupport) {
+ ActionSupport actSupport = (ActionSupport)action;
+
+ // Struts2 field errors.( Map)
+ Map> fieldErrors = actSupport.getFieldErrors();
+ variables.put(FIELD_ERRORS_NAME, fieldErrors);
+ }
+
+ return variables;
+ }
+}
diff --git a/src/main/java/org/codework/struts/plugins/thymeleaf/diarect/FieldAttrProcessor.java b/src/main/java/org/codework/struts/plugins/thymeleaf/diarect/FieldAttrProcessor.java
new file mode 100644
index 0000000..ea72d24
--- /dev/null
+++ b/src/main/java/org/codework/struts/plugins/thymeleaf/diarect/FieldAttrProcessor.java
@@ -0,0 +1,88 @@
+/**
+ *
+ */
+package org.codework.struts.plugins.thymeleaf.diarect;
+
+import java.util.Map;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.thymeleaf.Arguments;
+import org.thymeleaf.dom.Element;
+import org.thymeleaf.processor.attr.AbstractAttributeModifierAttrProcessor;
+import org.thymeleaf.standard.processor.attr.AbstractStandardSingleAttributeModifierAttrProcessor;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * Thymeleaf extensions,field.
+ * @author A-pZ
+ *
+ */
+public class FieldAttrProcessor extends AbstractStandardSingleAttributeModifierAttrProcessor {
+ public static final int ATTR_PRECEDENCE = 1010;
+ public static final String ATTR_NAME = "value";
+
+ public FieldAttrProcessor() {
+ super(ATTR_NAME);
+ }
+
+ protected String getTargetAttributeValue(Arguments arguments, Element element, String attributeName)
+ {
+ String attributeValue = super.getTargetAttributeValue(arguments, element, attributeName);
+
+ String name = element.getAttributeValueFromNormalizedName("name");
+ String type = element.getAttributeValueFromNormalizedName("type");
+ return processOverridesValue(name,attributeValue);
+ }
+
+ /**
+ * If Type-Convertion Error found at Struts2, overwrite request-parameter same name.
+ *
+ * @param name parameter-name
+ * @param value thymeleaf parameter-value
+ * @return request-parameter-value(if convertion error occurs,return from struts2 , not else thymeleaf.)
+ */
+ protected String processOverridesValue(String name , String value) {
+ ActionContext ctx = ActionContext.getContext();
+ ValueStack stack = ctx.getValueStack();
+ Map