2013-02-19 11 views
5

Dopo molte ricerche su StackOverflow, sto postando questa domanda perché non sono riuscito a trovare una soluzione per il problema.Struts2- Tag URL - Nascondi query String

Scenario di requisito: aggiornare un cliente da un elenco di clienti in base a ciascun ID cliente come parametro.

Soluzione provata: in base all'ID cliente ricevuto da jsp, passarlo all'azione come tag url Struts2.

Problema - Stringa di query visibile nell'URL.
http://foo.com/Struts2Example/getCustomerAction?customerId=2

Domande:

  1. Possiamo non nascondere la stringa di query se usiamo puntoni tag URL?
  2. Se non è possibile nascondere l'utilizzo della stringa di query durante l'utilizzo del tag Url? qual è l'alternativa per lo scenario sopra.

Codice per struts.xml, jsp e l'azione al di sotto -

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

Azione clienti Aula

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

Perché vuoi nascondere l'id? Se si memorizza il valore sul lato client, chiunque può consultare l'origine e ottenerlo. Puoi ovviamente utilizzare post per inviare il risultato, tuttavia considera la necessità per l'utente di aggiungere un segnalibro alla pagina. La risposta è davvero la sicurezza ... questo utente dovrebbe essere in grado di accedere a questo ID cliente? In caso contrario, non dovrebbe essere consentito in nessun caso. – Quaternion

+0

Sì, l'utente può aggiungere un segnalibro a una pagina del genere ... ma la domanda dice "Aggiorna un cliente" mentre l'URL è "** getCustomer ** Azione? CustomerId = 2' ... qualcosa di strano qui:> –

+0

@AndreaLigios - Lo scenario è, per aggiornare un cliente, dovrò pre-popolare i suoi dettagli sul modulo. Per recuperare i dettagli, interrogo il database con il cliente. –

risposta

1

Alcune considerazioni non ordinate:

  • uso diverse azioni (con il metodo execute solo) , o metodi diversi della stessa azione, per eseguire diverse "azioni";
  • Il nome di ogni azione/metodo deve corrispondere l'operazione eseguita e di essere auto-esplicativo, ad esempio, si dovrebbe avere un metodo editCustomer (o azione) per modificare il cliente e un metodo getCustomer (o azione) per ottenere il cliente;
  • Il metodo GET HTTP deve essere utilizzato per leggere i dati, mentre il metodo POST HTTP deve essere utilizzato per inviare i dati; ogni operazione di non lettura dovrebbe essere idealmente eseguita tramite POST; usare GET per inviare dati è una vecchia cattiva pratica nata 20 anni fa e mai morta:/I motivi per usare POST sono l'URL nascosto, una maggiore capacità di carico, la possibilità di inviare dati binari, ecc ...

Detto questo, un URL come http://foo.com/Struts2Example/getCustomerAction?customerId=2 deve essere visibile (da segnalibro per esempio), e idealmente dovrebbe essere prettified (stile REST, come StackOverflow): qualcosa di simile http://foo.com/Struts2Example/Customer/2/

Un URL come http://foo.com/Struts2Example/editCustomerAction?customerId=2 puo' lavoro, perché non stai passando nessun altro parametro; conosci l'id del cliente da modificare, ma non i dati da modificare ... Sarebbe qualcosa di simile: http://foo.com/Struts2Example/editCustomerAction?customerId=2&name=foo&lastname=bar&age=42, che funzionerebbe, ma come detto (e come chiedere nella tua domanda) dovrebbe essere nascosto e gestito attraverso il POST.

Se si stampa nello source della pagina ID s, non è necessario nasconderli all'utente;

Quello che dovete fare è garantire che l'utente non possa cambiare il ID s al di fuori dell'intervallo specificato; se nella pagina è presente un elenco di clienti con ID {1,2,3} è necessario bloccare qualsiasi tentativo dell'utente di modificare l'id e provare ad aggiornare il cliente con ID = 4 ... per ottenere ciò, è sufficiente memorizzare l'elenco di ID in session prima compilare la pagina e controllare i valori ID restituiti dalla pagina rispetto all'elenco. Se non corrispondono, bloccare l'operazione dannosa.

Speranza che aiuti

+0

Grazie per il tuo tempo e la risposta. Totalmente d'accordo con te, w.r.t Nomi di azione/metodo. In secondo luogo, dal momento che non sto usando un modulo qui, come posso rendere la richiesta all'azione come POST nel mio caso? apprezza il tuo aiuto qui. –

+0

Prego; perché non stai usando un modulo? E perché non puoi aggiungerne uno? Sono gratis :) –

+0

Tuttavia lo scenario non aveva bisogno di un modulo. Dal momento che non sto trovando alcuna altra opzione adatta potrei anche andare con un modulo. Inoltre dal momento che sono gratuiti;) Grazie gente per la risposta alle mie domande. Apprezzalo! Saluti! –

1

Un'alternativa, è per crittografare l'ID utente e inviarlo di nuovo alla pagina HTML. Mantenere il mapping sul lato client. Quando si invia la richiesta, POST il valore crittografato. La logica di decrittazione/encoding sarà sul lato server. Questo aggiungerà un sovraccarico sul sistema, ma questo è un compromesso abbastanza decente rispetto alle prestazioni rispetto alla sicurezza. Si prega inoltre di dare un'occhiata @ jcryption.org/info, è sotto licenza MIT e GPL.

Una soluzione più semplice è quella di convertire questo in azione "POST" in modo che i valori siano passati all'interno del corpo della richiesta HTTP. Se la sua su HTTPS, sarebbe criptata tuttavia si può ancora fare la ricerca id utente utilizzando strumenti di sviluppo di Google o Modalità sviluppatore IE9

+0

ha convertito i commenti in risposta. Si prega di ignorare i commenti. Grazie – user1428716

+0

@ user1428716- grazie per la risposta. In questo scenario, dal momento che non sto usando un modulo puntini, come posso ottenere/convertire la richiesta in POST? –