我正在 Spring 引导应用程序中与微服务建立相互通信。响应以 JSON 格式生成,并使用 logback.xml 记录在日志文件中。这在 ELK 端通过 docker-maven 插件得到了进一步的利用。在执行 mvn clean install 时,它在通过 pom.xml 创建 docker 映像时抛出异常
错误堆栈:
引起:com.spotify.docker.client.exceptions.DockerException:com.spotify.docker.client.shaded.com.fasterxml.jackson.core.JsonParseException:非法字符((CTRL-CHAR,代码0)):仅常规[来源:(文件)处的标记之间允许使用空格(\r,\n,\t)行:1,列:2] 在 com.spotify.docker.client.auth.ConfigFileRegistryAuthSupplier.authForBuild (ConfigFileRegistryAuthSupplier.java:108) 在 com.spotify.docker.client.auth.MultiRegistryAuthSupplier.authForBuild (MultiRegistryAuthSupplier.java:77)在 com.spotify.docker.client.DefaultDockerClient.build (DefaultDockerClient.java:1483) 在 com.spotify.docker.client.DefaultDockerClient.build (DefaultDockerClient.java:1460) 在 com.spotify.plugin.dockerfile.BuildMojo.buildImage (BuildMojo.java:240) 在 com.spotify.plugin.dockerfile.BuildMojo.execute (BuildMojo.java:135) 在 com.spotify。
pom.xml:
<!-- Dockerfile from Spotify -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.11</version>
<configuration>
<repository>${docker.image.prefix}/${project.artifactId}</repository>
</configuration>
<executions>
<execution>
<id>default</id>
<phase>install</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
我调试了代码,找到了错误的原因。这是在以下突出显示的方法中引起的:
private List<Comment> findCommentsForFeed(Feeds feed) {
log.info("Finding comments of feed with id {}", feed.getId());
String url = UriComponentsBuilder.fromHttpUrl(commentServiceBaseUrl).path("comments")
.queryParam("feedId", feed.getId()).toUriString();
// ** THIS LINE CAUSES ERROR... **
ResponseEntity<List<Comment>> response = restTemplate.exchange(url, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Comment>>() {
});
List<Comment> comments = Objects.isNull(response.getBody()) ? new ArrayList<>() : response.getBody();
log.info("Found {} comment(s) of feed with id {}", comments.size(), feed.getId());
return comments;
}
我的控制器看起来像:
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/feeds", produces = MediaType.APPLICATION_JSON_VALUE)
public class FeedController {
@Autowired
private final FeedService service;
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Feeds>> getFeeds() {
List<Feeds> feeds = service.getFeeds();
return ResponseEntity.ok(feeds);
}
@GetMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<FeedWithComment> getFeed(@PathVariable Long id) {
FeedWithComment feedWithComments = service.getFeed(id).orElseThrow(ResourceNotFoundException::new);
return ResponseEntity.ok(feedWithComments);
}
我用于 json 输出的 logback.xml 文件如下所示:
<springProfile name="docker">
<appender name="jsonConsoleAppender"
class="ch.qos.logback.core.ConsoleAppender">
<encoder
class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<timestamp>
<timeZone>UTC</timeZone>
</timestamp>
<version />
<logLevel />
<message />
<loggerName />
<threadName />
<context />
<pattern>
<omitEmptyFields>true</omitEmptyFields>
<pattern>
{
"trace": {
"trace_id": "%mdc{X-B3-TraceId}",
"span_id":
"%mdc{X-B3-SpanId}",
"parent_span_id": "%mdc{X-B3-ParentSpanId}",
"exportable": "%mdc{X-Span-Export}"
}
}
</pattern>
</pattern>
<mdc>
<excludeMdcKeyName>traceId</excludeMdcKeyName>
<excludeMdcKeyName>spanId</excludeMdcKeyName>
<excludeMdcKeyName>parentId</excludeMdcKeyName>
<excludeMdcKeyName>spanExportable</excludeMdcKeyName>
<excludeMdcKeyName>X-B3-TraceId</excludeMdcKeyName>
<excludeMdcKeyName>X-B3-SpanId</excludeMdcKeyName>
<excludeMdcKeyName>X-B3-ParentSpanId</excludeMdcKeyName>
<excludeMdcKeyName>X-Span-Export</excludeMdcKeyName>
</mdc>
<stackTrace />
</providers>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="jsonConsoleAppender" />
</root>
</springProfile>