2013-02-19 216 views
5

經過大量的關於stackoverflow的研究後,我張貼這個問題,因爲我找不到解決方案的問題。Struts2的URL標記 - 隱藏查詢字符串

要求方案:根據每個客戶ID作爲參數更新客戶列表。

解決方案嘗試:基於從jsp接收到的客戶ID,將它作爲Struts2 url標記傳遞給Action。

面臨的問題 - 在URL上可見的查詢字符串。
http://foo.com/Struts2Example/getCustomerAction?customerId=2

問題:

  1. 難道我們不能隱藏查詢字符串,如果我們使用Struts網址標記?
  2. 如果我們在使用Url標籤時無法隱藏使用的查詢字符串?上述場景的替代方案是什麼?

代碼struts.xml中,JSP和下面的動作 -

<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> 

客戶採取的行動接收機類

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; 

} 
+0

爲什麼你想隱藏ID?如果您將值存儲在客戶端,任何人都可以查看源代碼並獲取它。您當然可以使用帖子發送結果,但考慮用戶需要爲頁面添加書籤。真的,答案是安全性......該用戶是否應該能夠訪問該客戶ID?如果不是,那麼在任何情況下都不應該被允許。 – Quaternion 2013-02-19 05:41:31

+0

是的,用戶可以像這樣收藏一個頁面......但問題是,當URL爲'** getCustomer ** Action?customerId = 2'時,更新客戶'...這裏有點奇怪:> – 2013-02-19 09:06:33

+0

@AndreaLigios - 情景是,爲了更新客戶,我必須在表單上預先填寫他的詳細信息。要獲取細節,我使用customerId查詢數據庫。 – 2013-02-19 10:48:13

回答

1

一些無序因素仍然這樣做的用戶ID查找:

  • 使用不同的操作(execute方法只) ,或同一動作的不同方法來執行不同的「動作」;
  • 每個動作的名稱/方法應該匹配操作中執行和不言自明,例如,你應該有一個editCustomer方法(或動作),以編輯客戶和一個getCustomer方法(或動作),以獲得客戶;
  • GET HTTP方法應該用於讀取數據,而POST HTTP方法應該用於發送數據;每個非讀操作理應通過POST執行;使用GET發送數據是20年前出現的一種古老的不良習慣,從未死亡:/使用POST的原因是隱藏的URL,更高的負載能力,發送二進制數據的能力等等。

也就是說,像http://foo.com/Struts2Example/getCustomerAction?customerId=2的網址應清晰可見(被書籤爲例),理想的應該美化(REST風格,像StackOverflow的):像http://foo.com/Struts2Example/Customer/2/

的URL像http://foo.com/Struts2Example/editCustomerAction?customerId=2可以」因爲你沒有傳遞任何其他參數;你知道要編輯的客戶的ID,但不是要更改的數據... 它會變成類似於: http://foo.com/Struts2Example/editCustomerAction?customerId=2&name=foo&lastname=bar&age=42,這將工作,但正如說(和作爲你的問題問)應該隱藏,並處理通過POST。

如果您要在頁面的source中打印ID,那麼應該不需要將它們隱藏給用戶;

您需要做的是確保用戶不能在指定的範圍之外更改ID; 如果您在頁面中繪製了ID {1,2,3}的客戶列表,您必須阻止用戶嘗試更改標識並試圖用ID = 4更新客戶...以實現此目的,只需將ID列表存儲在session之前填充頁面,然後檢查頁面返回的ID對列表。如果它們不匹配,則阻止惡意操作。

希望有幫助

+0

感謝您的時間和答覆。完全同意你的意見,w.r.t行動/方法名稱。其次,由於我沒有在這裏使用表格,我如何在POST中提出請求作爲POST?感謝您的幫助。 – 2013-02-19 11:16:25

+0

不客氣,你爲什麼不使用表格?爲什麼你不能添加一個?他們是免費的:) – 2013-02-19 11:31:04

+0

雖然情況並不需要一個表格。由於我沒有找到任何其他選擇適合我不如去與表單。此外,因爲他們是免費的;)謝謝大家對我的疑問的迴應。欣賞它!乾杯! – 2013-02-20 14:11:11

1

一種替代,是加密userID並將其發送回HTML頁面。維護客戶端的映射。當您提交請求時,POST POST加密值。解密/加密邏輯將在服務器端。 這會增加系統的開銷,但與安全性相比,這對性能有足夠的權衡。 也請看看@ jcryption.org/info,它在MIT和GPL許可下。

更簡單的解決方案是將其轉換爲「POST」操作,以便值在HTTP請求正文內傳遞。如果它通過HTTPS,它會被加密,但是你可以使用谷歌開發者工具或IE9開發模式

+0

將註釋轉換爲答案。請忽略評論。謝謝 – user1428716 2013-02-19 04:21:01

+0

@ user1428716-感謝您的回答。在這種情況下,因爲即時通訊不使用struts表單,我如何實現/轉換請求到POST? – 2013-02-19 11:18:26