gpt4 book ai didi

java - Spring 在 URI 上更改媒体类型,最后带有 .au

转载 作者:行者123 更新时间:2023-11-30 08:30:22 26 4
gpt4 key购买 nike

目前实现的 REST 端点如下:

@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public User userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return new User(UUID.randomUUID());
}

我目前使用电子邮件地址作为用户名,当我使用以 .au 结尾的用户名时,端点返回 406 内容 Not Acceptable 。

我试着把上面的改成这个

@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public String userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return "blah";
}

当我访问它时,它会提示我下载一个 .au 文件(由 Sun microsystems 制作的音频格式...),其中包含“blah”。如果我在方法中随时检查用户名的值,我会得到正确的电子邮件地址,其中包含 .au。

我猜 Spring 堆栈中的某些东西正在解析 .au 并尝试强制执行不同的媒体类型,所以现在它忽略了 application/json

最佳答案

我最近遇到了同样的问题并找到了问题所在。想在这里分享它,因为它会帮助别人。 @Patrick 解释的这种行为似乎是由于 Spring MVC 中的基于 URL(URL 后缀)的内容协商而发生的。

什么是内容协商?

在某些情况下,我们必须处理 Controller 返回的相同数据的多个表示(或 View )。确定要返回的数据格式称为内容协商。

内容协商如何运作?

当通过 HTTP 发出请求时,可以通过设置 Accept header 属性来指定您想要的响应类型。但是,浏览器实际上会发送非常困惑的 Accept header ,这使得依赖它们变得不切实际。因此,Spring 为内容协商提供了一些替代约定。

Spring 内容协商备选方案 - URL 后缀和/或 URL 参数

These work alongside the use of Accept headers. As a result, the content-type can be requested in any of three ways. By default they are checked in this order:

  • Add a path extension (suffix) in the URL. So, if the incoming URL is something like http://myserver/myapp/accounts/list.html then HTML is required. For a spreadsheet the URL should be http://myserver/myapp/accounts/list.xls. The suffix to media-type mapping is automatically defined via the JavaBeans Activation Framework or JAF (so activation.jar must be on the class path).

  • A URL parameter like this: http://myserver/myapp/accounts/list?format=xls. The name of the parameter is format by default, but this may be changed. Using a parameter is disabled by default, but when enabled, it is checked second.

    • Finally the Accept HTTP header property is checked. This is how HTTP is actually defined to work, but, as previously mentioned, it can be problematic to use.

在问题中解释的上述案例中,您看到的是基于路径扩展的内容协商在进行中。 (.au)

来自 ContentNegotiationConfigurer 的 hava 文档,

favorPathExtension

public ContentNegotiationConfigurer favorPathExtension(boolean favorPathExtension)

Whether the path extension in the URL path should be used to determine the requested media type.

By default this is set to true in which case a request for /hotels.pdf will be interpreted as a request for "application/pdf" regardless of the 'Accept' header.

解决方案 - 将 favorPathExtension 设置为 false

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="mediaType" />
<property name="ignoreAcceptHeader" value="true"/>
<property name="useJaf" value="false"/>
<property name="defaultContentType" value="application/json" />

<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>

请注意,除了将 favorPathExtension 设置为 false 之外,上述配置还有一些其他更改。

有关这方面的更多详细信息,请参见 here .

仅作为补充,我们得到的问题回复如下。

{
"timestamp": 1518691842254,
"status": 406,
"error": "Not Acceptable",
"exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
"message": "Not Acceptable",
"path": "/rest/token/something.au"
}

关于java - Spring 在 URI 上更改媒体类型,最后带有 .au,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41262661/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com