How do you handle Ajax requests in Spring MVC? - java

In Spring MVC (I'm working with 3.0.2), two HTTP methods are always (or mostly as it seems to me) reserved (i.e. mapped with appropriate handlers) which are GET and POST such as
#RequestMapping(method=RequestMethod.GET)
public String showForm(Map model)
{
//Usually retrieve data from the database when the page is loaded.
return "admin_side/Temp";
}
The above method is invoked when a GET request is made.
#RequestMapping(method=RequestMethod.POST)
public String onSubmit(#ModelAttribute("tempBean") #Valid TempBean tempBean, BindingResult error, Map model, HttpServletRequest request, HttpServletResponse response)
{
//Perform some basic operations with the database like insert, update or delete when the form is submitted (by clicking a submit button or so).
return "admin_side/Temp";
}
The above method is invoked when a POST request is made. Assuming that the Spring controller is designated with the #RequestMapping(value="admin_side/Temp") annotation.
Now, what happens, if I need to use Ajax and I need to perform different functionality than the preceding methods do? I can neither handle another method with the GET method nor with the POST method because there are already handlers mapped (both the HTTP methods, GET and POST are reserved to handle the showForm() and onSubmit() methods respectively).
For the sake of demonstration, I used the method=RequestMethod.PUT approach with Ajax such as
#RequestMapping(method=RequestMethod.PUT)
public #ResponseBody String getStateList(#ModelAttribute("tempBean") #Valid TempBean tempBean, BindingResult error, HttpServletRequest request, HttpServletResponse response)
{
return "Message";
}
and it worked as intended but I felt it should not be the best solution. How do you handle Ajax requests in Spring MVC, if you have such a scenario (actually, it seems to be quite usual to me)? Should I (always) use RequestMethod.PUT? (or what is the best HTTP method for Ajax in Spring?)
Is there a way to map more than one method with same HTTP method in the same controller (an obvious answer should be no)? Again, which approach do you use when you need to work with Ajax in Spring MVC? Hope you follow what I mean! It's quite difficult for me to express as my English is at the very initial stage.

I think the real question is:
Why do you want the same URL/method combination to act different depending on how it is accessed?
Who cares if you are accessing it by making an AJAX request on the frontend? If the semantics of the call are different, give it a different URL. You can specify the URL pattern directly on the method, rather than on the class, to avoid having to duplicate functionality from that class.

We can have multiple GET and POST methods in a single Controller, we need to use value attribute for this purpose
Ex:
#RequestMapping(method=RequestMethod.GET, value = "/showForm")
public ModelAndView showForm(){
}
#RequestMapping(method=RequestMethod.GET, value = "/processAjaxRequest")
public ModelAndView processAjax(){
ModelAndView modelAndView = new ModelAndView("page.jsp");
modelAndView.addObject("ajax_response", ajax_response);
return modelAndView;
}

There's no such thing as best method for AJAX.
As for what methods you should use, it depends on the architectural style. The REST paradigm and its most common practical interpretation, ROA (Resource Oriented Architecture) make certain assumptions as to the semantics of HTTP methods. It's an increasingly popular approach and I think it's worth reading about. Making full use of the benefits of REST would probably require you to rethink your entire app design, though. If you decide to do it this way, read up on REST, ROA and JAX-RS, the Java standard for RESTful applications. Its implementations can be integrated with Spring.
Alternatively, you can just stick to GET and POST, as the most widely-supported methods. As for Spring itself, the reasonable way to do it would be to provide a separate bean (or perhaps a set of beans) to take care of your AJAX-based API. There will be no method "conflict" if you keep the URLs different.

Related

Can ResponseEntity be used outside of Controllers in Spring?

I have the following question. I find myself in using ResponseEntity inside a RestController in Spring whenever I want to manipulate the HTTP response coming back from my controller.
Let's say now that the outcome of this response depends indeed on what happens on the business layer below. Let's say this layer makes an http call, if it goes right I forward back above a positive message, instead I forward a negative message.
My controller now receives a message, but it would be nice to analyze whetever what happened down below was successful or not. So, can I return from the business level a ResponseEntity and mark it already as 400 or 200 (depending on what happens down there) or there is another better practice?
Sure you can. Technically ResponseEntity is a class like any other, you can return an instance of it from any layer.
The question you should ask yourself though, is this a good practise to return object of that class from a method that suppose to perform some business logic? For me it does not feel right. You introduce layers to separate concerns. Your domain layer should be totally agnostic of off communication protocol your application offer.
If you design domain layer right you'll know what went wrong based on thrown exception. Then you'll also know which HTTP status you should return.
This violates the concept of separation of layers: It is the controller's only job, and only the controller's job, to translate between the language of HTTP and your application's internal language (API). What if, in the future, you want to change how your HTTP API works but support multiple versions at the same time?
Instead, this is exactly what exceptions are for: Throw a sensible exception from your business methods. I frequently create subclasses of exception types such as IllegalStateException to represent application-specific errors, and sometimes I use the existing exception classes directly.

Which REST method to use if only sending path variable and key-value pair in header to trigger business logic?

I'm working on a web-game for training purposes. In this project I'm using Spring-Boot and REST endpoints to execute CRUD operations and trigger business logic methods.
One endpoint of mine looks like this:
#PatchMapping("companies/{companyId}/upgrade-star-value")
#ResponseBody
public String upgradeStarValue(#PathVariable int companyId, #RequestHeader(name = "playerId") int playerId)
throws GameLogicException {
return companyBusinessLogicService.upgradeStarValue(playerId, companyId);
}
The purpose of this endpoint is to trigger a method that validates the amount of specific resources of the player with the passed playerId and then reduces them and upgrades the star value of the company with the passed companyId. So everything is done without a request body.
Know I was wondering which REST method I should use to accomplish that. Should I use POST or PATCH or is there another method for the case that no request body but path variable and request header is sent? Is there a best practice to deal with such a case?
I tried to look up other posts, but it's hard for me to briefly express my problem in a google search, so the results don't apply to my problem. Therefore I am happy about hints to other posts.
I think that in your case you can use PUT but this is a link that can help you to understand which method used for Click
You have mentioned that your operation is not idempotent. In such case POST will suit your needs and will be more or less RESTful.

Is there any Annotations in Java Servlet? [duplicate]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I am designing a simple web-based application. I am new to this web-based domain.I needed your advice regarding the design patterns like how responsibility should be distributed among Servlets, criteria to make new Servlet, etc.
Actually, I have few entities on my home page and corresponding to each one of them we have few options like add, edit and delete. Earlier I was using one Servlet per options like Servlet1 for add entity1, Servlet2 for edit entity1 and so on and in this way we ended up having a large number of servlets.
Now we are changing our design. My question is how you exactly choose how you choose the responsibility of a servlet. Should we have one Servlet per entity which will process all it's options and forward request to the service layer. Or should we have one servlet for the whole page which will process the whole page request and then forward it to the corresponding service layer? Also, should the request object forwarded to service layer or not.
A bit decent web application consists of a mix of design patterns. I'll mention only the most important ones.
Model View Controller pattern
The core (architectural) design pattern you'd like to use is the Model-View-Controller pattern. The Controller is to be represented by a Servlet which (in)directly creates/uses a specific Model and View based on the request. The Model is to be represented by Javabean classes. This is often further dividable in Business Model which contains the actions (behaviour) and Data Model which contains the data (information). The View is to be represented by JSP files which have direct access to the (Data) Model by EL (Expression Language).
Then, there are variations based on how actions and events are handled. The popular ones are:
Request (action) based MVC: this is the simplest to implement. The (Business) Model works directly with HttpServletRequest and HttpServletResponse objects. You have to gather, convert and validate the request parameters (mostly) yourself. The View can be represented by plain vanilla HTML/CSS/JS and it does not maintain state across requests. This is how among others Spring MVC, Struts and Stripes works.
Component based MVC: this is harder to implement. But you end up with a simpler model and view wherein all the "raw" Servlet API is abstracted completely away. You shouldn't have the need to gather, convert and validate the request parameters yourself. The Controller does this task and sets the gathered, converted and validated request parameters in the Model. All you need to do is to define action methods which works directly with the model properties. The View is represented by "components" in flavor of JSP taglibs or XML elements which in turn generates HTML/CSS/JS. The state of the View for the subsequent requests is maintained in the session. This is particularly helpful for server-side conversion, validation and value change events. This is how among others JSF, Wicket and Play! works.
As a side note, hobbying around with a homegrown MVC framework is a very nice learning exercise, and I do recommend it as long as you keep it for personal/private purposes. But once you go professional, then it's strongly recommended to pick an existing framework rather than reinventing your own. Learning an existing and well-developed framework takes in long term less time than developing and maintaining a robust framework yourself.
In the below detailed explanation I'll restrict myself to request based MVC since that's easier to implement.
Front Controller pattern (Mediator pattern)
First, the Controller part should implement the Front Controller pattern (which is a specialized kind of Mediator pattern). It should consist of only a single servlet which provides a centralized entry point of all requests. It should create the Model based on information available by the request, such as the pathinfo or servletpath, the method and/or specific parameters. The Business Model is called Action in the below HttpServlet example.
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Action action = ActionFactory.getAction(request);
String view = action.execute(request, response);
if (view.equals(request.getPathInfo().substring(1)) {
request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
}
else {
response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
}
}
catch (Exception e) {
throw new ServletException("Executing action failed.", e);
}
}
Executing the action should return some identifier to locate the view. Simplest would be to use it as filename of the JSP. Map this servlet on a specific url-pattern in web.xml, e.g. /pages/*, *.do or even just *.html.
In case of prefix-patterns as for example /pages/* you could then invoke URL's like http://example.com/pages/register, http://example.com/pages/login, etc and provide /WEB-INF/register.jsp, /WEB-INF/login.jsp with the appropriate GET and POST actions. The parts register, login, etc are then available by request.getPathInfo() as in above example.
When you're using suffix-patterns like *.do, *.html, etc, then you could then invoke URL's like http://example.com/register.do, http://example.com/login.do, etc and you should change the code examples in this answer (also the ActionFactory) to extract the register and login parts by request.getServletPath() instead.
Strategy pattern
The Action should follow the Strategy pattern. It needs to be defined as an abstract/interface type which should do the work based on the passed-in arguments of the abstract method (this is the difference with the Command pattern, wherein the abstract/interface type should do the work based on the arguments which are been passed-in during the creation of the implementation).
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
You may want to make the Exception more specific with a custom exception like ActionException. It's just a basic kickoff example, the rest is all up to you.
Here's an example of a LoginAction which (as its name says) logs in the user. The User itself is in turn a Data Model. The View is aware of the presence of the User.
public class LoginAction implements Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
return "home"; // Redirect to home page.
}
else {
request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
return "login"; // Go back to redisplay login form with error.
}
}
}
Factory method pattern
The ActionFactory should follow the Factory method pattern. Basically, it should provide a creational method which returns a concrete implementation of an abstract/interface type. In this case, it should return an implementation of the Action interface based on the information provided by the request. For example, the method and pathinfo (the pathinfo is the part after the context and servlet path in the request URL, excluding the query string).
public static Action getAction(HttpServletRequest request) {
return actions.get(request.getMethod() + request.getPathInfo());
}
The actions in turn should be some static/applicationwide Map<String, Action> which holds all known actions. It's up to you how to fill this map. Hardcoding:
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
Or configurable based on a properties/XML configuration file in the classpath: (pseudo)
for (Entry entry : configuration) {
actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
Or dynamically based on a scan in the classpath for classes implementing a certain interface and/or annotation: (pseudo)
for (ClassFile classFile : classpath) {
if (classFile.isInstanceOf(Action.class)) {
actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
}
}
Keep in mind to create a "do nothing" Action for the case there's no mapping. Let it for example return directly the request.getPathInfo().substring(1) then.
Other patterns
Those were the important patterns so far.
To get a step further, you could use the Facade pattern to create a Context class which in turn wraps the request and response objects and offers several convenience methods delegating to the request and response objects and pass that as argument into the Action#execute() method instead. This adds an extra abstract layer to hide the raw Servlet API away. You should then basically end up with zero import javax.servlet.* declarations in every Action implementation. In JSF terms, this is what the FacesContext and ExternalContext classes are doing. You can find a concrete example in this answer.
Then there's the State pattern for the case that you'd like to add an extra abstraction layer to split the tasks of gathering the request parameters, converting them, validating them, updating the model values and execute the actions. In JSF terms, this is what the LifeCycle is doing.
Then there's the Composite pattern for the case that you'd like to create a component based view which can be attached with the model and whose behaviour depends on the state of the request based lifecycle. In JSF terms, this is what the UIComponent represent.
This way you can evolve bit by bit towards a component based framework.
See also:
Examples of GoF Design Patterns in Java's core libraries
Difference between Request MVC and Component MVC
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
What components are MVC in JSF MVC framework?
JSF Controller, Service and DAO
In the beaten-up MVC pattern, the Servlet is "C" - controller.
Its main job is to do initial request evaluation and then dispatch the processing based on the initial evaluation to the specific worker. One of the worker's responsibilities may be to setup some presentation layer beans and forward the request to the JSP page to render HTML. So, for this reason alone, you need to pass the request object to the service layer.
I would not, though, start writing raw Servlet classes. The work they do is very predictable and boilerplate, something that framework does very well. Fortunately, there are many available, time-tested candidates ( in the alphabetical order ): Apache Wicket, Java Server Faces, Spring to name a few.
IMHO, there is not much difference in case of web application if you look at it from the angle of responsibility assignment. However, keep the clarity in the layer. Keep anything purely for the presentation purpose in the presentation layer, like the control and code specific to the web controls. Just keep your entities in the business layer and all features (like add, edit, delete) etc in the business layer. However rendering them onto the browser to be handled in the presentation layer. For .Net, the ASP.NET MVC pattern is very good in terms of keeping the layers separated. Look into the MVC pattern.
I have used the struts framework and find it fairly easy to learn. When using the struts framework each page of your site will have the following items.
1) An action which is used is called every time the HTML page is refreshed. The action should populate the data in the form when the page is first loaded and handles interactions between the web UI and the business layer. If you are using the jsp page to modify a mutable java object a copy of the java object should be stored in the form rather than the original so that the original data doesn't get modified unless the user saves the page.
2) The form which is used to transfer data between the action and the jsp page. This object should consist of a set of getter and setters for attributes that need to be accessible to the jsp file. The form also has a method to validate data before it gets persisted.
3) A jsp page which is used to render the final HTML of the page. The jsp page is a hybrid of HTML and special struts tags used to access and manipulate data in the form. Although struts allows users to insert Java code into jsp files you should be very cautious about doing that because it makes your code more difficult to read. Java code inside jsp files is difficult to debug and can not be unit tested. If you find yourself writing more than 4-5 lines of java code inside a jsp file the code should probably be moved to the action.
BalusC excellent answer covers most of the patterns for web applications.
Some application may require Chain-of-responsibility_pattern
In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
Use case to use this pattern:
When handler to process a request(command) is unknown and this request can be sent to multiple objects. Generally you set successor to object. If current object can't handle the request or process the request partially and forward the same request to successor object.
Useful SE questions/articles:
Why would I ever use a Chain of Responsibility over a Decorator?
Common usages for chain of responsibility?
chain-of-responsibility-pattern from oodesign
chain_of_responsibility from sourcemaking

How to: Accessing RESTful Web Services with Play Framework 2.1 for Beginners

I am fairly new to many of the concepts and technologies being used in this question so I would appreciate a little understanding and help for a beginner from the community. I am using the Play Framework version 2.1.3 and I need to POST data to a RESTful web service so that it can be inserted into a remote database. An XML response will be returned indicating either success or failure.
I am sure you are aware that the documentation for the Play Framework is quite lacking and is in no way helpful to beginners, therefore I am unsure of how to accomplish this task with best practices in mind. I am looking for a Java solution to this problem, I do not have the time at present to learn the Scala language. My experience with Web Services is fairly limited, normally I would implement a DAO design pattern (or use one of the many available ORM libraries depending on needs) within my application and use JDBC to connect directly to the database. That is not an option here.
My first question would have to be, is there a recommended design pattern for accessing web services? Then, considering the Play MVC framework, how would one best implement such a design pattern, package the data (assuming the application has already captured and validated data from the user), send it off and process the responses back to the user?
I know it is a fairly lengthy question however my intention behind this is to create a knowledge base of sorts for beginners who can easily come in with limited experience, read, understand and replicate what they find here to produce a working solution. Having searched the web quite extensively, I have found a few disjointed snippets but nothing concrete involving these technologies and no up-to-date tutorials. Thank you for your time.
Creating requests is straight-forward. First you provide a URL. There are various methods to add content types, query parameters, timeouts, etc. to the request. Then you choose a request type and optionally add some content to send. Examples:
WSRequestHolder request = WS.url("http://example.com");
request.setQueryParameter("page", "1");
Promise<Response> promise = request.get();
Promise<Response> promise = WS.url("http://example.com").post(content);
The complicated part is to send it and use the response of the request. I assume you have a controller that should return a Result to the user, based on the web service's response. The result is usually a rendered template or maybe just a status code.
Play avoids blocking by using Futures and Promises. The controller's async method takes a Promise<Result> and returns a result (the future value) at some point later. A simple to use promise is provided by the get and post methods shown above. You don't need to care about their implementation, you just need to know that they promise to provide a Response once the request is complete.
Notice the problem here: When creating a request with WS.url("...").get() it will give you a Promise<Response> even though async takes a Promise<Result>. Here you have to implement another promise yourself, which will convert the response to a result using the map method. If you follow the Play documentation, this will look a bit confusing, because Java doesn't has closures (yet) and everything has to be wrapped in a class. You don't have to use anonymous classes inside the method call though. If you prefer more clean code, you also can do it like this:
return async(
request
.get() // returns a `Promise<Response>`
.map(resultFromResponse) // map takes a `Function<Response, Result>` and
// returns the `Promise<Result>` we need
);
The object resultFromResponse may look like follows. It's actually just like a cumbersome definition of some kind of callback method that takes a Response as only argument and returns a Result.
Function<Response, List<T>> resultFromResponse =
new Function<Response /* 1st parameter type */, Result /* return type */>() {
#Override
public Result apply(Response response) {
// example: read some json from the response
String message = response.asJson().get("message");
Result result = ok(message);
return result;
}
};
As #itsjeyd pointed out in the comments, when calling webservices in Play 2.2.x you don't wrap the call in async any more. You simply return the Promise<Result>:
public static Promise<Result> index() {
return request.get().map(resultFromResponse);
}

How to specify a parameter as part of every web service call?

Currently, each web service for our application has a user parameter that is added for every method. For example:
#WebService
public interface FooWebService {
#WebMethod
public Foo getFoo(#WebParam(name="alwaysHere",header=true,partName="alwaysHere") String user, #WebParam(name="fooId") Long fooId);
#WebMethod
public Result deletetFoo(#WebParam(name="alwaysHere",header=true,partName="alwaysHere") String user, #WebParam(name="fooId") Long fooId);
// ...
}
There could be twenty methods in a service, each with the first parameter as user. And there could be twenty web services.
We don't actually use the 'user' argument in the implementations - in fact, I don't know why it's there - but I wasn't involved in the design, and the person that put it there had a reason (I hope).
Anyway, I'm trying to straighten out this Big Ball of Mud.
I have already come a long way by wrapping the web services by a Spring proxy, which allows me to do some before-and-after processing in an interceptor (before there were at least 20 lines of copy-pasted boiler plate per method).
I'm wondering if there's some kind of "message header" I can apply to the method or package and that can be accessed by some type of handler or something outside of each web service method.
Thanks in advance for the advice,
LES
Who or what is expecting the user message to be bound to SOAP headers? Are your web services secured? Is that some kind of authentication header? It might have been the original intention. Actually, someone should have the answer to these questions. Find who. And if you find out that you won't ever need it, stop passing it. But if you need it, I think it's better to add it (even if you don't use it for now) unless if modifying the WSDL is not an issue (especially on the client side).
PS: I don't know how to avoid adding a parameter with #WebParam(header=true) to Java methods in order to generate a WSDL with operations having a <soap:header> in their input. AFAIK, this is how JAX-WS works when starting from Java.
If there is no reason why you need to have that variable as a parameter, you can have each one of your services extend a super class. In that super class have spring inject the MessageContext, ServletContext, ServletRequest, HttpHeaders or whichever is appropriate (probably MessageContext for JAXWS) using either the #Context annotation or #Resource annotation.
Then supply some methods in that super class to pull the user information from the request.
If authentication is what you are trying to accomplish you can manipulate contexts from predefined handlers such as protocol or Logical Handlers. E.g. implement SoapHanlder(which is a protocol handler) interface , from there add that class to the handler chain of each service you offer. Very simple and powerful. This gentleman has the best tutorial out there on this topic.

Categories