2016-01-25 19 views
9

Ho il seguente frammento di codice per invocare la chiamata di riposo. Ho circa 8 intestazioni da trasmettere per questa chiamata di riposo. Ma il problema è che è difficile da gestire. Se nel futuro l'elenco delle intestazioni viene aumentato, devo modificare la firma del metodo evaluateChange per includere le intestazioni aggiuntive come metodo params.REST Chiama con l'elenco delle intestazioni

@Path("/v1/restclienturi/") 
@Consumes({ MediaType.APPLICATION_JSON }) 
@Produces({ MediaType.APPLICATION_JSON }) 
public interface RestClient { 

    @POST 
    @Path("/samplecall/evaluate") 
    Response evaluateChange(
      @HeaderParam("HEADER1") String header1, 
      @HeaderParam("HEADER2") String header2, 
      @HeaderParam("HEADER3") String header3, 
      @HeaderParam("HEADER4") String header4, 
      @HeaderParam("HEADER5") String header5, 
      @HeaderParam("HEADER6") String header6, 
      @HeaderParam("HEADER7") String header7, 
      @HeaderParam("HEADER8") String header8, 
      @Context HttpServletResponse response, Request request); 
} 

Si prega di fornire i vostri pensieri o snippet di codice per sistemare questo.

Ho provato il seguente frammento di codice, ma non ha funzionato (dove headerMap contiene tutti gli 8 intestazioni in esso):

@Path("/v1/restclienturi/") 
@Consumes({ MediaType.APPLICATION_JSON }) 
@Produces({ MediaType.APPLICATION_JSON }) 
public interface RestClient { 

    @POST 
    @Path("/samplecall/evaluate") 
    Response evaluateChange(
      @RequestHeader Map<String, String> headerMap, 
      @Context HttpServletResponse response, Request request); 
} 

risposta

4

ho trovato una soluzione utilizzando javax.ws.rs.core.Form:

@Path("/v1/restclienturi/") 
@Consumes({ MediaType.APPLICATION_JSON }) 
@Produces({ MediaType.APPLICATION_JSON }) 
public interface RestClient { 

    @POST 
    @Path("/samplecall/evaluate") 
    Response evaluateChange(
      @Form MyHeader headers, 
      @Context HttpServletResponse response, Request request); 
} 

Il seguente è la myHeader che è un pojo:

public class MyHeader{ 
@HeaderParam("HEADER1") 
    private String header1; 

    @HeaderParam("HEADER2") 
    private String header2; 
..... 
// getters and setters present 
} 

Instantiate myHeader e impostare i valori di trasmetterla al servizio REST come:

MyHeader headers = new MyHeader(); 
headers.setHeader1("HEADER1_VALUE"); 
... 

e chiamare: evaluateChange(headers, null,request);

PROBLEMA: Il problema molto grande con questo approccio è che ogni volta che viene aggiunta una nuova intestazione, è necessario apportare una modifica al codice per impostare e ottenere i valori. Se la soluzione è qualcosa come passare come una colletione, allora non abbiamo quel cambio di codice coinvolto quando vengono aggiunte nuove intestazioni. Mi piace:

Map<String,String> headersMap = new HashMap(); 
headers.put("HEADER1","HEADER1_VALUE"); 
.... 
evaluateChange(headersMap,null,request); 

Sto cercando una soluzione come questa. Ma il codice sopra non ha funzionato. Alla ricerca di suggerimenti.

+0

Hai già selezionato la tua risposta come risposta corretta, hai ancora bisogno di aiuto o no? Sembra in ogni caso che tu stia cercando di implementare qualcosa come una fabbrica. Potresti implementare direttamente lo schema di fabbrica come definito nella teoria. – Rafa

+0

@Rafa: ho trovato la soluzione ma ha ancora un problema come affermato. L'implementazione della fabbrica o qualsiasi altro modello di progettazione non risolve il problema (poiché il servizio REST non accetta le intestazioni quando viene utilizzato un modello di fabbrica). – Arun

+0

@Arun Ho una nuova soluzione per creare intestazioni multiple secondo le tue necessità. per favore controlla [qui] (http://stackoverflow.com/a/35581805/5678086) – Thanga

2

Non esattamente sicuro di quello che vuoi dire, ma se si desidera ottenere tutte le intestazioni come su questo:

public Response evaluateChange(@Context HttpHeaders headers, ...) { 
    String header1 = headers.getRequestHeader("HEADER1").get(0); 
    ... 
} 

trovato un po 'di più su questo codice qui: http://www.mkyong.com/webservices/jax-rs/get-http-header-in-jax-rs/

Edit: Come chiamare il metodo con una mappa di valori-chiave.

public class MapHttpHeaders implements HttpHeaders { 
    private Map<String, String> values; 

    public MapHttpHeaders(Map<String, String> values) { 
     this.values = values; 
    } 

    @Override 
    public String getHeaderString(String key) { 
     return values.get(key); 
    } 

    @Override 
    public List<String> getRequestHeader(String key) { 
     String value = getHeaderString(key); 
     if (value == null) { 
     return null; 
     } else { 
     return asList(value); 
     } 
    } 
    ...and so on... 
} 

E poi basta fare:

evaluateChange(new MapHttpHeaders(values), ...); 
+0

Brautigam: Dalla tua soluzione, dimmi che sto provando a chiamare questa ausc di evaluateChange(). Devo passare le intestazioni a questo metodo. Ho queste intestazioni come hashmap nella mia base di codice. Come si passa a questo metodo (poiché questo metodo si aspetta solo HttpHeaders). Si prega di fornire un codice di esempio. – Arun

+0

Devi solo implementare l'interfaccia HttpHeaders per lavorare da una mappa, vedi sopra la mia modifica. La maggior parte dei metodi non ha bisogno di fare nulla, i più importanti sono mostrati sopra. –

+0

Ho provato l'implementazione di cui sopra, non riesco ancora a passare le intestazioni. Ho provato a scavalcare anche tutti i metodi. Ancora inutile. Qualsiasi suggerimento o idea di come questi HttpHeaders saranno letti sul lato server ... – Arun

2

Impossibile basta iniettare HttpServletRequest e poi usare il suo metodo getHeader (String nome)?

API

@POST 
@Path("/samplecall/evaluate") 
Response evaluateChange(
     @RequestHeader Map<String, String> headerMap, 
     @Context HttpServletResponse response, 
     @Context HttpServletRequest httpRequest, 
     Request request); 

Impl

@Override 
public Response evaluateChange(
     @RequestHeader Map<String, String> headerMap, 
     @Context HttpServletResponse response, 
     @Context HttpServletRequest httpRequest, 
     Request request) { 


    String header1 = httpRequest.getHeader("HEADER1"); 
    ... 

Naturalmente, in questo modo si nasconde parte del contratto per l'attuazione.

+0

Io sono il cliente non il servizio ... Necessario per formare e passare questo HttpServletRequest – Arun

0

Non certo perché si sta tentando un Map e non semplicemente un List:

@Path("/v1/restclienturi/") 
@Consumes({ MediaType.APPLICATION_JSON }) 
@Produces({ MediaType.APPLICATION_JSON }) 
public interface RestClient { 

    @POST 
    @Path("/samplecall/evaluate") 
    Response evaluateChange(
      @HeaderParam("HEADER") List<String> headers, 
      @Context HttpServletResponse response, Request request 
    ); 
} 

Ora non ho testare questo, ma ciò richiederebbe tutti HeaderParams essere chiamati 'header', e saranno/dovrebbero essere memorizzati nel List<String> seguendo l'ordine di occorrenza.

1

È possibile inviare tutte le intestazioni impostate in una MultivaluedHashMap (javax.ws.rs.core.MultivaluedHashMap) al Modulo. questo è un argomento costruttore accettabile per il Form.

MultivaluedMap<String, String> headerMap = new MultivaluedHashMap<String, String>(); 
    headersMap.putSingle("HEADER1","HEADER1_VALUE"); 
    headersMap.putSingle("HEADER2","HEADER1_VALUE"); 
    . 
    . 
    . 
    headersMap.putSingle("HEADER8","HEADER8_VALUE"); 

    evaluateChange(headersMap,null,request); 

e cambiare il tuo evaluateChange come sotto,

Response evaluateChange(
     @Form MultivaluedMap headers, 
     @Context HttpServletResponse response, Request request); 

Spero che questo aiuti .. Buona fortuna !!