Spring Webflow Best Practice - java

I have a java web application which uses spring webflow as framework. I have a problem with processing data on a plain flow xml. When the processing gets more complicated I find it hard to implement using the flow xml of the web flow. I was considering of using controllers to perform these operations. How do I do this. Have no Idea in using controllers in web flow. And from controllers can I jump to the flow xml too to continue processing?
An example of my problem is in submitting forms. Here's the scenario. I have a Users table and authorities table. I also have a User class representing the tablebec I used here Hibernate. In my register page I have the username, password and authority(not a field of the user class) fields. I bind this form to my User object using spring webflow binding. My problem is I can't bind the authority field because it doesn't exist in my User class. Do i need to create a bean representing my form? I need to add the username and password on Users table and authority in another table Authority. Where do I make the initializations for my User object and Authority object or where do I set the values from the registerFormBean to my POJOs? I think it is not a good approach or it will make my flow xml complicated

you can implement this by
jsf as presentation +webflow+mvc as controller
first you will create backing bean with username,password,authority
then let webflow to create the backing bean on session
then when submit the action will call #controller "Spring MVC"
and controller will call your business
and business call DAO which you implemented it as Hibernate
like this
<on-start>
<evaluate expression="youractionClass.createbackingBean()" result="conversationScope.yourbean" />
</on-start>
second solution
you can bind the view to model which contains username,password,authority
then when submit the action will call #controller "Spring MVC"
and controller will call your business
and business call DAO which you implemented it as Hibernate
<view-state id="registerForm" model="registerBean"

Related

Does a simple REST project in Spring Boot use the MVC principle?

I need to create a simple project that uses the Model-View-Controller principle and a MySQL database. And I want to use Spring Boot with Spring MVC and Spring Data JPA.
And I want to make GET, POST, PUT and DELETE requests that call the database and send a JSON to the client.
#GetMapping(value = "/users")
public Users getUsers() {
// call the service -> call the database
}
And the response will be:
{
"name": "John",
"age": 45,
...
}
Does this project use the MVC principle? Or do I need to use a .jsp for the view to have a complete MVC principle?
So the Controller is the REST Controller and the Model is the Users POJO. And if this project use the MVC principle can somebody explain where is the view?
And if the service calls the repository and fetch the data from the MySQL database I want to know if the MVC is modified by adding the DAO, or the DAO is a part of the Model?
MVC is an architectural design pattern for the layers of your application. It is exactly about inner work of your application.
REST is how does your application interact with other applications.
You can combine them together at one application.
In general they are different patterns for different problems:
MVC you are receiving request -> process it (fetching the data from DB or with some ways) -> render it to the view -> and view with requested data return to the caller.
REST (Representational State Transfer) flow is quite similar. However, instead of return view with the data -> your app sends just representation of the data. The content type of response should be specified by the caller at request.
Now go one by other parts of your questions. (Maybe, it is even too many questions just for one question to answer them properly)
Does this project use the MVC principle? Or do I need to use a .jsp file for the view to have a complete MVC principle?
From the snipped which you have already shared - you used REST - and your method return JSON representation of resource.
For now looks like it is the desired goal which you want to achieve:
And I want to make GET, POST, PUT and DELETE requests that call the database and send a JSON to the client.
If you want to use MVC you have to return a rendered view with fetched data instead. Keep in the mind that you have to return HTML page to the caller at that case:
#Controller
#RequiredArgsConstructor
public class ControllerDemo {
private final UserService userService;
#GetMapping(value = "/users")
public String getAllUsers(Model model) {
// add fetched data to model as attribute
model.addAtribute("users", userService.findAll());
// view resolver should be configured to render response to `response-page.ftl` for example
return "response-page";
}
It doesn't matter if you use JSP or Freemarker or Mustache, etc - the main idea is that you create template and data from DB will be represented according to this template on HTML page.
So the Controller is the REST Controller and the Model is the Users pojo. And if this project use the MVC principle can somebody explain where is the view? - with REST approach is no view, the response at this case is representation of resource.
And if the service calls the repository and fetch the data from the MySQL database I want to know if the MVC is modified by adding the DAO, or the DAO is a part of the Model?
DAO stands for Data Access Layer. You a have a model - User class which describes your entity. And you store some user entities at DB. And you want to receive the all users which have already been stored (in real life you need to have pagination but we omit it for simplicity).
Thus for doing it you have to go row by row for your users table and convert the row from DB to the User entity. And you take this retrieving to separate data layer - DAO.
DAO is not part of the Model it is separate layer between Model and DB.
You could not do it at your service layer (UserService) because it will brake the Simple Responsibility Principle (SOLID Principles) for the service layer - do one job and do it well.
At the same time you support high cohesion for parts of your app (GRASP Principles)
MVC is the pattern to implement UI. So if you are just developing a REST API, no UI is involved and hence you do not need to concerned whether it is implemented as MVC or not.
Instead if you are developing a web application , the view is the technology to render HTML codes to the browser . Usually they are just a template engine such as JSP , FreeMarker or Thymeleaf which allows you to use their expression language to access the data in some Java object (i.e. Model) to define the HTML code that you want to generate as a template.
In Spring MVC , you need to use #RestController for developing a REST API while #Controller for the web application. The main difference is that #RestController includes #ResponseBody which will by-pass the view resolution process as there are no view in the REST API.
In short, as you are developing a REST API now , there are no UI and no view. Hence MVC is not applicable in here and you do not need to worry whether it is implemented based on MVC or not.
And if the service calls the repository and fetch the data from the
MySQL database I want to know if the MVC is modified by adding the
DAO, or the DAO is a part of the Model?
DAO is an object that is responsible for getting and managing the data from DB. It is nothing to do with Model.

User data carriage using Interceptors in Struts2

I am using Struts2 framework to implement the MVC architecture in my Web application. While allowing the user to obtain an ID-specific session, I need to take the username and password from a JSP form. Instead of passing this data to the Action class directly, I want to check the validity of the values in an Interceptor and then check or continue the flow depending on business logic-specific criteria.
Hence, my quest is to obtain the user data from the JSP form in the Interceptor. What is (if there's any) way to do that?
Thanks in advance!
If you are validating the username and password through a call to a DB or another service,it would be better to have a separate action for it.
However subsequent calls to business logic can be prehandled via the request context in the interceptor itself.

How to ensure the user is logged into the system at the controller level?

I'm using spring MVC, and I have a custom authentication/security system that I had to build.
NOTE: I know of spring security, but my requirements were to do this in a custom way so please not looking for suggestions about using spring's security modules.
When the user logs into the system, it creates a session cookie. When the user visits a page, a interceptor looks for the existance of that cookie, and looks up the session guid in mysql and if it is present that it loads some data and stores it in the request's attributes.
Now for pages where the user has to be logged in, how can I restrict access at the controller level?
I could do this in an interceptor:
if url.contains("projects/") ...
If I want to restrict access to only logged in users in the ProjectController, but this isn't really something I want to do.
But I am looking for maybe a annotation I could add at the controller level, or maybe somehow create a BaseController that all controllers that require a loggedin user will inherit from.
What are my options for something like this?
In ASP.NET, I created a baseController, and the controller has an event cycle, and in the before-action fired event I checked to see if the user was logged in.
So looking for suggestions for spring mvc?
Update
For example, in ASP.NET you have 2 methods, 1 that fires just before the controller's action method and one that fires after:
Controller.OnActionExecuting
Controller.OnActionExecuted
http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.onactionexecuting.aspx
So in the OnActionExecuting, I can actually see exactly which controller I am in, and which action is about to get called in a programatic way, not by looking at the request URL and then doing string compares to see if it is a particular controller etc.
So in this event, I can simply check for things in cookies or in my request attributes etc.
This is a much more stable way to do it, does spring have anything similiar?
If you need this at the controller level, you could:
1) declare a java.security.Principal parameter in the controller method signature, which Spring will fill in with a Principal object, or
2) implement a PermissionEvaluator, which can be called on a controller method using the #PreAuthorize annotation, and which would have access to a Authentication object.
Similar to what you did in ASP.NET, you can take advantage of OncePerRequestFilter and chain it to the chain of filters you have in web.xml or Spring application context. The good point about this filter is that it's independent of the MVC approach that you take and no need for a "base controller".
On the other hand, if you're also using Spring security module, you can use a custom filter configuration and place it in the correct place that it should be.
If the check fails, then you'd probably want to raise exceptions or redirect user to the correct navigation.
Based on the last comment, you can also use mapped interceptors:
<mvc:interceptors>
<mvc:interceptor>
<mapping path="/myFirstPath/*"/>
<mapping path="/mySecondPath/*"/>
<bean class="org.example.SomeInteceptor" />
</mvc:interceptor>
<mvc:interceptor>another one</mvc:interceptor>
</mvc:interceptors>

Populating a Model based on User Role with Spring MVC and Spring Security

I have a problem with populating a model content in Spring MVC application, based on user role managed by Spring Security.
In my application (simplified example) I've got two roles defined: ROLE_USER and ROLE_ADMIN. Also I've got a page that displays a two separate lists of objects: readers (only available for ADMIN) and books (for both, ADMIN and USER).
There is no problem in conditional displaying lists in JSP Page, but I need to prepare model first and I don't want to load readers list if current user isn't an ADMIN.
I've thought about using Spring EL in Java code to determine if user has specified role (hasRole('ROLE_ADMIN')), but I can't find a way to manually evaluate that code.
Is there some way to call Spring EL handler in controller source code, or maybe there is a better solution (on architectural or design pattern level) for conditionally populating model, than checking roles directly in java code.
The issue was tackled by #Chepech and #Boris Kirzner in Prevent Method call without Exception using #PreAuthorize Annotation. That way you can return null (or empty list in your case) when a AccessDeniedException occurs.
One approach would be to just return everything when you're generating your model then rely on #PostFilter to filter that result based on roles. If you don't want to go that route, you could have your controller call out to another bean to build up specific parts of your model, and that other bean could have the role annotations attached. That would effectively limit you from ever creating objects if they won't be used.
If conditionally displaying of page parts is controlled by JSP page, then a conditional populating of model should be done by a controller (because JSP page and Controller are tightly coupled in view layer).
If we use annotations in service layer it will put the responsibility in wrong layer of an application (in service layer instead of view layer).
My final solution is based on remembering a Set of user Roles as user session attribute:
/* This is executed once, after user successful login. */
Set<String> roles = new HashSet<String>();
for (GrantedAuthority authority : authentication.getAuthorities()) {
roles.add(authority.getAuthority());
}
session.setAttribute("userRoles", roles);
Then if I want to conditionally populate a model I only need to check if required Role is contained by that Set.
Set<String> roles = (Set<String>) session.getAttribute("userRoles");
if(roles.contains("ROLE_ADMIN")) {
putReadersInModel(model);
}
I think that solution is clean and keeps the responsibility of proper populating of model in Controller.

How to store session in Spring MVC

What's the best way of storing session related data of a user (like, for example a log of recent actions a user has done) in a Spring MVC (2.5) web application ?
Using the classic javax.servlet.http.HttpSession or by specifying scope="session" in controller beans, and storing the data in a session object ?
Session-scoped beans (using scope="session") is the cleanest approach. This removes the need to interact with the session yourself.
If you want to autowire a session-scoped bean in to the controller, you either need to make the controller session-scoped itself, or use a scoped-proxy to wire it into a singleton controller, as described here. Either approach is valid.

Categories