Closed ST-DDT closed 7 years ago
Hi @ST-DDT , once again thanks for your feedback, it's always very constructive and useful.
There are basically 2 steps in template generation:
What I've changed so far resides in the Java objects creation. Jsondoc can only read Java fields to find properties, while Livedoc reads the properties returned by the configured PropertyScanner
that is also used for the doc generation (which can be customized and could be anything).
When using livedoc-springmvc
and its SpringLivedocReaderFactory
, the PropertyScanner
is a JacksonPropertyScanner
that I create using Spring's ObjectMapper
, so it respects your Jackson annotations, and most of the configuration (@JsonIgnore
, custom property names etc.).
This Java objects creation is done in the TemplateProvider
. The serialization to a JSON string from these objects happens when serializing the big Livedoc
object at the moment you request it from the controller, which means that these objects should be serialized using the Spring Jackson2HttpMessageConverter
used for the /jsondoc
endpoint. Which is why I'm surprised it's inconsistent with your settings.
I didn't change the serialization of the doc AFAIR, and the only thing that comes to my mind so far is the fact that I changed the type of the template
field from ObjectTemplate
(which extended LinkedHashMap
) to a plain Java Object
.
I'll look into this issue ASAP.
Hi @ST-DDT , I've got a couple questions to investigate this issue:
livedoc-springmvc
? Do you create your own controller?LivedocReader
?ObjectMapper
used by Spring's Jackson2HttpMessageConverter
?
- How do you use livedoc-springmvc? Do you create your own controller?
@Bean
public JsonLivedocController documentationController() {
String version = getCurrentVersion();
String contextPath = getContextPath();
List<String> packages = Arrays.asList("a", "b", "c");
return new JsonLivedocController(version, contextPath, packages);
}
No other configuration for LiveDocs.
- Do you create your own LivedocReader?
I don't understand the question, but I guess I don't.
- Does your first sentence mean you are seeing your expected result with the original Jsondoc project but not with Livedoc?
No, I don't get the expected result with JsonDoc either. IIRC I get the following from JsonDoc:
{
"currentTime": { },
"name": "",
"startupTime": { }
}
- How/where/when do you configure the ObjectMapper used by Spring's Jackson2HttpMessageConverter?
@Configration
public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof AbstractJackson2HttpMessageConverter) {
((AbstractJackson2HttpMessageConverter) converter).getObjectMapper().disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
}
}
}
}
Thanks a lot for your answers.
Do you create your own LivedocReader?
I don't understand the question, but I guess I don't.
This was in fact answered by question 1. There is another JsonLivedocController
constructor taking a custom LivedocReader
object for the doc generation, but you used the usual one taking a package list. The constructor that you used creates a Spring-oriented LivedocReader
, which is what we want here, so no issue on that side.
FYI, in the next version of Livedoc, due to the fix of https://github.com/joffrey-bion/livedoc/issues/12, neither constructors will take the basePath
as an argument, as it is now inferred by default from the current request context. You will still be able to force it via a setter of course.
Does your first sentence mean you are seeing your expected result with the original Jsondoc project but not with Livedoc?
No, I don't get the expected result with JsonDoc either.
Thanks for the clarification, I was really wondering how on earth this behaviour could have changed.
Regarding your ObjectMapper
configuration, can you confirm this configuration is actually applied to your other endpoints? Does your API actually return dates in text format?
I would just like to confirm whether this instanceof
check is actually true at some point.
Ok, I guess I have found the issue.
In fact, Livedoc doesn't use the actual ObjectMapper
instance used by Spring, but simply a Spring-generated ObjectMapper
instance. Therefore, it cannot reflect any custom configuration.
I had written it this way temporarily, but I thought I had changed it to access the actual ObjectMapper
bean. I guess I was wrong.
The culprit is the SpringLivedocReaderFactory:
public class SpringLivedocReaderFactory {
public static LivedocReader getReader(List<String> packages) {
Reflections reflections = LivedocUtils.newReflections(packages);
AnnotatedTypesFinder annotatedTypesFinder = LivedocUtils.createAnnotatedTypesFinder(reflections);
PropertyScanner propertyScanner = createJacksonPropertyScanner();
DocReader springDocReader = new SpringDocReader(annotatedTypesFinder);
DocReader baseDocReader = new LivedocAnnotationDocReader(annotatedTypesFinder);
return new LivedocReaderBuilder().scanningPackages(packages)
.withPropertyScanner(propertyScanner)
.addDocReader(springDocReader)
.addDocReader(baseDocReader)
.build();
}
private static PropertyScanner createJacksonPropertyScanner() {
// to match the spring config without accessing the actual bean containing it
ObjectMapper jacksonObjectMapper = Jackson2ObjectMapperBuilder.json().build();
return new JacksonPropertyScanner(jacksonObjectMapper);
}
}
Closing this issue as it contains 2 different issues: https://github.com/joffrey-bion/livedoc/issues/43 and https://github.com/joffrey-bion/livedoc/issues/44
The issue
The example generated by jsondoc does match the settings that have been set on the
Jackson2HttpMessageConverter
.I don't know how the template is generated, so I cannot give you further hints how to fix this. If you give me a pointer where/how they are generated I might be able to present a solution.
Livedoc output
Expected output