当前位置: 首页 > 知识库问答 >
问题:

Spring REST模板接受标头

蔚学林
2023-03-14

在我们的一个REST服务的一些负载测试期间,当负载增加时,我们开始看到Spring的REST模板的这些日志:

并发负载下,3-4小时后,http请求的Accept报头变为

DEBUG: org.springframework.web.client.RestTemplate - Setting request Accept header to [text/plain, application/json, application/*+json, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain, text/plain,<and so on>, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, */*, <and so on>]

最终,使用RestTemplate对此服务的所有调用开始失败,错误为400(错误请求)

被调用的REST服务接受字符串作为输入,并具有以下签名

@RequestMapping(value = "/findRecordById", method = {RequestMethod.POST, RequestMethod.GET })
@ResponseBody
public String findRecordById(@RequestBody String id) {//method body}

我们正在向该服务发送POST类型的请求,请求内容的形式为“SomeID”,例如。“一二三”

在轻负载下,调用服务没有问题。

令人费解的是text/plain、*/*不断添加到REST模板的accept标头列表中。为什么会出现这种情况?

REST模板bean声明是这样的:

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <constructor-arg>
            <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
                <property name="readTimeout">
                    <value>90000</value>
                 </property>
                <property name="httpClient" ref="restHttpClient" />
            </bean>
        </constructor-arg>
    </bean>

    <bean id="restHttpClient"  class="org.apache.http.impl.client.DefaultHttpClient">
          <constructor-arg> 
            <bean class="org.apache.http.impl.conn.PoolingClientConnectionManager">
                <property name="defaultMaxPerRoute">
                    <value>100000</value>
                 </property>
                <property name="maxTotal">
                    <value>100000</value>
                 </property>                 

            </bean>
          </constructor-arg>
    </bean>

请求的创建方式:

String postParams = "\"" + id + "\"";

String postResp = restTemplate.postForObject("findRecordById",postParams, String.class);

共有1个答案

唐钊
2023-03-14

添加text/plain是因为您尝试读取字符串和RestTemplate,发现StringHttpMessageConverter是您请求的转换器,并且StringHttpMessageConverter支持的媒体类型是text/plain。

正如您在RestTemplate的这个方法中所看到的。

public void doWithRequest(ClientHttpRequest request) throws IOException {
            if (responseType != null) {
                List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
                for (HttpMessageConverter<?> messageConverter : getMessageConverters()) {
                    if (messageConverter.canRead(responseType, null)) {
                        List<MediaType> supportedMediaTypes = messageConverter.getSupportedMediaTypes();
                        for (MediaType supportedMediaType : supportedMediaTypes) {
                            if (supportedMediaType.getCharSet() != null) {
                                supportedMediaType =
                                        new MediaType(supportedMediaType.getType(), supportedMediaType.getSubtype());
                            }
                            allSupportedMediaTypes.add(supportedMediaType);
                        }
                    }
                }
                if (!allSupportedMediaTypes.isEmpty()) {
                    MediaType.sortBySpecificity(allSupportedMediaTypes);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Setting request Accept header to " + allSupportedMediaTypes);
                    }
                    request.getHeaders().setAccept(allSupportedMediaTypes);
                }
            }
        }
    }
 类似资料:
  • 我有一个带有请求映射和路径变量的Spring restController: 调用此控制器时,我收到Http 406 Not Acceptable错误,请求如下: 但不包括: 那不是很奇怪吗?直到最近我才发现也失败了,所以我猜这与扩展映射有关。 我如何处理此隐藏功能? 问候

  • 我试图理解下面代码中的编译器错误。我有一个variadic模板函数,它接受具有指定类型的lambda,试图调用该函数会导致模板由于不匹配而不被视为有效的候选模板。 如果我将声明更改为不变: 然后它为上面的玩具示例工作,但对于真正的问题,我需要任意的论点。我是不是缺少了什么,或者还有什么方法可以做到这一点? 编辑:这被错误地标记为重复,我相信--受骗者没有回答我所问的问题。这个问题特别与这里的var

  • 我有一个简单的模板结构将字符串与值关联起来 我有一个函数,我希望接受1个或多个任何类型的字段,这些字段可能是不同的类型,所以我使用,因为据我所知,C++缺少类型化变量参数,不能确定变量参数的大小,并且必须至少有一个其他参数来确定从哪里开始。 问题是我不知道如何告诉它接受可能是不同类型的字段。在Java中,我只使用,但是C++缺少类型化变量参数和通配符。我唯一的另一个想法是使参数类型为,但这似乎是一

  • 普通标签 普通标签用于变量输出和模板注释,ThinkCMF普通模板标签以{ 和 } 作为开始和结束标识,并且在开始标记紧跟标签的定义,如果之间有空格或者换行则被视为非模板标签直接输出。 例如:{$name} 、{$vo.name} 、{$vo['name']|strtoupper} 都属于正确的标签,而{ $name} 、{ $vo.name}则不属于。 标签库标签 ThinkCMF的标签库默认定

  • 作为内容管理框架,ThinkCMF允许app开发者自定义任意标签,ThinkCMF标签使用花括号作为定界符,如{$name}。 ThinkCMF系统内置的标签有: <php></php>用来在模板中执行php的代码,示例代码: <php>echo "这个是在模板中执行的php程序"</php> <foreach></foreach>遍历标签,示例代码: <php>$title=array("简介

  • 普通标签 普通标签用于变量输出和模板注释,ThinkCMF普通模板标签以{ 和 } 作为开始和结束标识,并且在开始标记紧跟标签的定义,如果之间有空格或者换行则被视为非模板标签直接输出。 例如:{$name} 、{$vo.name} 、{$vo['name']|strtoupper} 都属于正确的标签,而{ $name} 、{ $vo.name}则不属于。 标签库标签 ThinkCMF的标签库默认定