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.
Related
I have a Spring Boot application, using Intellij, and am trying to use the #Value annotation in order to get an environment variable from my application.properties.
My application.properties looks like this
server.port=27019
web.entrance.id=63d284ec
Using debugger, I can see that the value of entranceId is successfully retrieved from application.properties, but the same variable is always null in the String.format and my WebUrl has the string 'null' in it and I don't understand why.
#RestController
public class Controller {
#Value(("${entrance.id}"))
private String entranceId;
String WebUrl = String.format("http://localhost:27019/%s", entranceId);
Can someone explain if there is some detail I'm missing why this happens?
Thank you
Your thinking is wrong. Spring will process the #Value after the object has been constructed, whereas your field is being initialized as soon as the class is being constructed (so during constructing).
Basically what Spring does
new Controller()
Detect #Value and with reflection set value
Any construction callbacks (like #PostConstruct).
Your field is being filled at step 1 not after step 2. At which point the #Value hasn't yet been processed.
If you want to set the value you need to do that in an #PostConstruct method or use constructor injection to construct the URL.
I need to retrieve the path param map in my spring boot application and I noticed that the following line of code:
final Map<String, String> pathVariables = (Map<String, String>) request
.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
only works when in a spring boot InterceptorHandler class, I guess because the "path param" abstraction is spring's.
Problem is that I'm using spring security, defining my own filter chain:
http.addFilterBefore(...).addFilterAfter(myFilterNeedingPathParam) //series of filters
And the last filter needs the path params map. My idea would be to put the interceptor before or, if you want, make sure that the last filter is executed after.
Is there a way to do so?
When in the Spring InterceptorHandler, check the actual class of the request, you may need to cast your request to that. Also look into the source code for that class and see if it's pulling that value from a ThreadLocal of some sort.
When using Spring Boot for a project, Jackson came as default to serialize objects back and from Jsons. I realize that Jackson fails if you don't have public accessors, e.g., getters/setters, or public fields in your POJO.
The behavior is different when I switch to Gson. It detects all fields regardless of their visibility. For this reason, I ended up using Gson.
I felt a little uncomfortable about switching my POJO access rules; It would force some refactoring in the project structure.
So, no problems using Gson, but is there a way of change Jackson's behavior?
Jackson does support reading values from private member fields, but does not do it by default.
You can configure the behavior globally in the Spring Boot config like
jackson:
visibility.field: any
visibility.getter: none
visibility.setter: none
visibility.is-getter: none
(this config will only look for member fields and no longer check get, set and is methods)
You could also use the #JsonAutoDetect annotation to do the same setting for a specific class.
Try to set visibility at ObjectMapper level,
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
I have a Controller with the following method:
#RequestMapping(method = POST)
public ModelAndView emailRegister(EmailParameter parameters, ModelMap model) {}
Where EmailParameter is an interface. I understand Spring (magically?) maps the incoming HTTP parameters to my object fields by name, and it can't do this as I have declared an Interface.
Is it possible to declare an interface here, if so is there additional config I need somewhere?
I don't have extensive programming experience so I may be wrong in trying to use an Interface type here, but I believe this is what I should be doing?
Additionally if someone could explain how Spring maps the request parameters to my object fields, that would be much appreciated. Or a link to where this is explained, as I haven't been able to find one!
Thanks
You shouldn't use Interface because Spring needs to instantiate that object, otherwise you will be requiring the property editors OR converters.
Read the following post to know about How Spring MVC Binds Parameter?
Read section "Binding Domain Object" in following link.
https://web.archive.org/web/20160516151809/http://www.jpalace.org/document/92/binding-and-validation-of-handler-parameters-in-spring-mvc-controllers
I would like to implement custom metric or statistics to my spring boot rest web service using actuator but i am not able to find simple tutorials.
For example:
how to show how many times a certain controller was called and what exact parameter field was filled?
how can i create a metric that when its URL is called, it runs certain query and shows back a json with some result
This seems like a good scenario for AOP (Aspect Oriented Programing) as this will allow you to separate this statistic logic from the business logic.
Have a look at Spring doc for more info about AOP and how to achieve that with Spring.
You can then define a pointcut on your controller and have a service for counting (and probably then storing) the data.
Refer below link
AOP Example
For point two the solution is to create an endpoint class (it can be or not a rest controller class). For example:
#Component
#RestControllerEndpoint(id = "pfm-statistics")
public class StatisticsEndpoint {
#GetMapping(value = "/", produces = "application/vnd.openxmlformats-
officedocument.spreadsheetml.sheet")
#ResponseBody
public byte[] generateStatisticsAsExcel() {
...
Note that the ID is the path to be called from URL. We can create a simple endpoint too and just return a string if we want. In this case instead of #RestControllerEndpoint annotation we can use #Endpoint, as a side note, the id should always contain dash