Struts2 Note

 

0. Create a project by archetype

Reference: http://blog.csdn.net/derek_zhang_/article/details/8142417

 

1. In order to use @Result, it's necessary to add this dependency in Maven's POM:


            org.apache.struts
            struts2-convention-plugin
            ${struts2.version}
        


2. Preparable Interface

You could understand its meaning as stupid as practical.


3. paramsPrepareParamsStack

Take updating scenario for example, some params were sent from front page, included in the Request object, we need one param to retrieve the domain object, once the object is prepared, other params should be used to override the retrieved object for updating.The framework does the override job automatically for us, otherwise we would have to do it manually, thank god. Make sense?


4. ObjectFactory

Quoted from Apache official site: The Struts-Spring Plugin works by overriding the Struts ObjectFactory to enhance the creation of core framework objects. When an object is to be created, it uses the class attribute in the Struts configuration to correspond to the id attribute in the Spring configuration. If not found, the class will try to be created as usual, then be autowired by Spring. In the case of Actions, Spring 2's bean scope feature can be used to scope an Action instance to the session, application, or a custom scope, providing advanced customization above the default per-request scoping.


5. Case: dependencies version collision when integrating Spring 2.5.6 with Hibernate 3.2.6

java.lang.NoClassDefFoundError: org/objectweb/asm/FieldVisitor

This error is caused by Spring-Hibernate integration, spring's asm dependencies collides with hibernate's asm version.

Solution Reference: http://stackoverflow.com/questions/9797334/maven-detect-multiple-versions-of-the-same-dependency


			org.hibernate
			hibernate
			3.2.1.ga
			
				
					asm
					asm
				
				
					asm
					asm-attrs
				
				
					cglib
					cglib
				
			
		

		
			cglib
			cglib-nodep
			2.2
		

6. SEVERE: Dispatcher initialization failed   

Unable to load configuration [unknown location]

LESSON: Look for the 'Caused by' sentence, DO NOT just google 'Struts 2 Unable to load configuration', Seriously! Find the 'Caused by' on screen you would get the more informative description. In my case, one of my result type set to an incorrect value caused the problem, totally different with all scenarios on the internet.

 

7. >>> FilterDispatcher <<< is deprecated!

It's really disappointing that strutsarchetypestarter 2.3.7 still uses FilterDispatcher, so we always get this annoying deprecation warning until we do this replacement:


        action2
        
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
    


8. org.apache.struts2.config.Result cannot be resolved

 Try this:

org.apache.struts2.config.convention.annotation.Result

 

9. The type Validation is deprecated

Since Struts 2.1, class level @Validation annotation is no longer necessary, just remove it, no replacement annotation. We just need to annotate type level for validators.

 

10. Struts 2 Spring Integration Error,  BeanCreationException

Cause: In my case, there is a field in SomeAction named 'service', whereas in the applicationContext.xml it's 'userService', they are not identical name, can't be autowired.

 

11. Since 2.1 CodeBehind plugin has been deprecated in favor of the Convention Plugin.

Reference: http://struts.apache.org/2.1.6/docs/convention-plugin.html

Reference: Rails

 

12. java.io.IOException: Stream closed

Check the jsp content and warnings from console:

Struts2 Note_第1张图片

LESSON: We can't ignore WARNINGs sometimes.

For the first warning, we can handle it via adding a corresponding i18n entry;

For the second, let's look at the action's configuration first:

@ParentPackage("enterEvent")
@Results( value={
    @Result(type= "redirect", location="selectContestants"),
    @Result(name="input", location="/WEB-INF/jsp/event/selectContestants-input.jsp")
})
public class RemoveContestantsAction extends BaseEventAction {
Given that our struts version is 2.3.4, and convention plugin as well, so we couldn't use 'removeContestants', we have to code it as 'remove-contestants', as shown below:


    <%--  --%>
    
LESSON: Take care of the convention!

13. WARNING: Parameter [namespace] is on the excludeParams list of patterns!


14. Unknown Error: No result defined for action xxx

Reference: http://guimingyue.iteye.com/blog/854628


15. SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

Solutions on the internet are all negative for me.

 

16. log4j:WARN No appenders could be found for logger


17. Struts 2 Freemarker Integration

Reference: http://struts.apache.org/2.3.7/docs/using-freemarker-templates.html

To configure the FreeMarker engine, just add a file freemarker.properties to the classpath.

Tags distributed with Struts are automatically made available to FreeMarker templates. To use any tag add "@s." in front of the tag name.

Freemarker Editor Eclipse Plugin

jEdit 4.1 is a Free programmer's text editor written in Java, supports FreeMarker out-of-the-box


18. Struts 2 Debug Tips

(1) Historic: (Deprecated)Make use of

 (2) Comtemtary: One tool is the Struts 2 configuration plugin and the other is the debugging interceptor.

For debugging interceptor:  Add '?debug=browser' to your url.

Reference: http://struts.apache.org/2.3.7/docs/debugging-struts.html

(3) Eclipse Debug Setting

Prerequisities: struts2-starter-archetype 2.3.7

Critical point is jetty setting:

Struts2 Note_第2张图片

Aftermath, at last, we are able to add break points and debug, enjoy your journey!


19. Exception: There is no Action mapped for namespace

Case URL:

http://localhost:8086/simple/saveSupplierHeader.action
Caused by incorrect action name in struts.xml. Struts.xml:

 
			/tpl/supplier-header-input.ftl
			/tpl/supplier-header-input.ftl
			/tpl/supplier-header-success.ftl
		

Solution: change the name to 'saveSupplierHeader'


20. The Model in Action Object is null

public class SupplierHeaderAction extends ActionSupport implements ModelDriven {

	private static final long serialVersionUID = 1L;

	@Autowired  
	protected SupplierHeaderService supplierHeaderServiceImpl;
	
	protected SupplierHeader sh;
	
	public SupplierHeader getModel(){
		return sh;
	}
	
	public String inputSupplierHeader(){
		return INPUT;
	}
	
	public String saveSupplierHeader(){
		supplierHeaderServiceImpl.save(sh);
		return SUCCESS;
	}
}
when saveSupplierHeader() method executed, the sh is null, debug it!

Here is the struts.xml:


		
			
			/tpl/index.ftl
		
		 
			/jsp/index.jsp
			/jsp/helloWorld.jsp
		
		 
			/jsp/index.jsp
			/tpl/hello-freemarker.ftl
		
		 
			/tpl/supplier-header-input.ftl
			/tpl/supplier-header-input.ftl
			/tpl/supplier-header-success.ftl
			
		 
			/tpl/supplier-header-input.ftl
		
	

Below is quoted from :

Providing access to the domain object is achieved by creating a model driven action. There are two steps to enable this process. The first step is to have the action extend the ModelDriven interface. The second step is to ensure that the modelDriven interceptor is being applied to the action implementing the ModelDriven interface.

If there is a strange bug, a NullPointerException, or data not present on a property that should have an assigned value, there is a good chance that it may have something to do with interceptors. Interceptors in the wrong order or missing interceptors are problems that can have consequences that do not point immediately to interceptors. The good news is that spelling mistakes in the interceptor or interceptor-ref attributes names will cause the initialization of Struts2 to be aborted, and the problem can be quickly rectified.

Now, we see that struts-default's default interceptor stack doesn't include modeldriven interceptor, so we add it first.

After adding Preparable, we got another situation: the sh is not null, but all the fields' value is null!

Struts2 Note_第3张图片

this empty sh object was created by prepare(), so the fact is ParametersInterceptor failed to set form values into ValueStack.

At last, found the bug was caused by lack of model's getter/setter, add this snippet to action then joy comes:

public SupplierHeader getSh() {
		return sh;
	}

	public void setSh(SupplierHeader sh) {
		this.sh = sh;
	}





你可能感兴趣的:(J2EE)