Thymleaf not returning templates but strings - spring

I'm building an application with thymeleaf, and i've encountered this problem where when returning a template as for example ...return "products";... and when I visit the url i addressed in #GetMapping() i get the string "products" instead of rendered template
.
#Service
public class HomeService {
#Autowired
ProductRepository productRepository;
public String getProducts(Model model) {
List<Product> products= productRepository.findAll();
if (!products.isEmpty()){
model.addAttribute("product", products);
return "products";
}else{
return "404";
}
}
}
#RestController
public class HomeController {
#Autowired
HomeService homeService;
#GetMapping("/home")
public String home(Model model){
return homeService.getProducts(model);
}
}

As stated above, the #RestController annotation should be replaced with the #Controller annotation.
The #RestController annotation in Spring is designed for building REST web services that return data in JSON or XML format, and it does not support the use of view templating engines like Thymeleaf. If you want to render HTML views, you should use the #Controller. In #Controller, we can return a view in Spring Web MVC.

Use #Controller, #RestController is for RestAPI only, and not MVC ;)

Related

How to call Spring Boot RESt api using Spring MVC?

I have created REST api using Spring Boot.
So, that is the fragment of it:
#RestController
#RequestMapping("/api/employee")
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#GetMapping(value = "/all", produces = "application/json")
public ResponseEntity<List<Employee>> getAllEmployees() {
return ResponseEntity.ok(employeeService.findall());
}
Now, I would like to create more like MVC application part - simple view that shows all Employees using thymeleaf. (Just simple UI to use this app more convinient than sending curl requests)
#Controller
public class MainPageController {
#GetMapping("/employees")
public String showEmployees() {
// i don't know what to do here
return "employeesPage";
}
What is the appropriate way to do so? Is there a more simple way to do it?
Looking forward for your answers!
So you do exactly the same you did on your EmployeeController but instead of a JSON, you return a view.
Get your employes through EmployeeService and put them on a collection
Create your employee view under /templates folder (many tutorials of how to do it)
return this view with your collection of employees
Example:
#GetMapping(value = "employees")
public ModelAndView showEmployees() {
ModelAndView mav = new ModelAndView("employeesPage");
mav.addObject("employees", employeeService.findall());
return mav;
}
Check here for more detailed info:
https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html

AutoConfigure RestController Spring Boot

I have tried to find documentation on how to manually configure a RestController (i.e in a Configuation class). That means without using the RestController annotation. Considering all the other annotations, like mapping, pathvariables etc. is at all possible?
A controller is essentially a component with a request mapping. See RequestMappingHandlerMapping.
#Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
If you want to instantiate a "rest controller" through configuration, you can probably do so via the following:
#Configuration
public class MyConfiguration {
#Bean
public MyController() {
return new MyController();
}
}
#ResponseBody
public class MyController {
#RequestMapping("/test")
public String someEndpoint() {
return "some payload";
}
}
But I don't think you'll be able to configure the request mappings (path variables, etc) in the configuration though; at least I haven't seen an example nor figured out how.

How to resolve return modal not working in spring boot

#PostMapping("/api/file/delete")
public String deleteMultipartFile(HttpServletRequest request) {
try {
String keyname=request.getParameter("keyname");
s3Services.deleteFile(keyname);
return "redirect:/welcome";
} catch(Exception e) {
return "redirect:/welcome";
}
}
Actual result :
printing "redirect:/welcome " in white page
Expected Result : it redirect to welcome modal.
Spring is a Java application framework and Spring boot is an evloution of Spring that helps create stand-alone, production-grade spring based application that you can "just run".
Spring boot supports #Controller and #RestController annotation, where
#Controller annotation indicates that the annotated class is a controller. It is a specialization of #Component and is autodetected through classpath scanning. It is typically used in combination with annotated handler methods based on the #RequestMapping annotation. #RestController is a sibling convenience annotation for creating Restful controllers.
If you created spring boot application having controller with annotation #Controller and you have #GetMapping method which return index.html(file location /src/main/resources/templates/index.html) view page. like code below :-
#Controller
public class MyController{
#GetMapping("/")
public String indexPage(){
return "index";
}
#GetMapping("/index")
public String routeWithIndex(){
return "redirect:/";
}
}
Both function returns index.html page. If you want more knowledge about spring annotation of #Controller and #RestController with examples visit baeldung site or official site about spring.

Controller or RestController

i'm new to jEE, and this is my first jEE code using spring. The code bellow is working fine. He just print the string index when i go to my localhost; and otherwise he print handling error.
My question is: Why this code isn't working anymore if I use #Controller instead of #RestController
I can't find any simple explanation in the docs from spring and I was hoping someone could explain this.
I have the feelings that a controller alone can't work without something like thymeleaf (I know if I were using thymeleaf the string index would be replaced by the index page from the ressources folder) where a RestController might be returning data as xml or json or something else.
Thanks
#RestController
public class HelloController implements ErrorController {
#RequestMapping("/")
public String index() {
return "index";
}
#RequestMapping("/error")
public String error() {
return "gestion erreur";
}
#Override
public String getErrorPath() {
return "/error";
}
}
The job of #Controller is to create a Map of model object and find a view but #RestController simply return the object and object data is directly written into HTTP response as JSON or XML.
The #Controller is a common annotation which is used to mark a class as Spring MVC Controller while #RestController is a special controller used in RESTFul web services and the equivalent of #Controller + #ResponseBody.
If you want the same functionality of #RestController without using it you can use #Controller and #ResponseBody.
#Controller
public class HelloController{
#RequestMapping("/")
#ResponseBody
public String index() {
return "index";
}
}

Dependency injection in Spring MVC?

I am trying to use dependency injection in my Spring MVC web application. I have a function like this in my controller
#RequestMapping(value = "/stockgoogle/", method = RequestMethod.GET)
public #ResponseBody Stock stockGoogle(Locale locale, Model model) {
StockDaoImpl si = new StockDaoImpl();
//al=s.listCurrent(id);
Stock s=si.listGoogle();
System.out.println("reached here");
model.addAttribute("s", s );
return s;
}
I want to dependency inject StockDaoImpl. Can you please tell me how I can do this. I have been trying to read but most of the explainations are very complex. Should I use #Autowired ? Where should I put it? Can you please help.
You can inject it through the Controller's constructor
class YourController{
private final StockDao dao;
#Autowired
public YourController(StockDao dao){
this.dao = dao;
}
}
And now StockDaoImpl has to be defined as a Bean of course,
#Bean
public StockDao stockDao(){
return new StockDaoImpl();
}
Another way for doing it would be defining StockDaoImpl as a Component
Add below config in Spring config file(for example root-context.xml)
then in your controller, you like below code
class TestController{
#Autowired
private StockDao stockDao;
}
With spring-4 you can directly inject in given way :
#Autowired
private StockDao stockDao;
public #ResponseBody Stock stockGoogle(Locale locale, Model model) {
//al=s.listCurrent(id);
Stock s = stockDao.listGoogle();
System.out.println("reached here");
model.addAttribute("s", s );
return s;
}
Here
StockDao will contain method signature
StockDaoImpl implements StockDao and definition of methods
Autowired will inject that Dao and you can use its method.

Resources