Ich verwende Commons HttpClient, um einen http-Aufruf eines Spring-Servlets durchzuführen. Ich muss ein paar Parameter in die Abfragezeichenfolge einfügen. Also mache ich folgendes:
HttpRequestBase request = new HttpGet(url);
HttpParams params = new BasicHttpParams();
params.setParameter("key1", "value1");
params.setParameter("key2", "value2");
params.setParameter("key3", "value3");
request.setParams(params);
HttpClient httpClient = new DefaultHttpClient();
httpClient.execute(request);
Allerdings, wenn ich versuche, den Parameter im Servlet mit zu lesen
((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest().getParameter("key");
es gibt null zurück. Tatsächlich ist die parameterMap vollständig leer. Wenn ich die Parameter vor dem Erstellen der HttpGet-Anforderung manuell an die URL anhänge, sind die Parameter im Servlet verfügbar. Das Gleiche gilt, wenn ich das Servlet vom Browser aus über die URL mit angehängtem queryString aufrufe.
Was ist der Fehler hier? In httpclient 3.x verfügte GetMethod über eine setQueryString () -Methode zum Anhängen des Querystrings. Was ist das Äquivalent in 4.x?
quelle
Ich benutze httpclient 4.4.
Für die Solr-Abfrage habe ich den folgenden Weg verwendet und es hat funktioniert.
NameValuePair nv2 = new BasicNameValuePair("fq","(active:true) AND (category:Fruit OR category1:Vegetable)"); nvPairList.add(nv2); NameValuePair nv3 = new BasicNameValuePair("wt","json"); nvPairList.add(nv3); NameValuePair nv4 = new BasicNameValuePair("start","0"); nvPairList.add(nv4); NameValuePair nv5 = new BasicNameValuePair("rows","10"); nvPairList.add(nv5); HttpClient client = HttpClientBuilder.create().build(); HttpGet request = new HttpGet(url); URI uri = new URIBuilder(request.getURI()).addParameters(nvPairList).build(); request.setURI(uri); HttpResponse response = client.execute(request); if (response.getStatusLine().getStatusCode() != 200) { } BufferedReader br = new BufferedReader( new InputStreamReader((response.getEntity().getContent()))); String output; System.out.println("Output .... "); String respStr = ""; while ((output = br.readLine()) != null) { respStr = respStr + output; System.out.println(output); }
quelle
http://myserver/apipath
. Bei der Initialisierung wurde URIBuilder nur verwendethttp://myserver
und ignoriert/apipath
. Der URI wurde extern bereitgestellt, daher wollte ich ihn nicht manuell analysieren, nur um URIBuilder zu verwenden.Dieser Ansatz ist in Ordnung, funktioniert jedoch nicht, wenn Sie Parameter dynamisch abrufen, manchmal 1, 2, 3 oder mehr, genau wie bei einer SOLR-Suchabfrage (zum Beispiel).
Hier ist eine flexiblere Lösung. Roh, kann aber verfeinert werden.
public static void main(String[] args) { String host = "localhost"; String port = "9093"; String param = "/10-2014.01?description=cars&verbose=true&hl=true&hl.simple.pre=<b>&hl.simple.post=</b>"; String[] wholeString = param.split("\\?"); String theQueryString = wholeString.length > 1 ? wholeString[1] : ""; String SolrUrl = "http://" + host + ":" + port + "/mypublish-services/carclassifications/" + "loc"; GetMethod method = new GetMethod(SolrUrl ); if (theQueryString.equalsIgnoreCase("")) { method.setQueryString(new NameValuePair[]{ }); } else { String[] paramKeyValuesArray = theQueryString.split("&"); List<String> list = Arrays.asList(paramKeyValuesArray); List<NameValuePair> nvPairList = new ArrayList<NameValuePair>(); for (String s : list) { String[] nvPair = s.split("="); String theKey = nvPair[0]; String theValue = nvPair[1]; NameValuePair nameValuePair = new NameValuePair(theKey, theValue); nvPairList.add(nameValuePair); } NameValuePair[] nvPairArray = new NameValuePair[nvPairList.size()]; nvPairList.toArray(nvPairArray); method.setQueryString(nvPairArray); // Encoding is taken care of here by setQueryString } }
quelle
So habe ich meinen URL Builder implementiert. Ich habe eine Serviceklasse erstellt, um die Parameter für die URL bereitzustellen
public interface ParamsProvider { String queryProvider(List<BasicNameValuePair> params); String bodyProvider(List<BasicNameValuePair> params); }
Die Implementierung der Methoden ist unten
@Component public class ParamsProviderImp implements ParamsProvider { @Override public String queryProvider(List<BasicNameValuePair> params) { StringBuilder query = new StringBuilder(); AtomicBoolean first = new AtomicBoolean(true); params.forEach(basicNameValuePair -> { if (first.get()) { query.append("?"); query.append(basicNameValuePair.toString()); first.set(false); } else { query.append("&"); query.append(basicNameValuePair.toString()); } }); return query.toString(); } @Override public String bodyProvider(List<BasicNameValuePair> params) { StringBuilder body = new StringBuilder(); AtomicBoolean first = new AtomicBoolean(true); params.forEach(basicNameValuePair -> { if (first.get()) { body.append(basicNameValuePair.toString()); first.set(false); } else { body.append("&"); body.append(basicNameValuePair.toString()); } }); return body.toString(); } }
Wenn wir die Abfrageparameter für unsere URL benötigen, rufe ich einfach den Dienst auf und erstelle ihn. Ein Beispiel dafür finden Sie weiter unten.
Class Mock{ @Autowired ParamsProvider paramsProvider; String url ="http://www.google.lk"; // For the query params price,type List<BasicNameValuePair> queryParameters = new ArrayList<>(); queryParameters.add(new BasicNameValuePair("price", 100)); queryParameters.add(new BasicNameValuePair("type", "L")); url = url+paramsProvider.queryProvider(queryParameters); // You can use it in similar way to send the body params using the bodyProvider }
quelle