It seems like I can do everything that the Controller class do inside Spring Web-Flow, for example decision making and switching from page to page. To my understanding, its the C inside the MVC model. Am I correct about this?
So my question is, is there any advantage to still include a Controller class when using Spring Web-Flow?
If you need access to the request and response, an appropriate design might still include a controller while also having a flow.xml. For example, if you had this code:
HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getNativeRequest();
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getNativeResponse();
It's more intelligible to put that in a controller rather than a service.
Also, if you want to register a custom editor, it might make sense to have the controller have this logic in the initBinder() method.
Spring Web Flow uses the Spring MVC framework. The DispatcherServlet handles the request. A FlowHandlerMapping is used to map the request to a particular Web Flow.
Web Flow is to solve the problem involved with controller logic that spans multiple-page navigation (a pageflow, or wizard).
Web Flow can eliminate the need for specialized controller classes to accomplish following a path of page transitions/form updates along a predefined workflow. If you don't need to do this, you can save yourself a lot of configuration/complexity just by using MVC.
Related
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.
Here a solution is described to handle redirects to a custom URL based on a condition via use of AccessStrategy.
This however is part of the unauthorized login logical flow therefore results into a still not-logged in user arriving at the end url we redirect to. (via getUnauthorizedUrl)
If we want to redirect the user based on a condition, say via injecting an action to the webflow, how can we manipulate the return URL to be changed into a custom one?
WebUtils.getService(requestContext) include getters of the source/originalUrl but no obvious way to set/manipulate said value through an action bean.
p.s. Currently using CAS version 5.3.x
Responses for normal web applications from CAS are built using WebApplicationServiceResponseBuilder.
If you examine this block you will find that the final response is built using WebApplicationServiceResponseBuilder bean. It is only created conditionally, if an existing bean is not already found in the context by the same name. So to provide your own, you just need to register a bean with the same name using your own #Configuration class.
#Bean
public ResponseBuilder<WebApplicationService> webApplicationServiceResponseBuilder() {
return new MyOwnWebApplicationServiceResponseBuilder(...);
}
...and then proceed to design your own MyOwnWebApplicationServiceResponseBuilder, perhaps even by extending WebApplicationServiceResponseBuilder and overriding what you need where necessary to build the final redirect logic conditionally.
To learn about how #Configuration classes work in general, you can:
Review this post
or this post
or consult the documentation for Spring and/or Spring Boot.
I am new to Restful web services in Java and trying to discover it by using MVC design pattern.
I have a simple HTML form with one button and one input text box. When the user types something into the text box, I want to store this data in DB.
This is part of my HTML code:
<input type="button" onclick="doneButton()" value="Done" />
When the button is clicked, I call "doneButton()" function as
<script>
function doneButton() {
var param = document.getElementById("text").value;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("text").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET","MYURL"+param);
xhttp.send();
}
</script>
I am able to call my RestFul web service by the AJAX code above.
In my web service, I call my model class and establish DB connection there. After that, I call my DAO class from my model class and store the required data in DB table.
As far as I know MVC design pattern:
I should not call a web service directly from view. I should first call
A controller from the view
This controller should call the Restful web service.
The web service should call the model class.
The model class should class DAO and DB operation.
Is this corrent in terms of MVC design pattern?
Can I call a Restful Web service directly from view in MVC design pattern?
I use jersey in web.xml:
RESTful Service
com.sun.jersey.spi.container.servlet.ServletContainer
1
RESTful Service
/webservices/*
Can you please help me to understand how I should build my application using MVC design pattern?
Thank you for your help.
Best Regards
Let me clarify this for you:
View makes a RESTful call to the controller. In other words, your controller is one API in your RESTful web service.
Controller calls the DAO layer, which in turn returns data from the underlying database.
Controller uses the returned data, also called the model, to return response to the view.
This is just an example, hope this helps
$(document).ready(function() {
$('#response_button').on('click', function() {
// console.log($('#request_textarea').val()); //get your values you need to send to the controller
$.ajax({
type : "GET",
url : "url", //call to your controller here.
data : "xmlRequest=" + $('#request_textarea').val() + "&functionType=submit_request", //append your data here
success : function(msg) {
$("#response_textarea").text(msg); //response from the controller will be processed here.
}
});
});
});
Call your DAO layer via the service layer and return the data back to the UI. To answer one of your questions, You can call the controller from the view.
Well thanks for your question.
First I want to tell you that your basic idea is right.
You should not call a web service directly from a view.
Also true is the fact that the controller is your entry point for displaying a view of your application.
But I think there is a little misunderstanding of the term 'view'.
For most MVC Frameworks a view is some sort of a template that is composed of HTML and several placeholders for the data.
A controller might call a REST service. It might also get it's data by querying a database directly. How the data is retrieved is pretty much dependent on the actual implementation of the controller.
Yet, client-side MVC Frameworks like Angular.js are usually designed to work with REST services.
So using REST services for the data operations is a good idea in case you want to use a Javascript MVC Framework.
Now what does a controller do?
A controller listens to a specific resource (a URL) and responds to it.
It does that by binding a (view) model to the requested view (usually an HTML template).
It basically replaces the placeholders from the view-definition with actual data and displays the completed HTML to the client.
If form data gets posted to the controller it parses the data and updates the view model accordingly.
So what is a (view) model and how is it populated with data?
Well, a (view) model is the M in MVC. It is the actual model that is bound to the view. In some cases the view model might be coincident with the domain model. That is usually the case when you are working with javascript based MVC frameworks. So your view model is not just a simple data model that contains the data bound to the placeholders of a specific view template. It terms of js MVC frameworks it might also contain the business logic that is called by the controller...in javascript...on the client. -> That's the downside.
In your case all the DB operations are handled by the REST service. So you have a server side component that has it's own data model which is independent of the MVC structured presentation layer. The REST service is therefore not part of the MVC approach! So you can still implement server side validation in the REST service operations if you want to. But remember that your client side controller has to translate between the client side (view and domain model) and the server side (domain and/or persistence model²).
² nicer word for an anemic domain model.
Roadmap:
Find an answer to the question: Do I build my own MVC framework (hint: bad idea!) or do I use an existent MVC framework to take advantage of the MVC approach?
Select an MVC framework that fits your needs and download it.
Create model, views and controllers.
But before you're actually thinking of building an MVC structured presentation layer you might want to understand what a REST service is and how it is structured and created.
I hope that helps.
Happy coding!
We are trying to have a spring MVC Controller that works as a portlet and a servlet, in order to be deployed in a Liferay context or as a standalone version. But it seems that the we have a conflict if we decide to have multiple RequestMappings on the method level (as opposed to having just 1 mapping on the level of the controller). we get the error shown below.
Note that if we decide to just have a requestMapping on the level of the controller that hosts a servlet mapping and a portlet mapping, it works.
#RequestMapping({"view", "/"})
The controller that does not work:
#Controller("controller")
#RequestMapping("VIEW")
public class MyController {
#RenderMapping
public ModelAndView doView(RenderRequest request, RenderResponse response) throws Exception {
HttpServletRequest portletHttpReq = PortalUtil.getHttpServletRequest(request);
HttpServletResponse portletHttpResp = PortalUtil.getHttpServletResponse(response);
return doView(portletHttpReq, portletHttpResp);
}
#RequestMapping(value="/home")
protected ModelAndView doView(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// do something
return new ModelAndView("view");
}
}
The resulting error:
[...]
Caused by: java.lang.IllegalStateException: Mode mappings conflict between method and type level: [/home] versus [view]
Do you have any suggestions on how we could implement such thing? What we would really like to avoid is having to maintain 2 controllers for every portlet/servlet.
Thank you.
I don't really think this is a good idea... the #RequestMapping annotation on the class level is going to cause problems for sure, simply because Spring portlet MVC expects the portlet mode, while Spring Web MVC expects a root URL.
Also, your code doesn't seem to be correct either, since ModelAndView exists in both the portlet MVC as the web MVC part of the Spring framework, and since you cannot import both, you'll have to specify the full package for one of them, and since you're not doing that either, your code is just wrong.
Except the technical issues, both portlets and servlet have different terminology and point of views. These are some key questions that pop up with me if I hear this:
What are you going to do about the different phases (ACTION and RENDER)
What about the the different portlet modes (VIEW, EDIT, HELP, ...)
What are you going to do about the specific portlet features (PortletSession, PortletPreferences, ...)
How are you going to handle the different kind of requests (ResourceRequest, ActionRequest, RenderRequest, PortletRequst, EventRequest vs HttpServletRequest)
How are you going to handle security? The portal container provides authentication for you, a standalone web application does not.
And these are just questions from a portlet mindset, I'm pretty sure there are also technical issues if you look at it from the web application point of view.
It makes much more sense to divide your code into a view layer and business logic. Put the business logic in a separate package or separate services, and build a separate portlet- and standalone application, using the same/shared business logic.
Good day!
I am planning to do a simple CRUD application. I am planning to make my add, edit, delete and view handled by one controller. Something like this:
#WebServlet(name="ControllerServlet",
urlPatterns = {"/add","/edit","/delete","/view"}
then just use this code in my controller:
String userPath = request.getServletPath();
if (userPath.equals("/add")) {
}
But I am not sure if this is a common practice. Anyway, I am wondering what is the best practice for this? What are the pros and cons of doing this instead of separating each controller?
Thank you in advance.
Frankly, the common practice is to adopt a MVC framework. Java EE 6 offers JSF 2.0 out the box as a component based MVC framework. CRUD is possible with a single bean and a single view. You can find a basic example in this answer. The sole controller is provided by JSF itself, the FacesServlet. Other MVC frameworks follows less or more the same ideology.
If you don't want to adopt a MVC framework because you would like to learn JSP/Servlets first and/or your project won't go beyond a CRUD form, then it is hard to point out the "right" approach. At least, the use of multiple URL patterns and if/else statements is a poor sign. You have basically 2 options.
Just use 4 separate servlets. With Servlet 3.0 you don't need to fiddle with web.xml anymore and it's really easy to add another servlet class. Each servlet class functions as an "action" class and each one has a clear responsibility.
Use a single servlet, but don't use multiple URL patterns and don't use if/else blocks to determine the actions. Map it on a single URL pattern such as /action/* or *.do so that you can invoke it by URLs like action/create, action/read, etc or by create.do, read.do, etc. Then create an interface like follows
public interface Action {
void execute(HttpServletRequest request, HttpServletResponse response);
}
Implement all actions based on this interface, CreateAction, ReadAction, etc and have in your servlet a Map<String, Action> which you fill as follows during init() method:
actions.put("create", new CreateAction());
actions.put("read", new ReadAction());
// ...
And invoke it as follows (assuming an URL pattern of /action/* is been used)
actions.get(request.getPathInfo().substring(1)).execute(request, response);
That's also how the average MVC framework works deep under the covers.
See also:
Design patterns web based applications
Have you considered doing this as a RESTful service using a JAX-RS framework (like Jersey)? Then you leverage URIs and the HTTP operations: PUT, GET, POST, DELETE for CRUD:
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-45.html
For example:
GET http://www.example.com/customer/1
reads customer with id=1
DELETE http://www.example.com/customer/1
deletes customer with id=1