Postgresql 在thymeleaf页上,源不能为空
我有一个异常(不能为空),当我填写表单的电子邮件字段时会抛出该异常。它发生在我提交表格时。 我加入控制器、模型、服务和dto类 控制器类为:Postgresql 在thymeleaf页上,源不能为空,postgresql,spring-boot,hibernate,spring-data-jpa,thymeleaf,Postgresql,Spring Boot,Hibernate,Spring Data Jpa,Thymeleaf,我有一个异常(不能为空),当我填写表单的电子邮件字段时会抛出该异常。它发生在我提交表格时。 我加入控制器、模型、服务和dto类 控制器类为: @Controller public class AdminController { @Autowired BusReservationService busReservationService; @Autowired UserService userService; @GetMapping(value = {
@Controller
public class AdminController {
@Autowired
BusReservationService busReservationService;
@Autowired
UserService userService;
@GetMapping(value = { "/", "/login" })
public ModelAndView login(@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView modelAndView= new ModelAndView("login");
if (error !=null) {
modelAndView.addObject("error", "Invalid Username and password!");
}
if (logout !=null) {
modelAndView.addObject("message", "You're been logout out successfully.");
}
return modelAndView;
}
@GetMapping(value = "/signup")
public ModelAndView signup() {
ModelAndView modelAndView = new ModelAndView("signup");
modelAndView.addObject("adminSignupFormData", new AdminSignupFormCommand());
return modelAndView;
}
@PostMapping(value = "/signup")
public ModelAndView createNewAdminUser(
@Valid @ModelAttribute("adminSignupFormData") AdminSignupFormCommand adminSignupFormCommand,
BindingResult result) {
ModelAndView modelAndView = new ModelAndView("signup");
if (result.hasErrors()) {
return modelAndView;
} else {
try {
UserDto newUser = registerAdmin(adminSignupFormCommand);
} catch (Exception e) {
result.rejectValue("email", "error.adminSignupFormCommand", e.getMessage());
return modelAndView;
}
}
return new ModelAndView("login");
}
private UserDto registerAdmin(@Valid AdminSignupFormCommand adminSignupFormCommand) {
UserDto userDto = new UserDto()
.setEmail(adminSignupFormCommand.getEmail())
.setFirstName(adminSignupFormCommand.getFirstName())
.setLastName(adminSignupFormCommand.getLastName())
.setPassword(adminSignupFormCommand.getPassword())
.setMobileNumber(adminSignupFormCommand.getMobileNumber())
.setAdmin(true);
UserDto admiDto = userService.signup(userDto);
AgencyDto agencyDto = new AgencyDto().setDetails(adminSignupFormCommand.getAgencyDetails())
.setName(adminSignupFormCommand.getAgencyName()).setUserOwner(admiDto);
busReservationService.addAgency(agencyDto);
return admiDto;
}
@GetMapping(value = {"/logout"})
private String logout() {
SecurityContextHolder.getContext().setAuthentication(null);
return "redirect:login";
}
@GetMapping(value = "/home")
public String home() {
return "redirect:dashboard";
}
}
@Component
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
private RoleRepository roleRepository;
@Autowired
private ModelMapper modelMapper;
@Override
@Transactional
public UserDto signup(UserDto userDto) {
Role userRole;
User userOptional = userRepository.findByEmail(userDto.getEmail());
if (userOptional == null) {
if (userDto.isAdmin()) {
userRole = roleRepository.findByRole(UserRole.ADMIN);
} else {
userRole = roleRepository.findByRole(UserRole.PASSENGER);
}
userOptional= new User().setEmail(userDto.getEmail()).setFirstName(userDto.getFirstName())
.setLastName(userDto.getLastName()).setMobileNumber(userDto.getMobileNumber())
.setPassword(userDto.getPassword()).setRoles(new HashSet<>(Arrays.asList(userRole)));
return UserMapper.userDto(userRepository.save(userOptional));
}
throw exception(EntityType.USER, ExceptionType.DUPLICATE_ENTITY, userDto.getEmail());
}
@Override
@Transactional
public UserDto findUserByEmail(String email) {
Optional<User> usOptional = Optional.ofNullable(userRepository.findByEmail(email));
if (usOptional.isPresent()) {
return modelMapper.map(usOptional.get(), UserDto.class);
}
throw exception(EntityType.USER, ExceptionType.ENTITY_NOT_FOUND, email);
}
@Override
@Transactional
public UserDto updteProfile(UserDto userDto) {
Optional<User> uOptional = Optional.ofNullable(userRepository.findByEmail(userDto.getEmail()));
if (uOptional.isPresent()) {
User user = uOptional.get().setEmail(userDto.getEmail()).setFirstName(userDto.getFirstName())
.setLastName(userDto.getLastName()).setMobileNumber(userDto.getMobileNumber());
return UserMapper.userDto(userRepository.save(user));
}
throw exception(EntityType.USER, ExceptionType.ENTITY_NOT_FOUND, userDto.getEmail());
}
@Override
@Transactional
public UserDto changePassword(UserDto userDto, String newPassword) {
Optional<User> userChangepassword = Optional.ofNullable(userRepository.findByEmail(userDto.getEmail()));
if (userChangepassword.isPresent()) {
User password = userChangepassword.get().setPassword(passwordEncoder.encode(newPassword));
return UserMapper.userDto(userRepository.save(password));
}
throw exception(EntityType.USER, ExceptionType.ENTITY_NOT_FOUND, userDto.getEmail());
}
/**
* @param entityType
* @param exceptionType
* @param arg
* @return
*/
private RuntimeException exception(EntityType entityType, ExceptionType exceptionType, String... arg) {
return BSRExecption.throwException(entityType, exceptionType, arg);
}
@Override
@Transactional
public List<UserDto> getAllUsers() {
return StreamSupport.stream(userRepository.findAll().spliterator(), false).distinct()
.map(users -> (modelMapper.map(users, UserDto.class))).collect(Collectors.toCollection(ArrayList::new));
}
}
@Configuration("CustomSecurityConfig")
网页为:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Sign Up</title>
<!-- Favicon icon -->
<link rel="icon" type="image/png" href="favicon.png">
<!-- Font Icon -->
<link rel="stylesheet"
href="/auth/fonts/material-icon/css/material-design-iconic-font.min.css">
<!-- Main css -->
<link rel="stylesheet" href="/auth/css/style.css">
</head>
<body>
<div class="main">
<!-- Sign up form -->
<section class="signup">
<div class="container">
<div class="signup-content">
<div class="signup-form">
<h2 class="form-title">Sign up</h2>
<form action="#" method="POST" class="register-form"
id="register-form" th:action="@{/signup}"
th:object="${adminSignupFormData}">
<div class="form-group">
<label for="firstName"><i
class="zmdi zmdi-account material-icons-name"></i></label> <input
type="text" th:field="*{firstName}" name="firstName"
id="firstName" placeholder="First Name" /> <small
class="text-danger" th:if="${#fields.hasErrors('firstName')}"
th:errors="*{firstName}"></small>
</div>
<div class="form-group">
<label for="lastName"><i class="zmdi zmdi-account-o"></i></label>
<input type="text" th:field="*{lastName}" name="lastName"
id="lastname" placeholder="Last Name" /> <small
class="text-danger" th:if="${#fields.hasErrors('lastName')}"
th:errors="*{lastName}"></small>
</div>
<div class="form-group">
<label for="email"><i class="zmdi zmdi-email"></i></label> <input
type="email" th:field="*{email}" name="email" id="email"
placeholder="Your Email" /> <small class="text-danger"
th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email
Error</small>
</div>
<div class="form-group">
<label for="password"><i class="zmdi zmdi-lock"></i></label> <input
type="password" th:field="*{password}" name="password"
id="password" placeholder="Password" /> <small
class="text-danger" th:if="${#fields.hasErrors('password')}"
th:errors="*{password}"></small>
</div>
<div class="form-group">
<label for="agencyName"><i class="zmdi zmdi-layers"></i></label>
<input type="text" th:field="*{agencyName}" name="agencyName"
id="agencyName" placeholder="Agency Name" /> <small
class="text-danger" th:if="${#fields.hasErrors('agencyName')}"
th:errors="*{agencyName}"></small>
</div>
<div class="form-group">
<label for="agencyDetails"><i
class="zmdi zmdi-assignment"></i></label> <input type="text"
th:field="*{agencyDetails}" name="agencyDetails"
id="agencyDetails" placeholder="Agency Details" /> <small
class="text-danger"
th:if="${#fields.hasErrors('agencyDetails')}"
th:errors="*{agencyDetails}"></small>
</div>
<div class="form-group">
<label for="mobileNumber"><i class="zmdi zmdi-phone"></i></label>
<input type="text" th:field="*{mobileNumber}"
name="mobileNumber" id="mobileNumber"
placeholder="Contact Number" /> <small class="text-danger"
th:if="${#fields.hasErrors('mobileNumber')}"
th:errors="*{mobileNumber}"></small>
</div>
<div class="form-group">
<input type="checkbox" name="agree-term" id="agree-term"
class="agree-term" /> <label for="agree-term"
class="label-agree-term"><span><span></span></span>I
agree all statements in <a href="#" class="term-service">Terms
of service</a></label>
</div>
<div class="form-group form-button">
<input type="submit" name="signup" id="signup"
class="form-submit" value="Register" />
</div>
</form>
</div>
<div class="signup-image">
<figure>
<img src="/auth/images/signup-image.jpg" alt="sing up image">
</figure>
<a href="/login" class="signup-image-link">I am already member</a>
</div>
</div>
</div>
</section>
</div>
<!-- JS -->
<script src="/auth/vendor/jquery/jquery.min.js"></script>
</body>
</html>
@启用Web安全性
@EnableGlobalMethodSecurity(Prespenabled=true,securedEnabled=true,proxyTargetClass=true)
公共类MultiHttpSecurityConfig{
@Configuration
@Order(1)
public static class ApiWebSecurityConfigAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
private CustomuserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder builderAuth) throws Exception {
builderAuth.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder);
}
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/api/*").authorizeRequests().antMatchers("/api/v1/user/signup")
.permitAll().anyRequest().authenticated().and().exceptionHandling()
.authenticationEntryPoint((req, rsq, e) -> rsq.sendError(HttpServletResponse.SC_UNAUTHORIZED)).and()
.addFilter(new ApiJWTAuthenticationFilter(authenticationManager()))
.addFilter(new ApiJWTAuthorizationFilter(authenticationManager())).sessionManagement()
// This diseables session creation on Spring Security
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public UserDetailsService usDetailsService() {
return new CustomuserDetailsService();
}
@Bean(name = "pwdEncoder") public PasswordEncoder getPasswordEncoder() {
DelegatingPasswordEncoder delPasswordEncoder = (DelegatingPasswordEncoder)
PasswordEncoderFactories .createDelegatingPasswordEncoder();
BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
delPasswordEncoder.setDefaultPasswordEncoderForMatches(bcryptPasswordEncoder)
; return delPasswordEncoder; }
}
/*
* @Bean public CorsConfigurationSource corsConfigurationSource() {
*
* final UrlBasedCorsConfigurationSource source = new
* UrlBasedCorsConfigurationSource();
*
* CorsConfiguration corsConfiguration = new
* CorsConfiguration().applyPermitDefaultValues();
* source.registerCorsConfiguration("/**", corsConfiguration); return source; }
*/
@Configuration
@Order(2)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private BCryptPasswordEncoder bCryptPasswordEncoder;
private CustomAuthentionSuccesshandler customAuthentionSuccesshandler;
private CustomuserDetailsService customuserDetailsService;
@Autowired
public FormLoginWebSecurityConfigurerAdapter(BCryptPasswordEncoder bCryptPasswordEncoder,
CustomAuthentionSuccesshandler customAuthentionSuccesshandler,
CustomuserDetailsService customuserDetailsService) {
super();
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.customAuthentionSuccesshandler = customAuthentionSuccesshandler;
this.customuserDetailsService = customuserDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(customuserDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and().csrf().disable().authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/signup").permitAll().antMatchers("/dashbord/**").hasAuthority("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/login").permitAll().failureUrl("/login?error=true")
.usernameParameter("email").passwordParameter("password")
.successHandler(customAuthentionSuccesshandler).and().logout().permitAll()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessHandler(new CustomLogoutSuccessHandler()).deleteCookies("JSESSIONID")
.logoutSuccessUrl("/").and().exceptionHandling();
}
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/resources/**", "/static/**", "/js/**", "/images/**",
"/resources/static/**", "/css/**", "/im/**", "/fonts/**", "/images/**", "/scss/**", "/vendor/**",
"/favicon.ico", "/auth/**", "/favicon.png", "/v2/api-docs", "/configuration/ui",
"/configuration/security", "/webjars/**", "/swagger-resources/**", "/actuator", "/swagger-ui/**",
"/swagger-ui/index.html", "/swagger-ui/");
}
}
}您能添加完整的stacktrace吗?您好,我添加了stacktrace。这不是stacktrace,而是日志。:)在任何情况下,我在你发布的内容中都没有看到任何异常。您好,非常感谢您的帮助,事实上,当我填写表单的所有必填字段并将其提交到postgres数据库时,我在日志中没有发现任何异常。这就是我在这个问题上寻求帮助的原因。我有一个返回码200,如果我查看数据库,没有插入任何数据。是否在类型为“org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder”的
无符合条件的bean后抛出表单错误,异常已修复(类路径中缺少spring安全核心)?
@Configuration("CustomSecurityConfig")
@Configuration
@Order(1)
public static class ApiWebSecurityConfigAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
private CustomuserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder builderAuth) throws Exception {
builderAuth.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder);
}
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/api/*").authorizeRequests().antMatchers("/api/v1/user/signup")
.permitAll().anyRequest().authenticated().and().exceptionHandling()
.authenticationEntryPoint((req, rsq, e) -> rsq.sendError(HttpServletResponse.SC_UNAUTHORIZED)).and()
.addFilter(new ApiJWTAuthenticationFilter(authenticationManager()))
.addFilter(new ApiJWTAuthorizationFilter(authenticationManager())).sessionManagement()
// This diseables session creation on Spring Security
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public UserDetailsService usDetailsService() {
return new CustomuserDetailsService();
}
@Bean(name = "pwdEncoder") public PasswordEncoder getPasswordEncoder() {
DelegatingPasswordEncoder delPasswordEncoder = (DelegatingPasswordEncoder)
PasswordEncoderFactories .createDelegatingPasswordEncoder();
BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
delPasswordEncoder.setDefaultPasswordEncoderForMatches(bcryptPasswordEncoder)
; return delPasswordEncoder; }
}
/*
* @Bean public CorsConfigurationSource corsConfigurationSource() {
*
* final UrlBasedCorsConfigurationSource source = new
* UrlBasedCorsConfigurationSource();
*
* CorsConfiguration corsConfiguration = new
* CorsConfiguration().applyPermitDefaultValues();
* source.registerCorsConfiguration("/**", corsConfiguration); return source; }
*/
@Configuration
@Order(2)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
private BCryptPasswordEncoder bCryptPasswordEncoder;
private CustomAuthentionSuccesshandler customAuthentionSuccesshandler;
private CustomuserDetailsService customuserDetailsService;
@Autowired
public FormLoginWebSecurityConfigurerAdapter(BCryptPasswordEncoder bCryptPasswordEncoder,
CustomAuthentionSuccesshandler customAuthentionSuccesshandler,
CustomuserDetailsService customuserDetailsService) {
super();
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.customAuthentionSuccesshandler = customAuthentionSuccesshandler;
this.customuserDetailsService = customuserDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(customuserDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors().and().csrf().disable().authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/signup").permitAll().antMatchers("/dashbord/**").hasAuthority("ADMIN").anyRequest()
.authenticated().and().formLogin().loginPage("/login").permitAll().failureUrl("/login?error=true")
.usernameParameter("email").passwordParameter("password")
.successHandler(customAuthentionSuccesshandler).and().logout().permitAll()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessHandler(new CustomLogoutSuccessHandler()).deleteCookies("JSESSIONID")
.logoutSuccessUrl("/").and().exceptionHandling();
}
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity.ignoring().antMatchers("/resources/**", "/static/**", "/js/**", "/images/**",
"/resources/static/**", "/css/**", "/im/**", "/fonts/**", "/images/**", "/scss/**", "/vendor/**",
"/favicon.ico", "/auth/**", "/favicon.png", "/v2/api-docs", "/configuration/ui",
"/configuration/security", "/webjars/**", "/swagger-resources/**", "/actuator", "/swagger-ui/**",
"/swagger-ui/index.html", "/swagger-ui/");
}
}