底线
可以通过如下映射和配置来解决:
// The OP's original controller with a small tweak
@BasePathAwareController
@RequestMapping("/businessActions")
public class MyCustomRestEndpoint {
// Let's specify the #produces type as text/plain (rather than the Spring Data REST JSON default)
@GetMapping(value = "/modellGenerieren", produces = MediaType.TEXT_PLAIN_VALUE)
public @ResponseBody ResponseEntity<String> modellGenerieren(@Param(value="project") String project) throws IOException {
// Get project by id from repository and map to string.
return ResponseEntity.ok("A String!");
}
}
@Configuration
public class PlainTextConfiguration implements RepositoryRestConfigurer {
// Allow for plain String responses from Spring via the `text/plain` content type
@Override
public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters)
{
StringHttpMessageConverter converter = new StringHttpMessageConverter();
converter.setSupportedMediaTypes(configureMediaTypes());
messageConverters.add(converter);
}
private List<MediaType> configureMediaTypes() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.parseMediaType("text/plain;charset=iso-8859-1"));
mediaTypes.add(MediaType.parseMediaType("text/plain;charset=UTF-8"));
mediaTypes.add(MediaType.parseMediaType("text/plain;charset=UTF-16"));
return mediaTypes;
}
}
并且通过在发出请求时指定ACCEPT 标头(这是关键!):
GET http://localhost:8080/api/businessActions/modellGenerieren
Content-Type: text/plain
Accept: text/plain
这会产生以下响应:
GET http://localhost:8080/api/businessActions/modellGenerieren
HTTP/1.1 200 OK
Date: Mon, 24 Dec 2018 06:21:10 GMT
Content-Type: text/plain;charset=iso-8859-1
Accept-Charset: ... <large charset>
Content-Length: 9
A String!
Response code: 200 (OK); Time: 151ms; Content length: 9 bytes
原因
经调查,您似乎永远无法返回未加引号的字符串的原因似乎是 BasePathAwareHandlerMapping#lookupHandlerMethod 函数的行为。
lookupHandlerMethod 基本上假设在对方法发出请求时,允许的媒体类型是通过 ACCEPT 标头中的 HTTP 请求发出的。否则默认为默认媒体类型(可使用RepositoryRestConfigurer#configureRepositoryRestConfiguration 配置)。
Spring Data REST 的默认媒体类型的默认值为 application/json 或 application/hal+json(取决于该默认值,see here)。这就是为什么您只能在结果中的字符串周围看到带有双引号 "" 的 application/json 内容类型。 String 正在使用 Jackson 转换器(用引号将 Strings 括起来)而不是 String 转换器进行转换。
在调查之后,我同意你的看法,这似乎是一个奇怪的假设。也就是说,框架不应该假设所有请求总是明确指定具有所需媒体类型的ACCEPT 标头(至少,我个人并不总是希望看到它),否则假设所有请求都应该是默认媒体类型只是因为像你这样的用例。
不用太深入研究文档,@BasePathAwareController 这一事实似乎暗示,在利用 Spring Data REST 时,不仅可以使用标准的 Spring Data Rest 实体。
即使没有指定 ACCEPT 标头,我也会亲自将产品类型返回给客户端 - 如果我要编写一些代码来修改 BasePathAwareHandlerMapping,我会添加以下关于我的注释行:
@Override
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
...
if (!defaultFound) {
mediaTypes.add(configuration.getDefaultMediaType());
}
// Lookup the Handler Method for this request
// If no media types are specific in the ACCEPT header of this request...
// Then look and see if the method has a #produces specified and define that as the ACCEPT type
super.lookupHandlerMethod(lookupPath, new CustomAcceptHeaderHttpServletRequest(request, mediaTypes));
}