Search code examples
javaurlstruts2clean-urls

Clean url-s in Struts2


Hi i am beginner to struts2. If i post an URL like https://stackoverflow.com/questions/25658104 I want to get value 25658104

It must be done without any parameter. not as https://stackoverflow.com/questions?qid=25658104

Is there any way to get content based on the value passed between /myvalue/

if I post https://stackoverflow.com/questions/myvalue1/-->redirects to a page and loads values corresponding to myvalue1 (from DB)

if I post https://stackoverflow.com/questions/myvalue2/-->redirects to a page and loads values corresponding to myvalue2(from DB)

I found it in SO site navigation based on the values passed between SO it navigates .How can i use it in Struts2

My question is similar to URL rewriting with PHP but i want to do it in struts2

EDIT

struts.xml

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<constant name="struts.custom.i18n.resources" value="ApplicationResources" />
<constant name="struts.multipart.maxSize" value="104857600" />


<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.patternMatcher" value="username"/>

<bean type="com.opensymphony.xwork2.util.PatternMatcher" name="username" class="com.opensymphony.xwork2.util.NamedVariablePatternMatcher"/>

<package name="default" extends="struts-default" namespace="/">

    <result-types>
        <result-type name="json" default="false" class="org.test.struts.controller.JSONResult" />
    </result-types>

    <action name="login" class="org.test.struts.controller.LoginAction"  method="execute">
        <result name="success">Welcome.jsp</result>
        <result name="error">Login.jsp</result>
    </action>

    <action name="profiles/{username}" class="org.test.struts.controller.ViewProfileAction">
        <result name="input">profile.jsp</result>
    </action>




    <action name="getJson" class="org.test.struts.controller.JsonTestAction">
      <result type="stream">
        <param name="contentType">text/html</param>
        <param name="inputName">inputStream</param>
     </result>
   </action>

   <action name="getJsonObj" class="org.test.struts.controller.JsonTest">
      <result type="stream">
        <param name="contentType">text/html</param>
        <param name="inputName">inputStream</param>
     </result>
   </action>

   <action name="getJsonObject" class="org.test.struts.controller.JsonObjectRet">
      <result name="success" type="json">
                 <param name="target">startswith</param>
                 <param name="targetObjectClass">java.lang.String</param>
      </result>
   </action>


    <action name="upload">
        <result>/UploadFile.jsp</result>
    </action>
    <action name="UploadFile" class="org.test.struts.fileupload.controller.UploadFileAction">
        <param name="filesPath">myfiles</param>
        <result name="success">/UploadFileSuccess.jsp</result>
        <result name="input">/UploadFile.jsp</result>

        <interceptor-ref name="defaultStack">
            <param name="fileUpload.maximumSize">10485760</param>
            <param name="fileUpload.allowedTypes">text/plain,image/jpeg</param>
        </interceptor-ref>

    </action>


</package>
</struts>

Action class

import com.opensymphony.xwork2.ActionSupport;

public class ViewProfileAction extends ActionSupport{
  private String username;

  public String getUsername() {
    return username;
}


public String execute() {
    // look up the appropriate user by username and
    // expose the user to the JSP with a getUser() method.
      System.out.println(username);
      return INPUT;
  }


  public void setUsername(String username) {
    this.username = username;
  }
}

Solution

  • Change this

    <constant name="struts.patternMatcher" value="username"/>
    
    <bean type="com.opensymphony.xwork2.util.PatternMatcher" name="username" class="com.opensymphony.xwork2.util.NamedVariablePatternMatcher"/>
    

    to this, using the regex patternMatcher:

    <constant name="struts.patternMatcher" value="regex"/>
    

    And of course add a result for your Action other than the input one !! Like

    <action name="profiles/{username}" class="org.test.struts.controller.ViewProfileAction">
        <result name="success">profile.jsp</result>
        <result name="input">profile.jsp</result>
    </action>
    

    And return SUCCESS from Action instead of INPUT.

    INPUT is an automated result returned by Workflow Interceptor when input errors occour, and the Action is not even reached (read a detailed answer about it)