问题
I'm creating an application using Struts2 and I want to have friendly URLs.
Si, i set the following params in struts.xml:
<constant name="struts.action.extension" value=""/>
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
and my actions:
<package name="notes" namespace="/notes" extends="struts-default">
<action name="/*/*" class="action.ViewNoteAction">
<param name="title">{1}</param>
<param name="id">{2}</param>
<result>/Notes/view.jsp</result>
</action>
</package>
But, when i hit the url http://localhost/notes/welcome/1 i got this error:
Servlet.service() for servlet default threw exception java.lang.NullPointerException
any idea? What I'm doing wrong? I'm using struts 2.0.14... Thanks.
Here is the full stack trace:
WARNING: StandardWrapperValve[default]: PWC1406: Servlet.service() for servlet default threw exception java.lang.NullPointerException at com.opensymphony.xwork2.config.impl.ActionConfigMatcher.convertActionConfig(ActionConfigMatcher.java:168) at com.opensymphony.xwork2.config.impl.ActionConfigMatcher.match(ActionConfigMatcher.java:144) at com.opensymphony.xwork2.config.impl.DefaultConfiguration$RuntimeConfigurationImpl.getActionConfig(DefaultConfiguration.java:297) at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:169) at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:41) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:494) at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:422) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:332) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:233) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954) at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170) at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) at com.sun.grizzly.ContextTask.run(ContextTask.java:69) at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) at java.lang.Thread.run(Thread.java:637)
Thanks.
回答1:
- I don't think you need the leading slash in your action name (e.g., */* instead of /*/*)
- Have you set any breakpoints in your action to see if the NPE is occurring before or after your action?
- What action mapper are you using?
Also, on the off chance you are just trying to get Ruby on Rails style friendly URLs, have you looked into the Struts2 Rest Plugin?
Edit: As I suspected, this appears to be related to the leading slash in your action mapping. I was able to reproduce this exception under Tomcat. The leading slash is causing Struts2 to not be able to properly parse the ActionConfig for that action and is producing the NPE. Changing the action name to */* resolved the issue and properly invoked ViewNotesAction with a title of welcome and an id of 1.
回答2:
If you don't want to re-work your application to use Rest directly, you could also use URL-rewriting tools like http://ocpsoft.com/prettyfaces/, which allows you to do URL-mappings directly on top of an existing application.
You just configure something like this in the pretty-config.xml file:
<url-mapping>
<pattern value="/my/restful/url" />
<view-id value="/my/existing/url" />
</url-mapping>
Or if you want to rewrite parameters, you can do this:
<url-mapping>
<pattern value="/my/restful/url/#{param}" />
<view-id value="/my/existing/url" />
</url-mapping>
And this means that any urls looking like /my/existing/url?param=value
will now become:
/my/restful/url/value
So it's easy to add on to your current apps.
来源:https://stackoverflow.com/questions/3993174/dynamic-urls-on-struts-2