2013-02-19 15 views
5

Po wielu badaniach nad stackoverflow, publikuję to pytanie, ponieważ nie mogłem znaleźć rozwiązania problemu.Struts2- Tag URL - Ukryj zapytanie Ciąg

Scenariusz wymagania: Zaktualizuj klienta z listy klientów na podstawie każdego identyfikatora klienta jako parametru.

Wypróbowane rozwiązanie: Na podstawie identyfikatora klienta otrzymanego z jsp należy przekazać go do tagu Działanie jako adres URL Struts2.

Problem w obliczu - Ciąg zapytania widoczny na URL.
http://foo.com/Struts2Example/getCustomerAction?customerId=2

Pytania:

  1. Czy nie możemy ukryć ciąg kwerendy jeśli używamy poprzeczne tag URL?
  2. Jeśli nie możemy ukryć ciągu zapytania przy użyciu tagu Url? jaka jest alternatywa dla powyższego scenariusza.

Kod struts.xml, JSP i działania poniżej -

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

Action klienta wykładowa

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

Dlaczego chcesz ukryć identyfikator? Jeśli przechowujesz wartość po stronie klienta, każdy może spojrzeć na źródło i je pobrać. Możesz oczywiście użyć postu do wysłania wyniku, ale rozważ, czy użytkownik musi dodać zakładkę do strony. Naprawdę odpowiedź brzmi: bezpieczeństwo ... czy ten użytkownik powinien mieć dostęp do tego identyfikatora klienta? Jeśli nie, to nie powinno być w żadnym wypadku dozwolone. – Quaternion

+0

Tak, użytkownik może dodać do zakładek taką stronę ... ale pytanie brzmi: "Zaktualizuj klienta", podczas gdy URL to '** getCustomer ** Action? CustomerId = 2' ... coś dziwnego tutaj:> –

+0

@AndreaLigios - Scenariusz polega na tym, że aby zaktualizować klienta, będę musiał wstępnie wypełnić jego dane w formularzu. Aby pobrać szczegóły, przeszukuję bazę danych za pomocą identyfikatora customerId. –

Odpowiedz

1

Niektóre nieuporządkowane kwestie:

  • stosowanie różnych działań (metodą wykonania tylko) lub różnymi metodami tej samej Akcji, do wykonywania różnych "działań";
  • Nazwa każdego działania/Metoda powinna odpowiadać operację wykonano i być oczywiste, na przykład należy mieć editCustomer metody (lub działania) do edycji klient i getCustomer metody (lub działania) do uzyskać klienta;
  • Do odczytania danych należy użyć metody GET HTTP, a do wysyłania danych należy użyć metody HTTP POST; każda operacja niezrozumienia powinna być przeprowadzana przez POST; używanie GET do wysyłania danych to stara, zła praktyka, która urodziła się 20 lat temu i nigdy nie umarła:/Przyczyny używania POST to ukryty adres URL, większa ładowność, możliwość wysyłania danych binarnych, itp ...

Powiedział, adresem URL jak http://foo.com/Struts2Example/getCustomerAction?customerId=2 powinny być widoczne (do zakładek na przykład), a najlepiej powinna być prettified (styl REST, jak StackOverflow): coś http://foo.com/Struts2Example/Customer/2/

Adres URL jak http://foo.com/Struts2Example/editCustomerAction?customerId=2 może” t działa, ponieważ nie przekazujesz żadnego innego parametru; znasz identyfikator klienta do edycji, ale nie dane do zmiany ... Stanie się coś takiego: http://foo.com/Struts2Example/editCustomerAction?customerId=2&name=foo&lastname=bar&age=42, które działałoby, ale jak powiedziano (i jako pytanie w pytaniu) powinno być ukryte i obsługiwane przez POST.

Jeśli drukujesz na stronie source s, nie powinno być potrzeby ukrywania ich przed użytkownikiem;

Należy upewnić się, że użytkownik nie może zmienić wartości ID s poza podanym zakresem; jeśli narysowałeś na stronie listę klientów z ID {1,2,3} musisz zablokować wszelkie próby zmiany przez użytkownika id i próby aktualizacji klienta za pomocą ID = 4 ... aby to osiągnąć, po prostu zapisz listę ID w session przed zapełnianie strony i sprawdzanie wartości zwróconych przez stronę na liście. Jeśli nie pasują, zablokuj złośliwą operację.

Nadzieję, że pomaga

+0

Dzięki za poświęcony czas i odpowiedź. Całkowicie zgadzam się z tobą, w.r.t Nazwy akcji/metod. Po drugie, ponieważ nie używam tutaj formularza, jak mogę wysłać żądanie do akcji jako POST w moim przypadku? doceń swoją pomoc tutaj. –

+0

Nie ma za co; dlaczego nie używasz formularza? I dlaczego nie możesz go dodać? Są za darmo :) –

+0

Scenariusz nie był jednak potrzebny. Ponieważ nie znajduję żadnej innej odpowiedniej opcji, równie dobrze mogę pójść z formularzem. Również dlatego, że są one bezpłatne;) Dziękuję ludziom za odpowiedź na moje pytania. Doceniam to! Twoje zdrowie! –

1

Alternatywą jest zaszyfrować identyfikator użytkownika i wysłać go z powrotem do strony HTML. Utrzymuj mapowanie po stronie klienta. Po przesłaniu żądania POST zaszyfrowaną wartość. Logika deszyfrowania/encypresji będzie po stronie serwera. To doda dodatkowy narzut na system, ale jest to dość przyzwoity kompromis do wydajności w porównaniu z bezpieczeństwem. Proszę również spojrzeć na @ jcryption.org/info, jego w ramach licencji MIT i GPL.

Prostszym rozwiązaniem jest przekonwertowanie tego działania na akcję "POST", aby wartości zostały przekazane w treści żądania HTTP. Jeśli jej pośrednictwem protokołu HTTPS, to być szyfrowane jednak nadal można zrobić odnośnika id użytkownika za pomocą Narzędzi Google dla programistów bądź tryb IE9 Developer

+0

przekonwertował komentarze na odpowiedź. Zignoruj ​​komentarze. Dzięki – user1428716

+0

@ user1428716- dzięki za odpowiedź. W tym scenariuszu, skoro nie używam formy rozpórki, jak mogę osiągnąć/przekonwertować żądanie na POST? –