Spring Boot Application ,JPA, - spring-boot

I have created a small application using the spring boot framework. I have created a Rest Controler class.
and deploy it on tomcat, but I am getting 404 error i.e
The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
#RestController
#RequestMapping("students")
public class StudentController {
#Autowired
StudentRepository repository;
#GetMapping
public List<Student> getAllStudents() {
return (List<Student>) repository.findAll();
}
#PostMapping
public String createStudent() {
return "created";
}
#PutMapping
public String updateStudent() {
return "updated";
}
#DeleteMapping
public String deleteStudent() {
return "deleted";
}
}

You are missing slash in annotation, it should look like this
#RestController
#RequestMapping("/students")
public class StudentController {
...
}

Related

how to split resource in spring boot

In Jersey we can do something like
#Path("/")
public class TopResource{
#GET
public Response getTop() { ... }
#Path("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
public class ContentResource {
#GET
public Response getContent() { ... }
}
so,
https://<host> will invoke getTop()
https://<host>/content will invoke getContent()
is there any equivalent in Spring?
I tried
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
#RequestMapping("content")
public ContentResource getContentResource() {
return new ContentResource();
}
}
#RestController
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}
only top resource works. content would return 404 Not Found.
Not sure how to do this in Spring Boot.
Tried replacing #RestController with #Resource and #Controller for content, but still got 404 Not Found.
There is no option to retun a whole class, please use the Annotation #RequestMapping on top of your content class to split them up.
#RestController
#RequestMapping("/")
public class TopResource{
#GetMapping()
public Response getTop() { ... }
}
#RestController
#RequestMapping("content")
public class ContentResource {
#GetMapping()
public Response getContent() { ... }
}

Transform MVC to layered Architecture in Spring Boot

I have a classic Spring Boot app, you can see the structure:
I am trying to modify it to have at the end a Layered Architecture.
The problem is that to isolate the layers we must to use APIs between layers,so I have no idea how to create API's for each Layer, maybe you can give some examples?
Here is the classic structure of Layered Arch.
And this is my structure.
Some codes from my app:
#Controller
public class UserController {
…
#PostMapping("/saveUser")
public String saveUser(#ModelAttribute("user") User theUser…){
theUser.setPassword(value);
userService.save(theUser);
}
…
}
...
#Service
#Component("userService")
public class UserServiceImpl implements Services<User> {
…
#Override
#Transactional
public void save(User theUser) {
theUser.setPassword(passwordEncoder.encode(theUser.getPassword()));
userDao.saveUser(theUser);
}
…
}
...
#RestController
#RequestMapping("/api")
public class AnnonceRestController {
#GetMapping("/announce-all")
public List<Annonce> findAll() {
return annonceService.findAll();
}
#PostMapping("/announce-create")
public Annonce addAnnonce(#RequestBody Annonce theAnnonce) {
theAnnonce.setId(0);
theAnnonce.setDate(null);
annonceService.save(theAnnonce);
return theAnnonce;
}

rest controller for Spring Data REST repository

I have implemented a simple Spring Data REST repository which works as expected and I am fine with it exposing all methods. This is what it looks like:
#RepositoryRestResource(path = "employees")
public interface EmployeeRepository extends PagingAndSortingRepository<Employees, Integer>
{ }
Now I would like to wrap this repository in a controller, so I can later add Hystrix to it for fallbacks and exception handling. My issue is now, that I would like to keep the behavior of the repository above and just pass the response through the controller to the client. Is there a possible way without reimplementing all the methods of my repository (including sorting and pagination)?
This is what my controller currently looks like:
#RepositoryRestController
public class EmployeeController {
private final EmployeeRepository repository;
#Autowired
public EmployeeController(EmployeeRepository repo) {
repository = repo;
}
// Here I would like to return the same respone as my repository does
#RequestMapping(method = GET, value = "/employees")
public #ResponseBody ResponseEntity<?> parseRequest() {
return ResponseEntity.ok("hi");
}
}
It seems that you could simply call the method from your repository. Did you try it?
#RepositoryRestController
public class EmployeeController {
private final EmployeeRepository repository;
#Autowired
public EmployeeController(EmployeeRepository repository) {
this.repository = repository;
}
#RequestMapping(method = GET, value = "/employees")
public #ResponseBody ResponseEntity<List<Employee>> parseRequest() {
List<Employee> employees = repository.getEmployees();
return new ResponseEntity(employees, HttpStatus.OK);
}
}

SecurityContextHolder.getContext().getAuthentication() always return 'anonymousUser'

I created Spring boot application with the following configuration:
Spring boot 2.1.0.RELEASE
OpenJdk 11
I have an AuditConfiguration class in my project that looks like:
#Configuration
#EnableJpaAuditing(auditorAwareRef = "auditorProvider")
public class AuditConfiguration {
#Bean
public AuditorAware<String> auditorProvider() {
return new AuditorAwareImpl();
}
class AuditorAwareImpl implements AuditorAware<String> {
#Override
public Optional<String> getCurrentAuditor() {
Principal principal =
SecurityContextHolder.getContext().getAuthentication();
return Optional.of(principal.getName());
}
}
}
and SecurityContextHolder.getContext().getAuthentication() always returns anonymousUser.
However, the following code returns the correct user name.
#RestController
#RequestMapping("/history")
public class HistoryEndpoint {
#RequestMapping(value = "/username", method = RequestMethod.GET)
#ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
I need your help for resolving this issue.
I got authenticared user using following class. i had problem with JPA Auditing.
#CreatedBy always saved null. then i tried to get authenticated user SecurityContextHolder.getContext().getAuthentication() using this method. that method returned annonymousUser. however my issue is fixed.
#ManagedBean
#EnableJpaAuditing
public class SpringSecurityAuditorAware implements AuditorAware<String> {
private final HttpServletRequest httpServletRequest;
public SpringSecurityAuditorAware(HttpServletRequest httpServletRequest) {
this.httpServletRequest = httpServletRequest;
}
#Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(httpServletRequest.getUserPrincipal())
.map(Principal::getName);
}
}

Spring boot application not identifying controller and repository beans

I have this project structure
com.demo.application
- DemoApplication.java
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
System.out.println("inside main");
SpringApplication.run(DemoApplication.class, args);
}
}
I have another package
com.demo.application.employee
- EmployeeController.java
- EmployeeInterface.java
- Employee.java (Entity Bean)
#Controller
#RequestMapping("/getAll")
public class EmployeeController {
#Autowired
EmployeeInterface empInterface;
public ModelAndView getEmployees() {
System.out.println("inside controller");
return new ModelAndView("employee", "employee", empInterface.findAll());
}
}
#Repository
public interface EmployeeInterface extends JpaRepository<Employee, Long>{
}
When i access the below URL i get 404. The reason is the Controller and Repository beans are not loaded.
http://localhost:8080/getAll
Any help?
Your getAll does not associated with any controller handler.
Add #RequestMapping to your getEmployees() method:
#RequestMapping
public ModelAndView getEmployees() {
But it's not very intuitive. You should annotated your controller with the base path and your method with specific path:
#Controller
#RequestMapping("/employee")
public class EmployeeController {
#Autowired
EmployeeInterface empInterface;
#RequestMapping("/getAll")
public ModelAndView getEmployees() {
System.out.println("inside controller");
return new ModelAndView("employee", "employee", empInterface.findAll());
}
}
Now your URL looks like: localhost:8080/employee/getAll

Resources