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!
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.
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.
I have a good basic knowledge of how to create web applications using java and jsp, together with Expression Language and JSTL. I am trying to learn how to use Angular.js for my front end.
I've gone through several tutorials, and I am starting to get a fair grip of the basics. But I have yet to figure out how to transfer data from the server, to the front end. Most tutorials I've found, describe how to send data from the front end, to the server.
I know that a RESTful api back end is recommended for Angular web apps. Unfortunately, I have no experience with this, and I find it hard to learn both angular and RESTful at the same time. If possible, I would love to make a work around, so that I can use my existing server solution, and learn one element at the time.
Server side setup
Now, in my old setup, using javax.servlet.http.HttpServlet, i call the service(HttpServletRequest, HttpServletResponse)-method. Inside the method, i add attributes to the request, like this:
request.setAttribute("attribute1", "1");
request.setAttribute("attribute2", "2");
request.setAttribute("attribute3", "3");
Then, because of a front controller pattern, I pass these request variables on to a redirect like this:
request.getRequestDispatcher("/WEB-INF/" + myPageVar + ".jsp").
forward(request, response);
For now, I would ideally like to keep this server side setup.
Current client side data access:
In the current setup, I can now access the initiated variables in two different ways. Either in a javascript script, like below (does not work with objects, only simpler attributes like strings (including JSON)). the next lines of code is picked from a jsp-page that the servlet would have redirected to.
var attribute1 = ${requestScope.attribute1};
or in the html, like this (would work with objects):
<c:set var="attribute1" value="${requestScope.attribute1}"></c:set>
I guess that I could incorporate Expression Language, and use javascript variables to initialize variables in my angular modules, directives and controllers, but I would prefer to do it purely in Angular.
Are these attributes accessible in any way, using angular? I've been trying to read up on $http, and $scope, but there is a jungle of non-relevant info on those, which I haven't been able to navigate through yet.
If the data you want to make accessible to angular should be ready when user lands on the page, it could make sense to put data in javascript variable in jsp page as you suggest.
Since your var is in global scope you can get in your angular controller like this:
$scope.att1 = attribute1;
However if you want to update your data without re-rendering the whole page (and that is what you want pretty soon) you should use $http to call a servlet that returns json. You can relatively simply make this servlet without jax-rs by overriding doGet in httpServlet and use a lightweight json lib (like gson). This example will do it:
//Set up pojo and make it into json string:
SomeClass pojo =new SomeClass();
pojo.setX("this is X");
JSONObject jsonObject = new Gson().toJson(pojo);
String jsonStr=jsonObject.toJSONString();
//Modify response and write json string
httpServletResponse.setStatus(200);//We are ok
httpServletResponse.setContentType("application/json");
httpServletResponse.setCharacterEncoding("UTF-8");
Writer writer = httpServletResponse.getWriter();
writer.write(jsonStr);
writer.close();
//Thats it
In a simple setup you handle this response in your controller like this:
$http({method: 'GET', url: 'http://yourservleturl' })
.success(function(jsonStringFromServlet){
$scope.newData = jsonStringFromServlet;
})
.error(function(){
$scope.error = true;
});
In page-html you access the data with
<div>This is your new x: {{newData.x}}</div>
Don't use jsps at all, don't set attributes.
Only use static html, thats the benefit ! You can write angular directives that perform the funcationality of jsp includes, and have much cleaner code (no embedded jstl, java. just pure html).
Create server side code that returns json. Then your angular js code calls the rest api and populates the client side model.
If you have something that needs populating on startup, use javascript appropriately.
Here is a typical java method that returns json, using Jersey (similar to Spring MVC, resteasy, restlets, spark, apache cxf etc etc) :
#PATH("/myPojo")
#GET
public Response getPojo(Long id) {
Pojo pojo = myService.getPojo(id)
return Response.ok()
.entity(pojo)
.build();
}
In angualr you can then create, for example, $myPojoService.getPojo() that is injected to relevant controllers and calls this endpoint. When called it probably returns the pojo as json and then probably populates the $scope.model.pojo json object. Then the two way databinding of angular updates your gui ... and Boom, you are a full stack engineer/ front end dev!
There are a lot of different ways to accomplish this. This is just what I ended up using.
To expose values in your JSP to Angular you'll need to write them out in script tags and build up Javascript vars with them. Then you can access them from Angular. I'm doing this to pass-in authenticated user account information from server side to my angular code. Your JSP would contain code such as:
<script>
window.CURRENT_USER = {
id: <%=currentUser.getId()%>,
name: "<%=currentUser.getName()%>",
email: "<%=currentUser.getEmail()%>",
prevLogin: new Date(<%=currentUser.getPrevLoginAt().getTime()%>),
prevLoginIp: "<%=currentUser.getPrevLoginIp()%>"
};
</script>
Then in your angular controllers, you can access it like this:
var currentUser = $window.CURRENT_USER;
A better approach (mentioned by Jacob Nicolaisen) would be to use the Google GSon library to actually generate the JSON objects instead of hand coding them.)
This question related to cross site submission across JSP/Servelet based web application and ASP.NET MVC based web application. I could able to submit a NameValueCollection object from an ASP.NET Web project to another ASP.NET MVC project like below.
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultNetworkCredentials;
string transId = Guid.NewGuid().ToString(); //In Java we may use UUID class
var data = new NameValueCollection
{
{ "TransId", transId },
{ "Name", "Regi" },
{ "DOB", "10/17/2013" },
{ "ZIPCode", "673010" },
};
var result = client.UploadValues("http://localhost:50976/api/Trans/Trans", data);
string s = Encoding.ASCII.GetString(result); //May be Base64.encodeToString(fileData, Base64.CRLF) in Java?
if (s == "1")
{
Response.Redirect("http://localhost:50976/Product/ProductList?TransId=" + transId + "");
}
}
ASP.NET MVC project has a WebAPI which is catching this submission like below.
public int Trans(TransViewModel transViewModel)
{
return 1;
}
My ViewModel definition like below
public class TransViewModel
{
public string TransId { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
So now I need to replace my 1st WebProject where ASP.NET MVC
application is calling, with a Java based web application. How can I
accomplish the same submission using alternate JAVA classes in place
of WebClient and also to submit a NameValueCollection type to the same
ASP.NET MVC application? This submission should be accepted by ASP.NET
MVC application like above through a ViewModel
Hmm.. I haven't tried but if you just use regular HTTP GET or POST it doesn't matter what web framework you are using. What ASP.NET MVC want is just a NORMAL request (for example: http://yourwebsite.com:8081/Main/Index?name=Me&email=me#gmail.com).If you send it from any java or other web frameworks your MVC router will be able to map them to a particular action method. In my example this is the Main controller and Index action (HTTP GET) with parameters name and email (string type). The same for Post (add HTTP POST attribute for the action). Problems could have place if you were using models. In this case I always use fiddler to see what exactly I am sending to MVC and also you have to understand how standard MVC model binding works. If you find that your java data structure can't be handled with the MVC standard model binder you can whether change the data structure or implement custom model binder and directly get access to all request data. MVC is a very pluggable framework and I believe this is one of the best web frameworks ever created!
I am not sure that you are trying to do. But I think that there is no way to DIRECTLY pass data between MVC and let's say plain java servlet. You always send data as HTTP requests and it's up to web framework how to handle them. If you need a similar to MVC you can use Spring MVC (java). Again I am not really sure what you are trying to achieve. However, you can make any HTTP based calls from server as well. For example, you have a servlet mapped to /doSomething in your java environment. In the servlet inside get method you have all access to request parameters. So in your MVC project you are free to just make a server side http based call to the servlet mapped address and pass any parameters. In the servlet you generate output and return to the mvc server. After it's up to you what to do with it!
I have started learning GWT and I would like to know if it is possible to create a form in GWT for a process such as user registration and then, handle the logic of the registration(extra validation, adding the data to the database, etc) in a spring controller. I have so far been unable to find resources on the web to do this, so I am guessing that what I am after might not be possible. Can this only be done using classes which extend the RemoteServiceServlet as shown in this video tutorial?
I have tried to access the data from my spring controller using the request.getParameter() method calls, what I noticed was that when I used the Post method, I was unable to access the form parameters, but when I use Get, I can access them. This is some of the code I am using:
GWT:
HorizontalPanel hrzPnlname = new HorizontalPanel();
hrzPnlname.add(new Label("User Name: "));
final TextBox txtUserName = new TextBox();
txtUserName.setName("userName");
hrzPnlname.add(txtUserName);...
Spring:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView helloWorldFromForm(HttpServletRequest request)
{
Map<String, Object> model = new HashMap<String, Object>();
System.out.println("------>\n\n\n\n\n\n" + request.getParameter("userName") + "\n\n\n\n\n<-------");...
I am using GWT 2.4. Any information on this would be highly appreciated.
Thanks!
You can share data between GWT client and spring controllers in a several ways:
REST/JSON request
See how:
Calling REST from GWT with a little bit of JQuery
See also original GWT documentation(section "Communicating with the server/JSON")
This is the best way to communicate with a server in my opinion, because JSON is a pure standard protocol and it can be used by 3-rd party plugins(jQuery for example) and other web services.
Async GWT RMI(Remote method invocation), provided by Google
I think this is not the best idea to use GWT RPC, see why:
4 More GWT Antipatterns
Submit forms directly to spring controller as POST/GET request (as you trying to do).
See com.google.gwt.user.client.ui.FormPanel
I can reconmmend you to use forms submitting only for file uploading, because the browser will only upload files using form submission. For all other operations, form is not required in GWT, any request possible to implement using ajax.
Here are links to some resources - http://technophiliac.wordpress.com/2008/08/24/giving-gwt-a-spring-in-its-step/ and Experiences with integrating spring 3 mvc with GWT? .