How to set RequestConfiguration per request using RestTemplate?

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-29 13:14:55
vanOekel

As Peter explains, using ThreadLocal is not a good idea here. But I also could not find a way to "pass the value up the chain of method calls".

If you use plain "Apache HttpClient", you can create an HttpGet/Put/etc. and simply call httpRequest.setConfig(myRequestConfig). In other words: set a request configuration per request (if nothing is set in the request, the request configuration from the HttpClient which executes the request is used).

In contrast, the RestTemplate calls createRequest(URI, HttpMethod) (defined in HttpAccessor) which uses the ClientHttpRequestFactory. In other words: there is no option to set a request configuration per request.
I'm not sure why Spring left this option out, it seems a reasonable functional requirement (or maybe I'm still missing something).

Some notes about the "they can bombard our service without any control":

  • This is one of the reasons to use the PoolingHttpClientConnectionManager: by setting the appropriate maximum values, there can never be more than the specified maximum connections in use (and thus requests running) at the same time. The assumption here is that you re-use the same RestTemplate instance (and thus connection manager) for each request.
  • To catch a flood earlier, specify a maximum amount of waiting tasks in the threadpool and set a proper error-handler (use the workQueue and handler in this constructor).

ThreadLocal is a way to pass dynamic value which normally you would pass via method properties, but you are using an API you can't/don't want to change.

You set the ThreadLocal (possible a data structure containing multiple values) at some level in the thread stack and you can use it further up the stack.

Is this the best approach? NO, you should really pass the value up the chain of method calls, but sometimes this is not practical.

Can you provide an example of how my code will look like with ThreadLocal

You might start with

static final ThreadLocal<Long> SOCKET_TIMEOUT = new ThreadLocal<>();

To set it you can do

SOCKET_TIMEOUT .set(key.getSocketTimeout());

and to get the value you can do

long socketTimeout = SOCKET_TIMEOUT.get();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!