How to use annotated Spring controllers with Freemarker to return custom ajax respones - ajax

I primarily use annotated controllers that return ModelAndView object used by Spring and Freemarker to render and return pages to browsers - works great. I'd now like to respond to ajax gets and posts that return html fragments as payload inside an XML message.
The problem I'm having not returning a ModelAndView objects seems to confuse Spring WRT to #ModelAttribute (s) and session objects that support data to / and from forms.
I've had to hack the freemarker template to support i18n messages, etc. I'm finding that simply rendering an FTL file while also trying to utilize Spring's object rendering from froms is becoming quite a rabbit hole.
I'm trying to manually (guess what and) do the things that get done behind the scenes and it's not working optimally. To edit an object I'm manually placing the object in the session on rendering the edit form. When the post comes back there are residual/different values in the object I get back out of the session AND the ModelAttribute that Spring rendered for me.
Bottom line? Questions about Spring, Freemarker and custom non-ModelAndView responses that are rendered by Freemarker.

Add another instance of FreeMarkerViewResolver that only that has viewNames ='*.frg'. The viewClass should be your own class that renders the template the way you want by overriding the processTemplate method.

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/

Spring MVC Load page automatically

I have a quick question about how to use the Spring MVC.
I just started with it and i was used to have pages that always had their data loaded calling some controller that you setted ON THE PAGE.. calling some methods on controllers to load objects at the page at load time.
Is it the same in Spring MVC? Cuz what im seeing so far is that if you want to load a page with data, you always have to use a modelandview object which is loaded by a method that you must call before... and them you return the modelandview object with its destination to the view that you want.
What im trying to know is if there is a way that the page requests some data from the controller before it gets loaded... automatically...
Dont know if im making my self clear... thanks anyway for the help!
in spring mvc, using Controllers, it is always Request->Controller(populates model and chooses view)->Response.
you could use ajax to load data from any resource (even Controllers) or jsp:useBean to explicitly call some business logic or jsp:include to include a certain fragment or a custom jsp tag.
I also face the same situation.
check the below link for getting the data from the controller before view(JSP) load.
how to load the data into index page

Spring MVC 3.0 - restrict what gets routed through the dispatcher servlet

I want to use Spring MVC 3.0 to build interfaces for AJAX transactions. I want the results to be returned as JSON, but I don't necessarily want the web pages to be built with JSP. I only want requests to the controllers to be intercepted/routed through the DispatcherServlet and the rest of the project to continue to function like a regular Java webapp without Spring integration.
My thought was to define the servlet-mapping url pattern in web.xml as being something like "/controller/*", then have the class level #RequestMapping in my controller to be something like #RequestMapping("/controller/colors"), and finally at the method level, have #RequestMapping(value = "/controller/colors/{name}", method = RequestMethod.GET).
Only problem is, I'm not sure if I need to keep adding "/controller" in all of the RequestMappings and no matter what combo I try, I keep getting 404 requested resource not available errors.
The ultimate goal here is for me to be able to type in a web browser "http://localhost:8080/myproject/controller/colors/red" and get back the RGB value as a JSON string.
You are not correct about needing to add the entire path everywhere, the paths are cumulative-
If you have a servlet mapping of /controller/* for the Spring's DispatcherServlet, then any call to /controller/* will be handled now by the DispatcherServlet, you just have to take care of rest of the path info in your #RequestMapping, so your controller can be
#Controller
#RequestMapping("/colors")
public class MyController{
#RequestMapping("/{name}
public String myMappedMethod(#PathVariable("name") String name, ..){
}
}
So now, this method will be handled by the call to /controller/colors/blue etc.
I don't necessarily want the web pages to be built with JSP
Spring MVC offers many view template integration options, from passthrough to raw html to rich templating engines like Velocity and Freemarker. Perhaps one of those options will fit what you're looking for.

JSF 2 - clearing component attributes on page load?

The real question: Is there a way to clear certain attributes for all components on an initial page load?
Background info:
In my application, I have a JSF 2.0 frontend layer that speaks to a service layer (the service layer is made up of Spring beans that get injected to the managed beans).
The service layer does its own validation, and I do the same validation in the frontend layer using my own validator classes to try and avoid code duplication somehow. These validator classes aren't JSF validators, they're just POJOs.
I'm only doing validation on an action, so in the action method, I perform validation, and only if it's valid do I call through to the service layer.
When I do my validation, I set the styleClass and title on the UIComponents using reflection (so if the UIComponent has the setStyleClass(:String) or setTitle(:String) methods, then I use them).
This works nicely, and on a validation error I see a nicely styled text box with a popup containing the error message if I hover over it. However, since the component is bound to a Session Scoped Managed Bean, it seems that these attributes stick. So if I navigate away and come back to the same page, the styleClass and title are still in the error state.
Is there a way to clear the styleClass and title attributes on each initial page load?
Thanks,
James
P.S. I'm using the action method to validate because of some issues I had before with JSF 1.2 and it's validation methods, but can't remember why... so that's why I'm using the action method to validate.
Ok, so I must use a PhaseListener, see this blog entry by BalusC and this other blog entry, that's a much better way of doing what I'm doing already - setting the styleClass manually using reflection - which gets all components with messages and highlights them... I'm gonna do the same, however think it's possible to add an attribute instead, haven't tried it yet.

Resources