Swagger for spring boot describing parameter - spring

My question is pretty simple:
having rest controller's params like
( #RequestBody Wrapper<Request> requestBody){...}
i got to customize UI view of model Wrapper<Request>. It has some fields and I use it from different starter. Im able to put #Schema(required=true) on the field of Request, cause it's located in my module, but what about Wrapper ? Thx.

This is related to #1490.The way to configure this is to create a
custom alternateTypeRules in the Docket config. For e.g. if you have
an immutable MyClass that generates ImmutableMyClass, then we would
add a rule for it as shown below.
#Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.alternateTypeRules(AlternateTypeRules.newRule(MyClass.class,
ImmutableMyClass.class));
https://springfox.github.io/springfox/docs/snapshot/#answers-to-common-questions-and-problems , see #22. It has side effects like resetting all custom settings.

Related

How to use spring-data-rest without href for relation

I'm migrating a legacy application from Spring-core 4 to Springboot 2.5.2.
The application is using spring-data-rest (SDR) alongside spring-data-mongodb to handle our entities.
The legacy code was overriding SDR configuration by extending the RepositoryRestMvcConfiguration and overriding the bean definition for persistentEntityJackson2Module to remove serializerModifier and deserializerModifier.
#EnableWebMvc
#EnableSpringDataWebSupport
#Configuration
class RepositoryConfiguration extends RepositoryRestMvcConfiguration {
...
...
#Bean
#Override
protected Module persistentEntityJackson2Module() {
// Remove existing Ser/DeserializerModifier because Spring data rest expect linked resources to be in href form. Our platform is not tailored for it yet
return ConverterHelper.configureSimpleModule((SimpleModule) super.persistentEntityJackson2Module())
.setDeserializerModifier(null)
.setSerializerModifier(null);
}
It was to avoid having to process DBRef as href link when posting entities, we pass the plain POJO instead of the href and we persist it manually before the entity.
Following the migration, there is no way to set the same overrided configuration but to avoid altering all our processes of creation we would like to keep passing the POJO even for DbRef.
I will add an exemple of what was working before :
We have the entity we want to persist :
public class EntityWithDbRefRelation {
....
#Valid
#CreateOnTheFly // Custom annotation to create the dbrefEntity before persisting the current entity
#DBRef
private MyDbRefEntity myDbRefEntity;
}
the DbRefEntity
public class MyDbRefEntity {
...
private String name;
}
and the JSON Post request we are doing:
POST base-api/entityWithDbRefRelations
{
...
"myDbRefEntity": {
"name": "My own dbRef entity"
}
}
In our database this request create our myDbRefEntity and then create the target entityWithDbRefRelation with a dbRef linked to the other entity.
Following the migration, the DBRef is never created because when deserializing the JSON into a PersistingEntity, the myDbRefEntity is ignored because it's expecting an href instead of a complex object.
I see 3 solutions :
Modify all our process to first create the DBRef through one request then create our entity with the link to the dbRef
Very costly as we have a lot of services creating entities through this backend
Compliant with SDR
Define our own rest mvc controllers to do operations, to ignore the SDR mapping machanism
Add AOP into the RepositoryRestMvcConfiguration around the persistentEntityJackson2Module to set le serializerModifier and deserializedModifier to null
I really prefer to avoid this solution as Springboot must have remove a way to configure it on purpose and it could break when migrating on newer version
Does anyone know a way to continue considering the property as a complex object instead of an href link except from my 3 previous points ?
Tell me if you need more information and thanks in advance for your help!

How can I set http method in servlet filter(in context of Spring Framework)?

I have got a such issue: I do have got antMatcher​ in Spring Security. And I have an opportunity to set http method GET/POST/PUT/PATCH/DELETE for url mapping for my filter. So requests with some methods will be filtered with my filter if they have certain methods and will not be filtered otherways. But how can I specify http method without Spring Security? Is it possible to do it somehow in a cool way using FilterRegistrationBean or I will be have to use
switch(request.getMethod()) {
...
}
in my fileter doFilterInternal() method (I use OncePerRequestFilter) and act according to which method is specified in HttpServletRequest? That is tedious, isn`t it?
I tried to find out some info according to this issue and researches have not been successful yet.
#Bean
public FilterRegistrationBean<CustomFilter> registrationBean(){
FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(customFilter);
registration.addUrlPatterns("/open/*");
/*may be it is possible to addHttpMethods?*/
registration.setName("customLoggingFilter");
registration.setOrder(2);
return registration;
}
Well, no. It is impossible, but I was told that it is a really not bad idea to override the shouldFilter method of the OncePerRequestFilter.

There is more than one bean - highlighted error with custom annotation

We created custom spring annotation #ProfileRegex to upgrade simple #Profile functionality
here is a usage example:
#Configuration
public class MySomeConfigClass {
#Bean
#ProfileRegex("^(test|dev)$")
public OurCustomInterface getLocalImplementation() {
return new LocalImplementationOfOurCustomInterface();
}
#Bean
#ProfileRegex("^(qa|prod)$")
public OurCustomInterface getCloudImplementation() {
return new CloudImplementationOfOurCustomInterface();
}
#Bean
public void CustomClassTakesOurInterfaceAsArg getSomething(OurCustomInterface ourCustomInterface) {
return new CustomClassTakesOurInterfaceAsArg(ourCustomInterface);
}
}
in this example Intellij highlight ourCustomInterface in 3d method as an error with info:
Could not autowire. There is more than one bean of 'OurCustomInterface' type
if I will change that example to simple #Profile it will understand that there is a difference between those 2 beans and not show error, however simple #Profile is not enough for us, as our profiles are more complex then just test, dev, qa, prod and we do require regex to avoid listing all of them like:
#Profile({"profile1", "profile2", "profile3", ***, "profileX"})
So the question is, how to make it treat our #ProfileRegex in the same way as simple #Profile and stop highlighting the error?
I did add #Primary to one of those, and it fixes the error, but our team thinks it is not really good approach, as there are truly no primary or secondary as all really depends on profile condition.
P.S. regardless error in IDEA, code compiles fine and working as needed, I just don't like error highlight in IDEA
any hints? thanks in advance
UPDATE (add an implementation of our #ProfileRegex):
#despadina created a gist based on this article https://raymondhlee.wordpress.com/2015/05/31/using-spring-4-condition-to-control-bean-registration/.
Just our version supports multiple regex, that's the only difference: https://gist.github.com/dpomaresp/1cbfdd13e2985b5796e30ee1714d8785
So by just adding #ProfileRegex("^(test|dev)$") at the class or method level should work

How to set content-type correctly in thymeleaf when mixing html and json templates

I'm working on a single page application using spring boot and thymeleaf. I have two kinds of templates; one producing the SPA scaffolding page as html and multiple producing json responses.
The json responses are being sent back with a content-type of text/html when I would like them to be application/json.
How do I have the content-types set correctly? Do I need two thymeleaf view resolvers? I tried #GetMapping(value = Routes.EVENTS, produces = MediaType.APPLICATION_JSON_VALUE) on the #Controller but to no effect.
I'm sure there are a few approaches to solving this. Here is the one that worked for me.
I figured it out by looking in the Spring Boot documentation on custom view resolvers. This lead me to looking at the ThymeleafAutoConfiguration class. Then a bit of judicious debugging in the Spring framework helped to fill in the gaps.
#Bean
public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setContentType("application/json");
viewResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
viewResolver.setOrder(1);
viewResolver.setViewNames(new String[] {"*.json"});
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}

Local override for setSerializationInclusion(Include.NON_NULL) in ObjectMapper

In my spring application in WebMvcConfigurerAdapter, CustomObjectMapper is added in HttpMessageConverter. The CustomObjectMapper has setSerializationInclusion(Include.NON_NULL). For 1 particular pojo returned via Spring's ResponseBody I want null properties to be returned as well. I cannot change global setting as it will impact all controllers endpoints. Any suggestions ?
You can create a mixin for the Pojo of interest and set the mixin on your CustomObjectMapper. This other answer shows exactly how to do this.

Resources