My application is running with an exception. When I try to post to localhost:8080/addUser I get the error that there is no mapping. However I have it in my UserController.java:
2021-10-03 20:28:04.852 INFO 9896 --- [ngodb.net:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server edumeet-shard-00-01.egesp.mongodb.net:27017
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:112) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:131) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:647) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveMessageWithAdditionalTimeout(InternalStreamConnection.java:512) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:355) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:279) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:107) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:62) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:144) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:188) ~[mongodb-driver-core-4.2.3.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:144) ~[mongodb-driver-core-4.2.3.jar:na]
at java.base/java.lang.Thread.run(Thread.java:835) ~[na:na]
2021-10-03 20:28:05.681 INFO 9896 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-10-03 20:28:05.692 INFO 9896 --- [ restartedMain] com.example.login.LoginApplication : Started LoginApplication in 3.95 seconds (JVM running for 4.612)
2021-10-03 20:28:17.960 INFO 9896 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-10-03 20:28:17.960 INFO 9896 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2021-10-03 20:28:17.996 INFO 9896 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 36 ms
2021-10-03 20:28:18.025 WARN 9896 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for POST /addUser
2021-10-03 20:28:18.032 WARN 9896 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for POST /error
UserController.java
package com.example.login.User;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#Controller
#RestController
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
#RequestMapping(path = "/addUser", method = RequestMethod.POST)
public String addUser(#RequestBody User user) {
userRepository.save(user);
return "added user with id: " + user.getId();
}
#RequestMapping(path = "/getAllUsers", method = RequestMethod.GET)
public List<User> getAllUsers() {
return userRepository.findAll();
}
#RequestMapping(path = "/getAllUsers/{id}", method = RequestMethod.GET)
public Optional<User> getUser(#PathVariable String id) {
return userRepository.findById(id);
}
#RequestMapping(path = "/removeUser", method = RequestMethod.DELETE)
public String deleteUser(#PathVariable String id) {
userRepository.deleteById(id);
return "removed user with id" + id;
}
}
LoginApplication.java
package com.example.login;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
#SpringBootApplication
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class,WebMvcAutoConfiguration.class})
public class LoginApplication {
public static void main(String[] args) {
SpringApplication.run(LoginApplication.class, args);
}
}
you should change path to value as shown below:
#RequestMapping(path = "/addUser", method = RequestMethod.POST)
public String addUser(#RequestBody User user) {
userRepository.save(user);
return "added user with id: " + user.getId();
}
change to
#RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String addUser(#RequestBody User user) {
userRepository.save(user);
return "added user with id: " + user.getId();
}
Related
I'm actually defining login with websecurity enabled, and i don't really know what is wring with my annotations that don't allow me to continue testing...
Here is the trace:
2021-10-29 13:58:09.436 INFO 10044 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-10-29 13:58:09.447 INFO 10044 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-10-29 13:58:09.447 INFO 10044 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-10-29 13:58:09.534 INFO 10044 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-10-29 13:58:09.534 INFO 10044 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1188 ms
2021-10-29 13:58:09.682 INFO 10044 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-10-29 13:58:09.731 INFO 10044 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-10-29 13:58:09.845 INFO 10044 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-10-29 13:58:09.933 INFO 10044 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-10-29 13:58:10.065 INFO 10044 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-10-29 13:58:10.089 INFO 10044 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL55Dialect
2021-10-29 13:58:10.628 INFO 10044 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-10-29 13:58:10.636 INFO 10044 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-10-29 13:58:10.670 WARN 10044 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-10-29 13:58:10.687 WARN 10044 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'personaDetails'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.taxig10.demo.service.PersonaDetailsImpl' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2021-10-29 13:58:10.687 INFO 10044 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-10-29 13:58:10.689 INFO 10044 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2021-10-29 13:58:10.695 INFO 10044 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2021-10-29 13:58:10.696 INFO 10044 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-10-29 13:58:10.706 INFO 10044 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-10-29 13:58:10.720 ERROR 10044 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field personaDetails in com.taxig10.demo.config.WebSecurityConfig required a bean of type 'com.taxig10.demo.service.PersonaDetailsImpl' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.taxig10.demo.service.PersonaDetailsImpl' in your configuration.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
And my classes:
// app class
package com.taxig10.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class TaxiG10Application {
public static void main(String[] args) {
SpringApplication.run(TaxiG10Application.class, args);
}
}
// config class
package com.taxig10.demo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.taxig10.demo.service.PersonaDetailsImpl;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private PersonaDetailsImpl personaDetails;
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(personaDetails).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/","/auth/**","public/**","/css/**","/js/**")
.permitAll().anyRequest().authenticated()
.and()
.formLogin().loginPage("/auth/index/").defaultSuccessUrl("/private/index",true).failureUrl("/auth/login?error=true")
.loginProcessingUrl("/auth/login-post").permitAll()
.and()
.logout().logoutUrl("/logout/").logoutSuccessUrl("public/index");
}
}
// IPersona class
package com.taxig10.demo.interfaces;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.taxig10.demo.modelo.Persona;
#Repository
public interface Ipersona extends CrudRepository<Persona, Integer> {
}
// IpersonaService class
package com.taxig10.demo.interfaceService;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Optional;
import javax.mail.MessagingException;
import com.taxig10.demo.modelo.Persona;
public interface IpersonaService {
public List<Persona> listar();
public Optional<Persona> listarId(int id);
public Persona save(Persona p) throws UnsupportedEncodingException, MessagingException;
public void delete(int id);
boolean login(Persona persona);
int confirm(Persona p);
boolean isAdmin(String name);
void logout(Persona persona);
// ---
public Persona getPersonaFromBD(String name);
public Persona registrar(Persona p);
}
// PersonaService class
package com.taxig10.demo.service;
#Service
public class PersonaService implements IpersonaService {
#Autowired
private Ipersona data;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#Override
public List<Persona> listar() {
return (List<Persona>)data.findAll();
}
#Override
public Persona getPersonaFromBD(String name) {
Iterator<Persona> personas = data.findAll().iterator();
while(personas.hasNext()) {
Persona cont = personas.next();
if(cont.getName().equals(name)) {
return cont;
}
}
return null;
}
}
// PersonaDetailsImpl class
package com.taxig10.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.User.UserBuilder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.taxig10.demo.interfaceService.IpersonaService;
import com.taxig10.demo.modelo.Persona;
public class PersonaDetailsImpl implements UserDetailsService{
#Autowired
private IpersonaService personaService;
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Persona persona = personaService.getPersonaFromBD(name);
UserBuilder builder = null;
if(persona != null) {
builder = User.withUsername(name);
builder.disabled(false);
builder.password(persona.getPwd());
builder.authorities(new SimpleGrantedAuthority("ROLE_USER"));
} else {
throw new UsernameNotFoundException("Usuario no encontrado");
}
return builder.build();
}
}
Thank you in advance <3
I started with a spring boot starter project version 2.3.5, but when I call authenticationManager.authenticate I get a stack overflow error.
java.lang.StackOverflowError: null
at ch.qos.logback.classic.Logger.callTurboFilters(Logger.java:751) ~[logback-classic-1.2.3.jar:na]
at ch.qos.logback.classic.Logger.isDebugEnabled(Logger.java:469) ~[logback-classic-1.2.3.jar:na]
at ch.qos.logback.classic.Logger.isDebugEnabled(Logger.java:465) ~[logback-classic-1.2.3.jar:na]
at org.apache.commons.logging.LogAdapter$Slf4jLog.isDebugEnabled(LogAdapter.java:310) ~[spring-jcl-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:186) ~[spring-security-core-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:524) ~[spring-security-config-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:219) ~[spring-security-core-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:524) ~[spring-security-config-5.3.5.RELEASE.jar:5.3.5.RELEASE]
Initially I did not use the user variable and instead created created the new UsernamePasswordAuthenticationToken inside the authenticationManager.authenticate either way I get the stack overflow error. I also have tried #PostMapping instead of #RequestMapping and Method. All of these cause the same failure.
I get the printline that says I am "in /Authenticate" with the following.
2020-11-09 16:20:32.141 DEBUG 10456 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to io.javabrains.springsecurityjwt.HelloResource#createAuthenticationToken(AuthenticationRequest)
2020-11-09 16:20:32.188 DEBUG 10456 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [io.javabrains.springsecurityjwt.models.AuthenticationRequest#758a32c5]
in /Authenticate
2020-11-09 16:20:32.197 DEBUG 10456 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Failed to complete request: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError
2020-11-09 16:20:32.201 ERROR 10456 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
Here is the full code of the Class
Thank you for any info or things I should try!
package io.javabrains.springsecurityjwt;
import io.javabrains.springsecurityjwt.models.AuthenticationRequest;
import io.javabrains.springsecurityjwt.models.AuthenticationResponse;
import io.javabrains.springsecurityjwt.services.MyUserDetailsService;
import io.javabrains.springsecurityjwt.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloResource {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private MyUserDetailsService userDetailsService;
#Autowired
private JwtUtil jwtTokenUtil;
#RequestMapping( "/hello")
public String hello() {
return "Hello World";
}
#RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(#RequestBody AuthenticationRequest authenticationRequest) throws Exception {
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword());
System.out.println("in /Authenticate");
try {
authenticationManager.authenticate(
user
// new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
);
System.out.println("in Try in /Authenticate");
} catch (BadCredentialsException e) {
throw new Exception("Incorrect Username or Password", e);
}
System.out.println("outside the try catch");
final UserDetails userDetails = userDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
}
I'm trying to write a basic application with rest api's connecting with a postgres database to perform couple of crud operations. When I run the application it starts successfully. But when I go to the url "http://localhost:8080/employees" or http://localhost:8080", it shows "This localhost page can’t be found. No webpage was found for the web address: http://localhost:8080/employees. HTTP ERROR 404".
Here is my TestApplication.java
package com.ranjana.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.http.HttpStatus;
#SpringBootApplication
#EntityScan(basePackages = {"com.ranjana.test.model"})
#ComponentScan(basePackageClasses = EmployeeController.class)
public class TestApplication implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
#Override
public void customize(ConfigurableServletWebServerFactory factory) {
factory.addErrorPages(new ErrorPage(HttpStatus.FORBIDDEN, "/errors/403.html"));
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/404.html"));
factory.addErrorPages(new ErrorPage("/errors/500.html"));
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
The controller class - EmployeeController.java :
package com.ranjana.test.controller;
import com.ranjana.test.repositoy.EmployeeRepo;
import com.ranjana.test.exception.ResourceNotFoundException;
import com.ranjana.test.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#RestController
#RequestMapping("/api/v1")
public class EmployeeController {
#Autowired
private EmployeeRepo empRepo;
#GetMapping("/employees")
public List<Employee> getAllEmployees(){
System.out.printf(empRepo.findAll().toString());
return empRepo.findAll();
}
#GetMapping("/employee/{id}")
public ResponseEntity<Employee> getUsersById(#PathVariable(value = "id") Long emplId)
throws ResourceNotFoundException {
Employee employee = empRepo.findById(emplId).orElseThrow(() -> new ResourceNotFoundException("Employee not found for id: " + emplId));
return ResponseEntity.ok().body(employee);
}
#PostMapping("/employees")
public Employee createEmployee(#Valid #RequestBody Employee employee){
System.out.println(employee.toString());
return empRepo.save(employee);
}
#PutMapping("/employee/{id}")
public ResponseEntity<Employee> updateEmployee(#PathVariable(value = "id") Long emplId, #Valid #RequestBody Employee empDetails)
throws ResourceNotFoundException{
Employee employee = empRepo.findById(emplId).orElseThrow(() -> new ResourceNotFoundException("Employee not found for id: " + emplId ));
employee.setFirstName(empDetails.getFirstName());
employee.setLastName(empDetails.getLastName());
employee.setEmailId(empDetails.getEmailId());
employee.setContactNumber(empDetails.getContactNumber());
employee.setUpdateDateTime(new Date());
final Employee updatedEmployee = empRepo.save(employee);
return ResponseEntity.ok(updatedEmployee);
}
#DeleteMapping("/employee/{id}")
public Map<String, Boolean> deleteEmployee(#PathVariable(value = "id") Long emplId)
throws Exception{
Employee employee = empRepo.findById(emplId).orElseThrow(() -> new ResourceNotFoundException("Employee not found for id: " + emplId));
empRepo.delete(employee);
Map <String, Boolean> response= new HashMap<>();
response.put("Deleted", Boolean.TRUE);
return response;
}
}
The model - Employee.java:
package com.ranjana.test.model;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.util.Date;
#Entity
#Table(name = "employee")
public class Employee {
//Employee Id
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
//Employee First Name
#Column(name = "first_name", nullable = false)
private String firstName;
//Employee Last Name
#Column(name = "last_name", nullable = false)
private String lastName;
//Employee Email Address
#Column(name = "email", nullable = true)
private String emailId;
//Employee Contact Number
#Column(name = "contact_number", nullable = true)
private String contactNumber;
//Creation Timestamp
#CreationTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "create_date_time", nullable = false)
private Date createDateTime;
//Update Timestamp
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "update_date_time", nullable = true)
private Date updateDateTime;
//Getters and Setters
#Override
public String toString(){
return "Employee{"
+ "id = " + id + '\''
+ "firstName" + firstName + '\''
+ "lastName" + lastName + '\''
+ "email" + emailId + '\''
+ "phone" + contactNumber + '\''
+ "createDateTime" + createDateTime + '\''
+ "updateDateTime" + updateDateTime + '\''
+ "}";
}
}
The console looks like following:
2019-08-05 13:27:18.327 INFO 9943 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-05 13:27:18.332 INFO 9943 --- [ restartedMain] com.ranjana.test.TestApplication : Started TestApplication in 3.678 seconds (JVM running for 9.357)
2019-08-05 13:27:18.340 DEBUG 9943 --- [ restartedMain] o.s.boot.devtools.restart.Restarter : Creating new Restarter for thread Thread[main,5,main]
2019-08-05 13:27:18.340 DEBUG 9943 --- [ restartedMain] o.s.boot.devtools.restart.Restarter : Immediately restarting application
2019-08-05 13:27:18.340 DEBUG 9943 --- [ restartedMain] o.s.boot.devtools.restart.Restarter : Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader#51171eea
2019-08-05 13:27:18.340 DEBUG 9943 --- [ restartedMain] o.s.boot.devtools.restart.Restarter : Starting application com.ranjana.test.TestApplication with URLs [file:/Users/ranjanasinha/ransinha/test/target/classes/]
2019-08-05 13:27:18.714 DEBUG 9943 --- [2)-10.36.30.147] o.s.jdbc.core.JdbcTemplate : Executing SQL query [SELECT 1]
2019-08-05 13:27:18.714 INFO 9943 --- [3)-10.36.30.147] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-08-05 13:27:18.714 INFO 9943 --- [3)-10.36.30.147] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-08-05 13:27:18.715 DEBUG 9943 --- [3)-10.36.30.147] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2019-08-05 13:27:18.724 DEBUG 9943 --- [3)-10.36.30.147] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-08-05 13:27:18.724 INFO 9943 --- [3)-10.36.30.147] o.s.web.servlet.DispatcherServlet : Completed initialization in 9 ms
2019-08-05 13:27:31.581 DEBUG 9943 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/employees", parameters={}
2019-08-05 13:27:31.587 DEBUG 9943 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:31.591 DEBUG 9943 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:31.591 DEBUG 9943 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2019-08-05 13:27:31.599 DEBUG 9943 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/errors/404.html", parameters={}
2019-08-05 13:27:31.601 DEBUG 9943 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:31.602 DEBUG 9943 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:31.602 DEBUG 9943 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
2019-08-05 13:27:35.827 DEBUG 9943 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/", parameters={}
2019-08-05 13:27:35.830 DEBUG 9943 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:35.830 DEBUG 9943 --- [nio-8080-exec-2] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:35.830 DEBUG 9943 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2019-08-05 13:27:35.831 DEBUG 9943 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/errors/404.html", parameters={}
2019-08-05 13:27:35.833 DEBUG 9943 --- [nio-8080-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:35.834 DEBUG 9943 --- [nio-8080-exec-2] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:35.834 DEBUG 9943 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
2019-08-05 13:27:38.056 DEBUG 9943 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : GET "/", parameters={}
2019-08-05 13:27:38.058 DEBUG 9943 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:38.058 DEBUG 9943 --- [nio-8080-exec-3] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:38.058 DEBUG 9943 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2019-08-05 13:27:38.059 DEBUG 9943 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/errors/404.html", parameters={}
2019-08-05 13:27:38.060 DEBUG 9943 --- [nio-8080-exec-3] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-08-05 13:27:38.062 DEBUG 9943 --- [nio-8080-exec-3] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-08-05 13:27:38.062 DEBUG 9943 --- [nio-8080-exec-3] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
I'm new to spring boot. Please help me figure out what I'm missing.
Also the table got created. And I checked with manually putting data in the table, still the 404 not found error is showing. Thanks in advance.
You should call like http://localhost:8080/api/v1/employees
Because you have created requestmapping("API/v1")
I have a Spring RestController which I am starting in locahost:8080. When I send a request to it (localhost:8080/people) I get a response in XML format. How can I make it JSON? When I send the request using Opera web browser I get XML format, but when I use the terminal( I use Mac) the answer to the request is Json. How can I make the answer in the browser be a JSON format.
Controller
package People;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.Resources;
import org.springframework.web.bind.annotation.*;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
#RestController
#RequestMapping("people")
public class PersonController {
private final PersonRepository repository;
PersonController(PersonRepository repository){
this.repository = repository;
}
#GetMapping
public Resources<Resource<Person>> all(){
List<Resource<Person>> persons = repository.findAll().stream()
.map(employee -> new Resource<>(employee,
linkTo(methodOn(PersonController.class).one(employee.getId())).withSelfRel(),
linkTo(methodOn(PersonController.class).all()).withRel("Persons")))
.collect(Collectors.toList());
return new Resources<>(persons,
linkTo(methodOn(PersonController.class).all()).withSelfRel());
}
#PostMapping("")
public Person newEmployee(#RequestBody Person newEmployee) {
return repository.save(newEmployee);
}
#GetMapping("{id}")
public Resource<Person> one(#PathVariable Long id) {
Person Person = repository.findById(id)
.orElseThrow(() -> new PersonNotFoundException(id));
return new Resource<>(Person,
linkTo(methodOn(PersonController.class).one(id)).withSelfRel(),
linkTo(methodOn(PersonController.class).all()).withRel("Persons"));
}
#PutMapping("{id}")
public Person replacePerson(#RequestBody Person newPerson,#PathVariable Long id){
return repository.findById(id)
.map(Person -> {
Person.setName(newPerson.getName());
Person.setLastName(newPerson.getLastName());
return repository.save(Person);
}).orElseGet(() -> {
newPerson.setId(id);
return repository.save(newPerson);
});
}
#DeleteMapping("{id}")
void deletePerson(#PathVariable Long id) {
repository.deleteById(id);
}
}
This is how the response looks like
<html>
<body>
<h1>Whitelabel Error Page</h1>
<p>
This application has no explicit mapping for /error, so you are seeing this as a fallback.
</p>
<div id="created">Mon Oct 29 22:41:51 MSK 2018</div>
<div>
There was an unexpected error (type=Internal Server Error, status=500).
</div>
<div>
Could not marshal [Resources { content: [Resource { content: Person(id=1, Name=Paul, LastName=Walker), links: [<http://localhost:8080/people/1>;rel="self", <http://localhost:8080/people>;rel="Persons"] }, Resource { content: Person(id=2, Name=Stan, LastName=Smith), links: [<http://localhost:8080/people/2>;rel="self", <http://localhost:8080/people>;rel="Persons"] }], links: [<http://localhost:8080/people>;rel="self"] }]: null; nested exception is javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.internal.SAXException2: unable to marshal type "org.springframework.hateoas.Resource" as an element because it is not known to this context.]
</div>
</body>
</html>
Console log
2018-10-29 23:57:26.747 INFO 21281 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-10-29 23:57:26.747 INFO 21281 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-10-29 23:57:26.767 INFO 21281 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 20 ms
2018-10-29 23:57:26.985 WARN 21281 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not marshal [Resource { content: Person(id=1, Name=Paul, LastName=Walker), links: [<http://localhost:8080/people/1>;rel="self", <http://localhost:8080/people>;rel="Persons"] }]: null; nested exception is javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: class People.Person nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class People.Person nor any of its super class is known to this context.]]
Please try to add producer to your get method as below
#GetMapping(path = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
I have been trying for hours now, can't seem to fix this. I have a simple Spring Boot Application.
These are the important files:
DemoApplication.java
package com.whatever.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.whatever.config.ConfigurationSettings;
#SpringBootApplication
#ComponentScan(basePackages = {"com.whatever.controllers", "com.whatever.config"})
public class DemoApplication{
public static void main(String[] args) {
Class[] sources = {DemoApplication.class, ConfigurationSettings.class};
SpringApplication.run(sources, args);
System.out.println("Hello WORLD!");
}
}
MainController.java
package com.whatever.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#RestController
#RequestMapping("/")
public class MainController{
#RequestMapping("/welcome")
public ModelAndView welcome(){
System.out.println("WELCOME!");
ModelAndView mAndView = new ModelAndView();
mAndView.setViewName("welcome");
return mAndView;
}
}
ConfigurationSettings.java
package com.whatever.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
public class ConfigurationSettings extends WebMvcConfigurationSupport{
#Bean
public InternalResourceViewResolver getResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".jsp");
return resolver;
}
}
My project structure:
--src
--main
--com.whatever.config
--com.whatever.controllers
--com.whatever.demo
--webapp
--WEB-INF
welcome.jsp
However, it can't load the welcome.jsp page and I keep on getting the /error page.
I can't seem to understand the problem.
Any help is appreciated.
P.S: I get the "Hello world!" and "WELCOME!" messages on the console. So, I know the control reaches there.
The StackTrace says:
2018-07-17 16:40:19.869 DEBUG 11004 --- [-auto-13-exec-9] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'welcome'
2018-07-17 16:40:19.869 DEBUG 11004 --- [-auto-13-exec-9] o.s.b.f.s.DefaultListableBeanFactory : Invoking afterPropertiesSet() on bean with name 'welcome'
2018-07-17 16:40:19.869 DEBUG 11004 --- [-auto-13-exec-9] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2018-07-17 16:40:19.869 DEBUG 11004 --- [-auto-13-exec-9] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2018-07-17 16:40:19.870 DEBUG 11004 --- [-auto-13-exec-9] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.JstlView: name 'welcome'; URL [/WEB-INF/welcome.jsp]] in DispatcherServlet with name 'dispatcherServlet'
2018-07-17 16:40:19.871 DEBUG 11004 --- [-auto-13-exec-9] o.s.web.servlet.view.JstlView : Forwarding to resource [/WEB-INF/welcome.jsp] in InternalResourceView 'welcome'
2018-07-17 16:40:19.872 DEBUG 11004 --- [-auto-13-exec-9] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-07-17 16:40:19.875 DEBUG 11004 --- [-auto-13-exec-9] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2018-07-17 16:40:19.875 DEBUG 11004 --- [-auto-13-exec-9] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Looking up handler method for path /error
2018-07-17 16:40:19.876 DEBUG 11004 --- [-auto-13-exec-9] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Did not find handler method for [/error]
You have add #RestController in your controller code,if you want to see the jsp page,you need to remove it and change to #Controller,since #RestController will add #ResponseBody to
you controller method automatically
package com.whatever.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.whatever.config.ConfigurationSettings;
#Controller("/")
public class MainController{
#RequestMapping("/welcome")
public ModelAndView welcome(){
System.out.println("WELCOME!");
ModelAndView mAndView = new ModelAndView();
mAndView.setViewName("welcome");
return mAndView;
}
}
You have used #RestController , rather use #Controller , It will solve your problem
Please try as below ,
package com.whatever.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.whatever.config.ConfigurationSettings;
#Controller
public class MainController{
#RequestMapping("/welcome")
public String welcome(){
System.out.println("WELCOME!");
return "welcome";
}
}