Application.properties validator - spring-mvc

I want to make some kind of properties validation in my spring boot aplication. In my application.properties I have something like this:
log.path=
logging.config=${log.path}log4j2.properties
When I start my application I want to find all empty properties and throw Exception in which message there will be information about all missing properties.
Is spring giving that kind of mechanism?

You can create a bean and bind properties from application.properties to bean's fields by adding #ConfigurationProperties annotation. You can even use JSR-303 validators like #NotNull and #NotEmpty for automatic validation.
If you have too many properties and you don't want to create fields for each of these properties then, probably, you should open and parse application.properties file by your own. (But if application uses all these properties, then why not create a bean to validate them in the single place?)

Related

Spring Framework: what is the purpose of <mvc:annotation-driven />

I'm relatively new to Spring and I'm a little confused about the tag.
After going through the documentation and looking around different posts it seems like the main use of is that it is required by Spring MVC to dispatch requests to #Controllers.
I created a controller with two requestMappings:
#RequestMapping(method=RequestMethod.GET, value="/health")
#RequestMapping(method=RequestMethod.GET, value="/test")
I tested the web app with and without in the servlet.xml and it doesn't seem like any difference was made with being omitted or not. The requests seemed to still reach my controller just fine.
Can anyone explain to me what exactly that tag is used for?
Thanks in advance!
The support for #Controller and #RequestMapping is provided by Spring by default. However, by enabling mvc:annotation-driven you get support for processing the requests that are mapped to annotated controller methods, such as declarative validation, formatting and conversion service. An excerpt from spring's blog that introduced the new config features
It applies sensible defaults based on what is present in your
classpath. Such defaults include:
Using the Spring 3 Type ConversionService as a simpler and more robust alternative to JavaBeans PropertyEditors
Support for formatting Number fields with #NumberFormat
Support for formatting Date, Calendar, and Joda Time fields with #DateTimeFormat, if Joda Time is on the classpath
Support for validating #Controller inputs with #Valid, if a JSR-303 Provider is on the classpath
Support for reading and writing XML, if JAXB is on the classpath
Support for reading and writing JSON, if Jackson is on the classpath
Another related usefull blog post
If this tag is not added to the XML, then you will have to manually
define the beans for components like HandlerAdapter, HandlerMapping,
Binding Initializer, Request Message converters, etc. This tag helps
registering the following components.
DefaultAnnotationHandlerMapping - This is a HandlerMapping
implementation which maps the HTTP requests to the handler methods
defined using the #RequestMapping annotation.
AnnotationMethodHandlerAdapter - It is responsible for scanning the
controllers to identify methods (and parameters) annotated with #MVC
annotations. It scans and caches handler methods annotated with
#RequestMapping. Also handles the #RequestParam, #ModelAttribute,
#SessionAttributes and #InitBinder annotations.
ConfigurableWebBindingInitializer - The initializer for the Web Data
Binder. Helps in declaratively configuring the Web Binder with
validators, conversion services, property editors, etc.
LocalValidatorFactoryBean - Implements the validator interface and
enables JSR303 validation. This is injected into
ConfigurableWebBindingInitializer.
FormattingConversionServiceFactoryBean - A conversion factory that
returns conversion services for basic objects like date and numbers.
This factory is again injected into ConfigurableWebBindingInitializer.
Support for Message Converters
Finally a more formal definition in the official docs

Access Servlet which is initialize during webserver startup

This is related to the question
How do i get servlet instance from web.xml in my java class
Folks were not clear as to what is the usecase for this type of question. I have the same question and wanted to give a usecase.
In my application i have a class called Configuration which extends HttpServlet. In my web.xml i have an load-on-startup servlet defined for Configuration. This class reads all the properties necessary for the application, and it is absolutely necessary that this properties are read during startup because there something which i am doing differently for each instance of my webserver based on the properties. Now i need to get a handle of this instance in my spring controllers so that i can get the values of the properties. How do i do it?
Is there any specific reason why Configuration is a Servlet? If this class's sole purpose is to read properties to be used later and it is not serving any requests by itself, it shouldn't be a Servlet.
There are two ways to do these configuration classes.
One, you can annotate this class as a #Component and make this class to be instantiated by Spring during startup. Then you can inject this bean wherever you need it.
Second way, without using Spring, is to register an ServletContextListener in your web.xml. Create a class implement the ServletContextListener and inside the contextInitialized() method, call the method of the Configuration class where your property loading logic resides.
http://www.mkyong.com/servlet/what-is-listener-servletcontextlistener-example/

webapp configuration in spring mvc read from database

I'm struggling to find some idea, tutorial or sample how to put some of the configuration of the webapp into database. There will be static configuration put in properties files like database connection, but there is some configuration which can be changed like email account, facebook account and best location for this in the database. That configuration should be loaded as soon as possible when webapp starts. Ideally all the configuration should be in some bean named Configuration.
Thanks in advance.
When a Spring webapp starts, Spring instantiates and injects all its beans. Once the beans are instantiated and injected, if a bean has a method annotated with #PostConstruct, it calls this method.
So you just have to define such a method, read the config from the database and store it in the bean (if you want it to be cached).
Inject this bean everywhere you need access to the configuration properties.

Spring MVC interceptor vs Sitemesh

In a Spring MVC application using Sitemesh to decorate my views, I want to inject into every Model a security attribute called sec of type WebSecurityExpressionRoot.
This way I could call hasAnyRole(), hasAuthority()... in all my views so administrators would be presented extra stuff by the underlying templating engine (Thymeleaf BTW).
A custom HandlerInterceptorAdapter with an overridden postHandle(...) seems to be Spring MVC's way of accomplishing this, but it seems that my master Sitemesh decorator is kind of stealing my security attribute, because whenever I try to reference in some views it is null.
BUT only the views rendered after one of my controllers are affected, the ones
mapped with mvc:view-controller do have the sec attribute.
I'm considering writing a Filter to stash sec into the current HttpServletRequest to solve this issue but I'm maybe missing something.
Thanks in advance!
Are you sure the mvc:view-controller views/path are hitting the interceptor?
Also, I don't know about Thymeleaf, but using JSPs (eg, JstlView) makes Spring MVC copy Model into Request attributes (for purposes of rendering the view) -- the fact that Sitemesh also gets the values via request attributes is, I think, a consequence.

flex and jsf access the same instance of bean

i integrate a flex app in a jsf-icefaces app (in a jspx site with the ice:outputmedia-tag) and want to access the same instance of a bean from flex by remote, that jsf inject.
i already connect with blazeds to a java-bean. this bean - like all other beans - get other beans by injection of jsf, but when i access the bean by remote from flex it doesnt hold the injected beans (like localizer and accesmanager, both session scoped) and i can't connect to the jsf session (FacesContext.getCurrentInstance() is null). this is because flex create a new instance of the bean and it’s not the same current instance, that jsf inject, i think.
i can connect from flex to the database by create a new entity manager in the java bean, but that's not what i want, because it's again another entity manager...i want persist and get data over the accessmanager-bean.
i know exadel fiji and flamingo, but i couldn't work with fiji, because my jsf app include the icefaces components and then it doesn't work with richfaces which fiji needs. and flamingo work only with jboss seam and spring. is it right?
i also read about the spring-flex-integration, but the jsf application did not create with spring and i don't want to integrate spring in such a large jsf app.
yesterday i read about the FlexFactory interface. this interface i have to implement in my own Factory and set it in the service-config.xml of blazeds as a factory read this. i still implement my own factory but i only get application scoped beans over the servlet context which i get over FlexContext.getServletContext().getAttribute("Bean"); and not session scoped beans...
i hope there is a chance to connect throw flex and jsf...
thanks!
FacesContext.getCurrentInstance() is null
This will only happen when the current request is not been passed through the FacesServlet. In other words, the request URL did not match the url-pattern of the FacesServlet. It's namely the one responsible for creating the threadlocal FacesContext instance.
But you actually don't need the FacesContext here. As JSF just runs on the top of the Servlet API, you can also go low level and make use of it to grab the session scoped managed bean. JSF stores session scoped managed beans as attribues of the HttpSession with the managed bean name as key.
Thus, if you for example have a session scoped managed bean with the managed bean name myBean and you have the HttpServletRequest at your hands, then you can also access it as follows:
MyBean myBean = (MyBean) request.getSession().getAttribute("myBean");

Resources