Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struts2- URL tag - Hide query String

Tags:

url

tags

struts2

After a lot of research on stackoverflow i'm posting this question as i could not find a solution for the issue.

Requirement Scenario : Update a customer from a list of customers based on each customer id as parameter.

Solution tried: Based on the customer Id received from the jsp, pass it to the Action as Struts2 url tag.

Issue Faced - Query String visible on the URL.
http://foo.com/Struts2Example/getCustomerAction?customerId=2

Questions :

  1. Can we not hide the query string if we use struts Url tag?
  2. If we cannot hide the using query string while using Url tag? what is the alternative for the above scenario.

Code for struts.xml,jsp and action below -

<h2>All Customers Details</h2>

<s:if test="customerList.size() > 0">
    <table border="1px" cellpadding="8px">
        <tr>
            <th>Customer Id</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Age</th>
            <th>Created Date</th>
        </tr>
        <s:iterator value="customerList" status="userStatus">
            <tr>
                <td><s:url var="editCustomer" action="getCustomerAction">
                        <s:param name="customerId" value="%{customerId}" />
                    </s:url>

                    <p>
                        <s:a href="%{editCustomer}">
                            <s:property value="customerId" />
                        </s:a>
                    </p></td>

                <td><s:property value="firstname" /></td>
                <td><s:property value="lastname" /></td>
                <td><s:property value="age" /></td>
                <td><s:date name="createdDate" format="dd/MM/yyyy" /></td>
            </tr>
        </s:iterator>
    </table>
</s:if>
<br />
<br />

struts.xml-

<!-- Get Customer Details - To Pre-Populate the form to update a Customer -->
    <action name="getCustomerAction" method="getCustomerById"
        class="com.hcl.customer.action.CustomerAction">
        <result name="success">pages/customerForm.jsp </result>
    </action>

Customer Action class-

public class CustomerAction extends ActionSupport implements ModelDriven {

Logger logger = Logger.getLogger(CustomerAction.class);

Customer customer = new Customer();

List<Customer> customerList = new ArrayList<Customer>();
CustomerDAO customerDAO = new CustomerDAOImpl();

public Customer getCustomer() {
    return customer;
}

//Set Customer onto Value Stack
public void setCustomer(Customer customer) {
    this.customer = customer;
}

public List<Customer> getCustomerList() {
    return customerList;
}

//Set Customer List onto Value Stack
public void setCustomerList(List<Customer> customerList) {
    this.customerList = customerList;
}

public String execute() throws Exception {
    return SUCCESS;
}

public Object getModel() {
    return customer;
}



// Edit customer details, it will retrieve the records based on customerId
//SkipValidation is used to skip the validate()
@SkipValidation
public String getCustomerById() {

    logger.info("** Customer Id to edit ** " + customer.getCustomerId());

    customer = customerDAO.customerById(customer.getCustomerId());

    return SUCCESS;

}
like image 987
P.D Avatar asked Nov 03 '22 04:11

P.D


1 Answers

Some unordered considerations:

  • use different Actions (with the execute method only), or different Methods of the same Action, to perform different "actions";
  • The name of each Action/Method should match the operation performed and be self-explanatory, for example you should have an editCustomer method (or Action) to edit the customer and a getCustomer method (or Action) to obtain the customer;
  • The GET HTTP method should be used to read data, while the POST HTTP method should be used to send data; every non-reading operation should ideally be performed through POST; using GET to send data is an old bad practice born 20 years ago and never died :/ The reasons to use POST are the hidden URL, a higher load capacity, the ability to send binary data, etc...

That said, an URL like http://foo.com/Struts2Example/getCustomerAction?customerId=2 should be visible (to be bookmarked for example), and ideally should be prettified (REST style, like StackOverflow): something like http://foo.com/Struts2Example/Customer/2/

An URL like http://foo.com/Struts2Example/editCustomerAction?customerId=2 can't work, because you are not passing any other parameter; you know the id of the customer to edit, but not the data to alter... It would become something like: http://foo.com/Struts2Example/editCustomerAction?customerId=2&name=foo&lastname=bar&age=42, that would work, but as said (and as ask in your question) should be hidden, and handled through POST.

If you are printing in the source of the page the IDs, then there should be no need to hide them to the user;

What you need to do is to ensure that the user can't change the IDs outside the range you specified; if you drawed in the page a list of customers with ID {1,2,3} you must block any attempt of the user to alter the id and trying to update the customer with ID = 4... to achieve that, simply store the list of ID in session before populating the page, and check the IDs returned by the page against your list. If they don't match, block the malicious operation.

Hope that helps

like image 145
Andrea Ligios Avatar answered Nov 15 '22 09:11

Andrea Ligios