Validation framework for business app built on Spring 2.5 - spring

What could the best strategy for writing validation layer for mid-enterprise level business application built on Spring 2.5
I know that Spring provides facility where we can implement Validator interface and write validation logic in validate method. But this will be restricted to only web requests coming through spring controller.
I would like to develop the validation framework which can be utilized during web-services calls.
In other words, the framework can remain and be called independently without the need of implementing Validator interface and then too it can be automatically integrated into Spring MVC flow.
Hope you get my point.

The Spring Validation framework can be used outside of Spring MVC. What WebServices Stack are you using? If you are using Spring-WS (Spring's Web Services stack) they have special instructions on how to set up the validator here:
http://static.springframework.org/spring-ws/sites/1.5/reference/html/server.html#d0e2313
If you are using some other stack, it is probably easier to implement something for that stack (or find one) that will use Spring's validation framework.

Recall that the Validator interface defines two methods:
boolean supports(Class clazz)
void validate(Object target, Errors errors)
The Object target is your form object, which is the whole object representing the page to be shown to the user. The Errors instance will contain the errors that will be displayed to the user.
So, what you need to do is define an intermediary that can be called with the specifics in your form that you want to validate which are also the same as in your web service. The intermediary can take one of two forms:
(probably the best):
public interface ErrorReturning {
public void getErrors(Errors errors);
}
(this can get ugly really fast if more than two states are added):
public interface ValidationObject {
public Errors getErrors(Errors errors);
public Object getResultOfWebServiceValidation();
}
I would suggest that the first approach be implemented. With your common validation, pass an object that can be used for web service validation directly, but allow it to implement the getErrors() method. This way, in your validator for Spring, inside your validation method you can simply call:
getCommonValidator().validate(partialObject).getErrors(errors);
Your web service would be based around calls to getCommonValidator().validate(partialObject) for a direct object to be used in the web service.
The second approach is like this, though the interface only allows for an object to be returned from the given object for a web service validation object, instead of the object being a usable web service validation object in and of itself.

Related

Are template engines (i.e. Thymeleaf) necessary for Spring Boot applications?

I am currently working on a Spring Boot project and I am fairly new to template engines. This will also be my first own private project with Spring Boot.
I would like to know whether it is necessary to include a template engine, such as Thymeleaf, while developing a web application with Spring Boot. I'm using PostegreSQL for the database.
I read under another post that a template engine is not needed, if the backend framework uses JSON for data exchange, because template engines are for rendering retrieved data to HTML for the client. I retrieve JSON objects from the database, can I leave template engines out of my project then?
If any more details are needed, leave a comment below.
No they aren't necessary, in fact most new projects that require web-pages are using single page applications now like Angular, React, Vue, ... over thymeleaf or jsp.
Aside from that a Spring project doesn't always need web pages, for instance when you are just creating a REST API for other applications to call on, or when you are automating things like: a mail service / printing / ... You name it.
However, when you DO want a simple solution with some pages that aren't all that dynamic or complex, pivotal / VMware does recommend to use thymeleaf (over jsp and other solutions) because it integrates easily.
I read under another post that a template engine is not needed, if the backend framework uses JSON for data exchange, because template engines are for rendering retrieved data to HTML for the client. I retrieve JSON objects from the database, can I leave template engines out of my project then?
This is partly true. Yes, Thymeleaf and alike are mostly intended to render data to HTML. They can render any text data, including JSON, but there are tools better suited for the job. On other hand it does not matter how you store the data in your database or what database you are using. You can't just skip rendering (serializing) the response so it does not matter how you store it. What matters is what you want to return as response. For HTML Thymeleaf or even JSP are suitable, but for JSON you may want to use Jackson or Gson instead.
You didn't mentioned the technology you are going to use, so for my examples I'll assume you intend to use Spring Web MVC. Lets take a look at "traditional" controller:
#Controller
public class GreetingController {
#GetMapping("/greeting")
public ModelAndView greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new ModelAndView("greeting", "greeting", new Greeting(name));
}
}
When you make GET request to "/greeting", Spring will call greeting and get the object it returns. In this case it contains the model (the data we want to render) and the view (the template file to use). Then it will try to find a view (something like greeting.html or greeting.jsp) and use template engine like Thymeleaf (or whatever else is configured) to render it (typically to HTML).
What if we want to return JSON instead? In this case we need to:
modify greeting to return Greeting instance instead of ModelAndView
Use RestController instead of Controller. This will tell Spring MVC that we want to directly serialize the object returned to JSON (or similar format) instead of using template to do that.
Here is the modified example:
#RestController
public class GreetingController {
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(name);
}
}
Spring MVC still needs some help to serialize the Greeting instance to JSON. But if you use Spring Boot and the web starter, you don't have to worry about it. It will include Jackson for you.
This is in no way exhaustive answer. As a matter of fact it skips a lot of details, but I hope nevertheless it is useful one. If you want to create REST API using JSON, this Building a RESTful Web Service guide is a good place to start. If you follow the Starting with Spring Initializr steps you'll get a project setup with only what is needed (well maybe with a bit extra but I would not worry too much about it).

REST and spring-mvc

Since REST based controller methods only return objects ( not views ) to the client based on the request, how can I show view to my user ? Or maybe better question what is a good way to combine spring-mvc web app with REST, so my user always get the answer, not in just ( for example ) JSON format, but also with the view ?
So far as I understood, REST based controller would be perfectly fitting to the mobile app ( for example twitter ), where views are handled inside the app and the only thing server has to worry about is to pass the right object to the right request. But what about the web app ?
I might be wrong in several things ( correct me if I am ), since I am trying to understand REST and I am still learning.
To simplify things - you basically have two options:
1) Build Spring MVC application.
2) Build REST backend application.
In case of first option - within your application you will have both backend and frontend (MVC part).
In case of second option you build only backend application and expose it through REST API. In most cases, you will need to build another application - REST client for your application. This is more flexible application because it gives you opportunity to access your backend application from various clients - for example, you can have Android, IOS applications, you can have web application implemented using Angular etc...
Please note, that thins are not so simple, you can within one application have both REST backend and REST client etc... This is just very very simplified in order that you get some general picture. Hope this clarified a little things.
There is some additional clarification related to REST and views worth learning. From your question, I can see that you mean "view" in a sense of UI(user interface) and typical MVC usage. But "view" can mean different things in a different contexts.
So:
JSON can be considered as a view for data
JSON is a representation of the resource, just like HTML is
JSON doesn't have style (unless you are not using a browser
extension, which most the users are not using)
The browser is recognizing HTML as a markup language and applying a
style to it
Both are media types
Both JSON and HTML are data formats
Both can be transferred over the wire
This method returns a view
#RequestMapping("/home")
String home(Model model) {
return "home"; // resources\templates\home.html
}
This method Returns String
#RequestMapping(value = "/home")
#ResponseBody
public String home() {
return "Success";
}
If you annotate a method with #ResponseBody, Spring will use a json mapper to generate the response. Instead of annotating every method with #ResponseBody you can annotate your class with #RestController.
If you want to return a view, you need to annotate the class with #Controller instead of #RestController and configure a viewresolver. Bij default spring will use thymeleaf as a viewresolver if you have spring-web as a dependency on the classpath. The return type of the method is a String that references the template to be rendered. The templates are stored in src/main/resources/templates.
You can find a guide on the spring website: https://spring.io/guides/gs/serving-web-content/

ASP.Net MVC Architecture - Missing a layer?

I am using the Entity Framework/Repository-UnitOfWork/Service layer method on this ASP.NET MVC Application and it works great, but it seems a layer might be missing in order to keep the controllers thin.
Lets take for example a user authentication scenario:
1) The AuthenticationController takes a IAuthenticationService which in turn takes a IUnitOfWork and IRepository<User> (I am using generic repositories).
2) In the controller I want to make its only concern that the service authenticates the user:
if (userService.AuthenticateUser(model.userName, model.password)) {
FormsAuthentication.SetCookie(...);
return RedirectToAction(...);
}
return View(model);
Some will say this is too much logic in the controller right? So it seems as though we might need a Application Manager if you will:
if (appManager.AuthenticateUser(model.userName, model.password)) {
// Here the app manager calls the service???
return RedirectToAction(...);
}
I am trying to keep my domain services agnostic of the consuming application so I can use them on MVC, WinForms, Console, WPF, WCF, etc.
My service layers only return domain objects, I need a place to transform them into View Models, but I want to keep that out of the controllers.
Any input on this would be great!!
Typically, one would use something like AutoMapper to map your domain objects to ViewModels. Then you only have a Map call that wraps your service layer. There is little reason to introduce an entirely new layer just for object mapping.

JSF-SPRING-HIBERNATE architecture- Backing bean related best practice

I am developing a web project and after much research I have decided to go ahead with JSF+Primefaces, Spring and Hibernate approach. While designing the architecture of my project I have finalized the following approach :
Actor --> JSF+PrimeFaces page --- > Backing Bean -- > Service Bean -- > Dao -- > Hibernate
Service Bean and DAO are spring beans with dependency injection.
My concern now is now with respect to backing bean:
I plan to use multiple backing beans for UI page depending upon the type of Page I need to render.
Now for example: For a new user registration page i have UserProfile.xhtml which uses UserBackingBean. UserBackingBean has UserServiceBean injected by spring. UserServiceBean has UserDao injected by Spring.
Now in UserBackingBean when the user enters the form data from UserProfile.xhtml I will have to populate the User.java domain(ORM) object.
a) What is the best practice for this ? Should I initilize the User.java in the constructor on UserBackingBean ? Is this the proper approach ? Please suggest if there is any other way out ?
b) Also please suggest on the above architecture I have decided upon for my project ? Is it the proper approach ?
The general rule I follow is that transaction boundaries are marked in the service beans therefore I don't like to modify hibernate POJO outside of a service because I don't know if there is a transaction already running. So from the backing bean I would call the service layer pass in the parameters that the service layer needs to build up the hibernate pojo and save it, update it, ... etc.
Another way to do this would be have your backing bean implement an interface defined by the service layer and then pass the backing bean to the service layer. For example.
public interface UserInfoRequest {
public String getName();
}
#Service
public class SomeSpringService {
#Transactional(.....)
public void registerNewUser(UserInfoRequest request)
{
}
}
public class SomeBackingBean implements UserInfoRequest {
private SomeService someSpringService;
public void someMethodBoundToSJF()
{
this.someSpringService.registerNewUser(this);
}
}
Regarding your last question I am not a fan of JSF, I think JSF is fundamentally flawed because it is a server component based framework. So my argument against JSF is a generic argument against server side component based frameworks.
The primary flaw with server side component based frameworks is that you don't control what the component will output which means you are stuck with the look of the component, if you want something that looks different you have to write your own component or you have to modify an existing component. Web browsers are currently evolving very quickly adding new features which can really improve the quality of an application UI but to you those features you have to write HTML, CSS, and JavaScript directly and the server side components make that harder.
Client side component architectures are here and much better than doing components on the server side. Here is my recommend stack.
Client Side Architecture:
jquery.js - Basic libary to make all browser look the same to JavaScript
backbone.js + underscore.js - High level client side component based architecture
handlebars.js - for the client side templates
Twitter bootstrap - to get a decent starter set of CSS & widgets
You write code in HTML, CSS and JavaScript organized as backbone views that talk to server side
models using AJAX. You have complete control over the client side user experience with enough
structure to really make nice reusable code.
Server Side Architecture:
Annotation Driven Spring MVC, Services and Dao (#Controller, #Service, #Repository)
Spring component scanning with autowiring by type (#Autowired, #Inject)
AspectJ Load Time Weaving or Compile Time Weaving
Hibernate
Tomcat 7
JSP as the view technology for Spring MVC (yes it cluncuky but you wont be creating
too many jsp pages, mostly for usng <% #inculde > directive
Tooling:
- Spring Tool suite
- JRebel (so that you don't have to start and stop the server) it really works really worth the money
- Tomcat 7

MVC3 Action Filter Using Database (EF 4.1 DBContext, Ninject)

I'm trying to setup an 'Authorization' Filter on an Action, creating my own ActionFilterAttribute where I do a database lookup to determine if a user has access to a certain resource.
On my class inheriting from ActionFilterAttribute, I have created an Injected(Ninject) property to hold the service that I am using for the database access. I have a parameterless constructor so that I can use this as an attribute on my actions. In the 'OnActionExecuting' Method, I am able to gain access to the Injected property (it's not null), but the base DBCotext that it is using is closed.
This working fine, up until the RTM of MVC3, where the Release Notes stated:
Breaking Changes:
In previous versions of ASP.NET MVC, action filters are create per
request except in a few cases. This
behavior was never a guaranteed
behavior but merely an implementation
detail and the contract for filters
was to consider them stateless. In
ASP.NET MVC 3, filters are cached more
aggressively. Therefore, any custom
action filters which improperly store
instance state might be broken.
The first time I use this filter, it works as expected, but if I refresh the page or another user access this filter, I get the error:
The operation cannot be completed
because the DbContext has been
disposed.
which is what I guess I should expect given the breaking changes notes.
My question is this, what would be the preferred/recommended way of accomplishing what I need to do? Should this be in an ActionFilterAttribute, or should this 'authorization' be done somewhere else?
I'd do authentication in Application_AuthenticateRequest and authorization in your attribute using Thread.CurrentPrincipal, but your method should work too. You just need to count with fact that DbContext will be different for each request but your attribute won't. Something like this should do the trick (I'm assuming you are using DependencyResolver):
public class MyMightyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var context = (DbContext)DependencyResolver.Current.GetService(typeof(DbContext))
// authenticate, authorize, whatever
base.OnActionExecuting(filterContext);
}
}
I have been battling with this for a while and finally solved my problem. So here is my solution in the hope it may help someone else.
The setup:
1. I have an MVC3 project, a custom action filter that accesses the db using EF5 via a business service.
2. I use Unity and unity.MVC to resolve my dependencies on a per request basis.
3. I use property injection into my custom Action filter, as it has a parameterless constructor.
The result.
Dependency injection works correctly for all the services used by actions, my EF DbContext is correctly disposed of at the end of each request.
The Problem
Although my property dependency is resolved in my custom action filter, it contains a stale instance of my DbContext (e.g. it seems to have been cached from the previous request)
As mentioned in previous posts, MVC3 is more aggressive with filter caching and the state of a filter cannot be relied on. So the suggestion was to resolve the dependency in the OnActionExecuting method. So I removed my injected property and did just that called resolve on my unity container. However I still got a stale version of the DbContext. Any changes in the DB were correctly queried in my main actions, but the custom action filter didn’t pick them up.
The solution.
Unity.MVC Manages per-request lifetime by using child containers and disposing these at the end of each request. By resolving my dependency’s in the action filter from my unity container I was resolving from the parent container which is not disposed of on each request.
So rather than
IoC.Instance.CurrentContainer.Resolve<IService>();
I used this to obtain an instance of the child container rather than parent.
var childContainer = HttpContext.Current.Items["perRequestContainer"] as IUnityContainer;
var service = childContainer.Resolve<IServcie>();
I'm sure there must be a clean way to achive the same result, so please add suggestions.
Ok slight refinement to allow my unit test to inject a mock of the service.
1. remove the dependency resolve from the the OnActionexecuting and add two constructors.
public MyCustomActionfilter() : this(((IUnityContainer)HttpContext.Current.Items["perRequestContainer"].Resolve<IService>())
and
public MyCustomActionfilter(IService service)
{
this.service = service;
}
Now the constructor resolves your service and stores it as a private readonly. This can now be consumed in your OnActionExecutng function. Unit tests can now call the second constructor and inject a mock.

Resources