issue with springboot project : org.thymeleaf.exceptions.TemplateInputException - java

hey guys i have a problem in my java spring boot application
i've built a simple application and connected it with a database
but when i try to make a POST or GET on the data base my program access the database and do any thing i did but show an error
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "Students", template might not exist or might not be accessible by any of the configured Template Resolvers
when i make GET i check the Iterable list and it's already get the data from database
but doesn't show the data on the localhost
it's give me that exception
is there any solution for that ?
this is my code in controller
#Path("Students")
#Controller
public class studentsController {
#AutoWired
StudentServices st;
#RequestMapping(method = RequestMethod.GET)
public Iterable<Students> getAllStudents() {
Iterable<Students> list = st.getAllStudents();
return list
}

With #Controller you are defining a Model-View-Controller (MVC) endpoint for returning your view templates. So with Iterable<Students> Spring is looking for a Students template in your src/main/resources/templates folder because it is interpreted as a View name.
If you want to create a REST endpoint which returns a list of Student objects you should use #RestController at your class which adds the Spring annotation #RequestBody automatically.
Furthermore #Path("XYZ") should be replaced with #RequestMapping("XYZ") in Spring and #AutoWired with #Autowired.
An working example could look like the following:
#RequestMapping("/students")
#RestController
public class StudentsController {
#Autowired
StudentServices st;
#RequestMapping(value="/", method = RequestMethod.GET)
public Iterable<Students> getAllStudents() {
Iterable<Students> list = st.getAllStudents();
return list
}

Related

Spring Boot | Using a separate file for logic

I am writing a small CRUD in Spring and Java. And I want to use a separate file for writing logic, this is very convenient for me, I did this when developing with NestJS. I have a few questions, is it correct to do this in Spring, or should I do everything inside a function in the controller. And if I write logic in a separate file, I should mark the logic class as #Component and the functions inside it as #Bean, right? I am new to Spring and as I understand it, I have to do this in order for the application to work correctly and my functions to be in the application context.
AuthLogic.java
#Component
public class AuthLogic {
#Bean
public void register() {
// code ...
}
}
AuthController.java
#RestController
public class AuthController {
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
// here I call the register function from AuthLogic
}
}
you can mark your logic class with #Service and use that for example you can make a AuthService and use it like
#Service
public class AuthService{
public returnType login(){
//Logic
}
}
and use this like
#RestController
public class AuthController {
AuthService authService;
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
authService.login();
}
}
You can write your business logic in a new separate file at service layer.
Suppose you name it as AuthService and you mark it with annotation #Service.
#Service
public class AuthService{
}
You can then Autowire it in your controller class.
#RestController
public class AuthController {
#Autowired
AuthService authService;
#RequestMapping(value = "/register", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public void register(#Valid #RequestBody UserDTO newUser) {
// here I call the register function from AuthLogic
}
}
Using separate files, or classes more importantly, is very recommended in Spring, and I assume most other languages.
The #Bean annotation on AuthLogic.java is unneeded and I think may cause startup or compilation errors.
I would change the name of AuthLogic to AuthLogicImpl, create an interface named AuthLogic with the method signature void register(), and have AuthLogicImpl implement AuthLogic. Then you can create a constructor for AuthController which accepts and AuthLogic parameter and sets it to a private field (note using the interface not the implementation in the constructor).
At the core of Spring is the IoC container. This container holds "beans" that can be injected or autowired into other beans. These beans are an instance of their class and can be used by other beans. Remember Spring uses the singleton pattern, so your beans should be stateless. This allows Spring to handle the application startup for you, so you don't need to write a ton of code creating all the different services/classes and wiring them together, it's all automagically done for you.
There are two key annoitations that you appear to be confused about:
#Component Putting this above a class will create an instance of that class (a bean) and put it into the IoC container. Other beans can access this by accepting the original beans interface in its constructor. So if I put #Component above my class FooImpl which implements Foo, then I can create a class, BarImpl with the constructor public BarImpl(Foo foo) {this.foo = foo} and BarImpl can use any public method of Foo (which will use FooImpl's implementation).
#Bean this is to be put on a method of a class that is annotated with #Configuration. This tells Spring that this method should be run at startup, and this method will return a bean that Spring should add to the IoC container. This is a popular way of configuring a bean that requires some parameters, such as the bean that manages the connection to a third party service or datastore, especially when that there is a little bit of logic that needs to go into creating the bean.
Note that the above is very broad, and there are some specifics if you need to dig deep into the spring framework, so there will be more clarification in the Spring documentation or you dig into some established Spring project. However it should suffice to answer the broad question of what is going on with #Component and #Bean.
There is no specific layout or code structure for Spring Boot Projects. However, there are some best practices followed by developers that will help us too. You can divide your project into layers like service layer, entity layer, and repository layer.
We use the entity layer to write all model and POJO classes. We annotate them with #Entity.
We use #Repository to indicate that this is a repository interface that is used to do some basic CRUD operations.
Sidenote:- You don't have to write #Repository for classes that implement or interfaces that extends Repository interfaces provided by Spring Boot framework.
We use #Service to say that this is the service class where your all business logic will be present.
We use the controller layer to receive HTTP requests and send back HTTP Responses or views.
You can learn and understand more from here
You can refer to this Image to understand the structure
project structure

How to hide only one mapping from swagger ui documentation if I more than one mapping for method in Spring boot

I've one spring boot rest controller method which is mapped to multiple mappings. Please find the example code below.
#RestController
public class HomeController {
#RequestMapping( {"/", "/home"} )
public String home() {
return "Hello, World!";
}
}
I want to hide /home mapping from swagger documentation.
Can someone please help me to achieve this.
I also searched for a way to hide certain URLs from multi mapping methods. Unfortunately, I don't think it's possible when multi mapping it's defined like this #RequestMapping( {url1, url2} )
There are 2 alternative ways to do it:
Split your method into 2 methods that call the same function and annotate the one you want to hide with #Operation(hidden=true)
Define exceptions in your swagger config (for swagger 3 which uses open API):
#Configuration
public class SwaggerConfig {
#Bean
public GroupedOpenApi myApi()
{
return GroupedOpenApi.builder()
.pathsToMatch("/**")
.pathsToExclude("/home")
.build();
}
}

Spring boot return 404 given that debugger hits the breakpoint I set in the controller. How can I fix it?

I used IntelliJ to create a web application with Spring boot which runs on Tomcat using Mustache and Gradle.
My TestController.java and TestApplication.java are in the same package (com.example.test).
Here is the TestApplicaiton.java
#SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
Here is the TestController:
#Controller
public class TestController {
#GetMapping(value = "/")
public ModelAndView index(#RequestParam(name="name", required=false, defaultValue="World") String name, Model model) {
return new ModelAndView("index");
}
}
I put the index.html under both /resources/static and /resources/templates. Still, the page says
404 not found (Whitelabel Error Page).
If I change the #controller annotation to #RestController and change the return type to String, it returns the string properly.
So, it seems like something went wrong when resolving the view. However, it doesn't throw an exception. I noticed that mvContainer view is null when I stepped into the code.
Can someone help?
I think you need to configure ViewResolver to resolve view by name.
Here is a guide: https://www.baeldung.com/spring-mvc-view-resolver-tutorial
For me, I finally found out that I should rename the file extension to .mustache instead of using .html. This will work with the out of the box configuration. Here is an example code I found online:
https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-web-mustache
I have not found out the exact way to override the template path and file extension while having the app still recognize it is a mustache template. So, it will compile before returning it.

SpringBoot Rest api

I want to make a simple java application and I want to use CRUDREPOSITORY and my own repository. I have this:
#RestController
#Transactional
#ExposesResourceFor(Person.class)
#RequestMapping("/prueba")
public class PersonController {
#RequestMapping(value="/prueba", method=RequestMethod.GET)
public String person(#RequestParam(value="id", defaultValue="1") int id) {
return "hola"+id;
}
}
this:
#RepositoryRestResource
public interface IClientRepository extends CrudRepository<Client, Long> {
}
The problem is that the CRUD works well, but I canĀ“t call my localhost:8080/prueba/prueba because it gives a 404 error. I have try all and I cant access it, please help me!!
By default, Spring Data REST serves up REST resources at the root URI, "/". There are multiple ways to change the base path.
With Spring Boot 1.2+, add below to application.properties:
spring.data.rest.basePath=/api
In your case:
spring.data.rest.basePath=/prueba/prueba
, assuming there is no override for server.contextPath in application.properties
Reference:
http://docs.spring.io/spring-data/rest/docs/current/reference/html/

Spring project with REST and MongoDB - 404 pages and nothing working

I'm trying to get a Spring project to work with a simple rest service and a repository which fetches data from a MongoDB database. At this moment two separate things are working:
I can run this simple REST example: https://spring.io/guides/gs/rest-service/
I can connect to the MongoDB instance and fetch data
This both in separate projects.
I don't see, however, how I can bring these two together properly. At this moment I've tried the following based on several other tutorials and references (for example https://spring.io/guides/gs/accessing-mongodb-data-rest/). We now have 2 configs but when we deploy and try to go to rest url we just get 404's. it's not clear to me if the mapping is alright, I also don't see how the mapping is done in the first simple REST example.
Rest Controller:
#RestController
public class UserController {
#Autowired
private UserRepository userRepository;
#RequestMapping(value = "/users/{emailaddress}", method = RequestMethod.GET)
#ResponseBody
public User getUser(#PathVariable("emailaddress") String email) {
User user = userRepository.findByEmailAddress(email);
return user;
}
}
The Application class (as done in the tutorials):
#Configuration
#ComponentScan
#EnableAutoConfiguration
#Import(MongoConfig.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The MongoConfig class (which we assume is about right but not 100% sure):
#Configuration
public class MongoConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "<dbname>";
}
#Override
public Mongo mongo() throws Exception {
MongoCredential mongoCredential = MongoCredential.createPlainCredential("<username>", "<dbname>", "<pswd>".toCharArray());
return new MongoClient(new ServerAddress("<dbaddress>", <port>), Arrays.asList(mongoCredential));
}
}
I really hope someone can shed some light on how to this best, we don't need a Spring (MVC) front-end, just a REST service which will get data from our MongoDB.
Thanks in advance.
I too had this problem, I still get 404 error while running through eclipse tomcat, but I deployed the war in the tomcat webapps and ran through the server which worked for me.

Categories

Resources