I am beginning to study AngularJS with Spring MVC and I wanted when I entered the system in the case http: // localhost: 8080 / he entered a home page that is called index.html, walked snooping on the Internet, most could not succeed in time to call the page.
This is my controller that just created to call the page as in the examples I've seen too.
package br.com.escconsultoria.standard.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
#RestController
#RequestMapping(value = "/")
public class IndexController {
#RequestMapping(method = RequestMethod.GET)
public ModelAndView getIndexPage() {
return new ModelAndView("/index");
}
}
Beauty of this fine examples simply doing: it returns index, worked over my could not for nothing there I saw talking about using Template: Thymeleaf only that I could not even now he does not think where's the page.
package br.com.escconsultoria.standard.configuration;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"br.com.escconsultoria.standard.configuration",
"br.com.escconsultoria.standard.controller",
"br.com.escconsultoria.standard.repository",
"br.com.escconsultoria.standard.service",
"br.com.escconsultoria.imobiliario.controller",
"br.com.escconsultoria.imobiliario.repository",
"br.com.escconsultoria.imobiliario.service"})
public class AppConfiguration extends WebMvcConfigurerAdapter{
/*#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/resources/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
return resolver;
}*/
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/templates/");
viewResolver.setSuffix(".html");
viewResolver.setCache(false);
return viewResolver;
}
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000l);
return multipartResolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app/**").addResourceLocations("/app/");
registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/templates/**").addResourceLocations("/templates/");
}
}
Does anyone have an idea how to implement it?
My index page is in the scr/main/resources/templates/index.html
Solution:
Good I managed to solve my problem and I am putting the solution here, first the first thing that kept me from work was the Controller noted with RestController and needed to be only Controller.
#Controller
#RequestMapping(value = "/")
public class IndexController {
#RequestMapping(method = RequestMethod.GET)
public String getIndexPage() {
return "index3";
}
}
And according to my App Configuration it looked like this.
package br.com.escconsultoria.standard.configuration;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"br.com.escconsultoria.standard.configuration",
"br.com.escconsultoria.standard.controller",
"br.com.escconsultoria.standard.repository",
"br.com.escconsultoria.standard.service",
"br.com.escconsultoria.imobiliario.controller",
"br.com.escconsultoria.imobiliario.repository",
"br.com.escconsultoria.imobiliario.service"})
public class AppConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/templates/");
viewResolver.setSuffix(".html");
viewResolver.setCache(false);
return viewResolver;
}
#Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000l);
return multipartResolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/app/**").addResourceLocations("/app/");
registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/templates/**").addResourceLocations("/templates/");
}
}
Then I had a little problem in the index that I was trying to do more was because they were generating in Pingendo and he did not close the tag in the case of the target, input and some other was not close at hand and it worked. My Test HTML below.
<html>
<head>
<meta charset="utf-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1"></meta>
<script type="text/javascript"
src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript"
src="http://netdna.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link
href="http://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css"
rel="stylesheet" type="text/css"></link>
<link
href="http://pingendo.github.io/pingendo-bootstrap/themes/default/bootstrap.css"
rel="stylesheet" type="text/css"></link>
</head>
<body>
<div class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#navbar-ex-collapse">
<span class="sr-only">Toggle navigation</span><span
class="icon-bar"></span><span class="icon-bar"></span><span
class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"><span>Brand</span></a>
</div>
<div class="collapse navbar-collapse" id="navbar-ex-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">Home</li>
<li>Contacts</li>
</ul>
</div>
</div>
</div>
<div class="section">
<div class="container">
<div class="row">
<div class="col-md-12">
<form class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-2">
<label for="inputEmail3" class="control-label">Email</label>
</div>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputEmail3"
placeholder="Email"></input>
</div>
</div>
<div class="form-group">
<div class="col-sm-2">
<label for="inputPassword3" class="control-label">Password</label>
</div>
<div class="col-sm-10">
<input type="password" class="form-control" id="inputPassword3"
placeholder="Password"></input>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox"> Remember me </input></label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
Related
I am currently working on the localization of my (second) Spring Boot project. However, I have come to a halt after several hours of struggling: I am unable to get a user-editable Session localization.
The problem appears to occur as soon as the user sends a GET request with the lang parameter. (travel down below to see the results I am getting)
Details
Spring Boot version:(3.0.0-M3)
Expected localized content
i18n/messages.properties is empty
i18n/messages_en_US.properties:
morning=good morning
afternoon=bye
i18n/messages_fr_FR.properties:
morning=salut
afternoon=a+
i18n/messages_ja_JP.properties:
morning=ohayou
afternoon=jane
Configuration
application.properties (section related to this issue):
spring.messages.always-use-message-format=true
spring.messages.basename=i18n.messages
spring.messages.fallback-to-system-locale=false
spring.messages.use-code-as-default-message=false
LocalizationConfiguration file:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
#Configuration
public class LocalizationConfiguration implements WebMvcConfigurer {
#Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
// localeResolver.setDefaultLocale(Locale.US);
return localeResolver;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
interceptorRegistry.addInterceptor(localeChangeInterceptor());
}
}
Display
Page Controller:
#GetMapping
#RequestMapping(value = "/international")
public String getInternationalView(Model model) {
return "international";
}
Template loaded (international.html):
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org" th:with="lang=${#locale.language}" th:lang="${lang}">
<head>
<script src="https://kit.fontawesome.com/2f4c03ee9b.js" crossorigin="anonymous"></script>
<script th:src="#{/webjars/jquery/3.0.0/jquery.min.js}"></script>
<script th:src="#{/webjars/popper.js/2.9.3/umd/popper.min.js}"></script>
<script th:src="#{/webjars/bootstrap/5.1.3/js/bootstrap.min.js}"></script>
<link th:rel="stylesheet" th:href="#{/webjars/bootstrap/5.1.3/css/bootstrap.min.css} "/>
<meta charset="UTF-8"/>
<title>Localization tests</title>
</head>
<body>
<p th:text="${#locale}"></p>
<p th:text="#{morning}"></p>
<p th:text="#{afternoon}"></p>
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
<i class="fa-solid fa-language fa-4x"></i>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" th:href="#{''(lang=en)}">English</a></li>
<li><a class="dropdown-item" th:href="#{''(lang=fr)}">Français</a></li>
<li><a class="dropdown-item" th:href="#{''(lang=jp)}">日本語</a></li>
</ul>
</div>
</body>
</html>
What is being displayed
Found result
As you can see in the above gif, the first display of the page shows the messages in the browser's language. However, as soon as an other language is selected the page breaks apart, with the exception of the #locale parameter.
Try it.
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
#Configuration
public class ApplicationConfig implements WebMvcConfigurer {
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:/i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
#Bean(name = "localeResolver")
public SessionLocaleResolver sessionLocaleResolver() {
SessionLocaleResolver localeResolver = new SessionLocaleResolver();
localeResolver.setDefaultLocale(new Locale("en"));
return localeResolver;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
I am having an issue where the custom login page doesn't appear to be working properly. It sends me to the login?error url, rather than the index page. When using the default Spring Security page, it works exactly as intended. I have placed the code below for the html page and the code dealing with the security and custom page in general.
I'm also using a postgresql database if that's somehow involved here.
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:tiles="http://www.thymeleaf.org">
<head>
<title>Index</title>
<link href="webjars/bootstrap/5.1.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container col-xl-10 col-xxl-8 px-4 py-5">
<div class="row align-items-center g-lg-5 py-5">
<div class="col-lg-7 text-center text-lg-start">
<h1 class="display-4 fw-bold lh-1 mb-3">Twitter-Clone</h1>
<p class="col-lg-10 fs-4">You must sign in before accessing the website. THYMELEAF</p>
</div>
<div class="col-md-10 mx-auto col-lg-5">
<form class="p-4 p-md-5 border rounded-3 bg-light" th:action="#{/login}" method="post" name="f">
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput username" placeholder="username">
<label for="floatingInput">User Name</label>
</div>
<div class="form-floating mb-3">
<input type="password" class="form-control" id="floatingPassword password" placeholder="Password" name="password">
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="w-100 btn btn-lg btn-info" type="submit">Login</button>
<hr class="my-4">
<small class="text-muted">If you don't have an account, sign up.</small>
</form>
</div>
</div>
</div>
<script src="webjars/jquery/3.6.0/jquery.min.js"></script>
<script src="webjars/bootstrap/5.1.0/js/bootstrap.min.js"></script>
</body>
</html>
SecurityConfiguration.java
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
#EnableWebSecurity
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Bean(name = "pwdEncoder")
public PasswordEncoder getPasswordEncoder() {
DelegatingPasswordEncoder delPasswordEncoder = (DelegatingPasswordEncoder) PasswordEncoderFactories
.createDelegatingPasswordEncoder();
BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
delPasswordEncoder.setDefaultPasswordEncoderForMatches(bcryptPasswordEncoder);
return delPasswordEncoder;
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/webjars/**", "/signup").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
}
You forgot to include the name attribute on your username input.
Been at this all day. I may be missing an annotation somewhere. I also cannot get this app to serve the index.html.
What am I missing here? The primary issue is not being able to get the form to submit anything to the backend. Is ModelAttribute correct?
Thanks in advance.
Controller:
package com.lms.application.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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;
import com.lms.application.entity.Course;
import com.lms.application.service.CourseService;
#RestController
#RequestMapping("/courses")
public class CourseController {
#Autowired
private CourseService service;
#RequestMapping(method=RequestMethod.GET)
public ResponseEntity<Object> getCourses(){
return new ResponseEntity<Object>(service.getCourses(), HttpStatus.OK);
}
#RequestMapping(value="/submit", method=RequestMethod.POST)
public ResponseEntity<Object> createCourse(#ModelAttribute("course") Course course){
return new ResponseEntity<Object>(service.createCourse(course), HttpStatus.CREATED);
}
Form
<div class="container">
<form method="post" th:object="${course}" th:action="#{/courses/submit}">
<div class="row mb-3">
<label for="title" class="col-sm-2 col-form-label">Course Title</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="course.title" th:field="${course.title}"></input>
</div>
</div>
<div class="row mb-3">
<label for="credit" class="col-sm-2 col-form-label">Course
Credits</label>
<div class="col-sm-10">
<input type="number" class="form-control" id="course.credits" th:field="${course.credits}"></input>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
Before demanding an Object from Thymeleaf you have to create and pass one there. Thymeleaf won't create an object for you.
You need to pass the object via Model to the Controller like so:
#ModelAttribute("course")
public Course course() {
return new Course();
}
You need to make sure Course object has getters, setters and default constructor for Thymeleaf to be able to work with it correctly.
package com.project.agro.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.project.agro.model.Role;
import com.project.agro.model.User;
import com.project.agro.repos.UserRepository;
import java.util.HashSet;
import java.util.Set;
#Service
public class UserDetailsServiceImpl implements UserDetailsService{
#Autowired
private UserRepository userRepository;
#Override
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) {
User user = userRepository.findByUsername(username);
if (user == null) throw new UsernameNotFoundException(username);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
}
package com.project.agro.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.project.agro.model.Role;
import com.project.agro.model.User;
import com.project.agro.repos.UserRepository;
import java.util.HashSet;
import java.util.Set;
#Service
public class UserDetailsServiceImpl implements UserDetailsService{
#Autowired
private UserRepository userRepository;
#Override
#Transactional(readOnly = true)
public UserDetails loadUserByUsername(String username) {
User user = userRepository.findByUsername(username);
if (user == null) throw new UsernameNotFoundException(username);
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()){
grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
}
}
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link href="${contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
<link href="${contextPath}/resources/css/style.css" rel="stylesheet">
<link href="${contextPath}/resources/css/fixed.css" rel="stylesheet">
</head>
<body>
<%# include file="common/navbar.jsp"%>
<div class="container-fluid">
<div class="row">
<div class="col-3">
<div class="side-nav">
<nav>
<ul>
<li> <span>Title</span></li>
<li> <span>Crops</span></li>
<li class="active"> <span>Fertilizer</span></li>
<li> <span>Agro News</span></li>
</ul>
</nav>
</div>
</div>
<div class="col-9">
<form class="form-horizontal" action="/admin/crop/addcrop"
method="post" enctype="multipart/form-data" style="margin-top:5rem;" >
<fieldset>
<legend class="center-block">
New crop Information
</legend>
<!-- title -->
<div class="form-group" style="display:flex;">
<label class="col-sm-2 control-label" for="title">Crop Name</label>
<div class="col-sm-8">
<input type="text" name="cName" class="form-control" id="cName"
required="required" placeholder="Title" />
</div>
</div>
<!-- author -->
<div class="form-group" style="display:flex;">
<label class="col-md-2 control-label" for="cScientificName">
Scientific Name</label>
<div class="col-md-8">
<input type="text" name="cScientificName" class="form-control"
id="cScientificName" required="required"
placeholder="Scientific Name" />
</div>
</div>
<!-- description -->
<div class="form-group" style="display:flex;">
<label class="col-md-2 control-label" for="description">Description</label>
<div class="col-md-8">
<textarea name="description" rows="5" class="form-control"
id="description" placeholder="Description"></textarea>
</div>
</div>
<!-- upload image -->
<div class="form-group" style="display:flex;">
<div class="col-md-2">
<label for="cImage">Upload crop image</label>
</div>
<div class="col-md-8">
<input id="cImage" type="file" name="cImage" value="cImage" />
</div>
</div>
<!-- description -->
<div class="form-group" style="display:flex;">
<label class="col-md-2 control-label" for="description">Associated
Disease</label>
<div class="col-md-8">
<input type="text" name="associatedDisease" class="form-control"
id="description"
placeholder="Associated Disease" />
</div>
</div>
<div class="form-group" style="display:flex;">
<div class="col-md-2"></div>
<div class="col-md-8">
<button type="submit" class="btn btn-success">Add Book</button>
<a class="btn btn-danger" href="">Cancel</a>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
<script src="${contextPath}/resources/js/bootstrap.min.js" ></script>
<script src="${contextPath}/resources/js/jquery-3.3.1.min.js" ></script>
</body>
</html>
-
package com.project.agro;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasAuthority("ADMIN")
.antMatchers("/resources/**", "/registration","/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll().defaultSuccessUrl("/welcome")
.and()
.logout()
.permitAll();
}
#Bean
public AuthenticationManager customAuthenticationManager() throws Exception {
return authenticationManager();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
}
package com.project.agro.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import com.project.agro.model.Crop;
import com.project.agro.service.CropService;
#Controller
public class CropController {
#Autowired
private CropService cropService;
#RequestMapping(value="/admin/crop/addcrop" ,method = RequestMethod.GET)
public String addcrop(Model model) {
Crop crop = new Crop();
model.addAttribute("crop", crop);
return "addcrop";
}
#RequestMapping(value="/admin/crop/addcrop" , method = RequestMethod.POST)
public String addcroppost(#ModelAttribute(value="crop") Crop crop ,HttpServletRequest request){
cropService.save(crop);
MultipartFile cImage=crop.getcImage();
try {
byte[] bytes = cImage.getBytes();
String name = crop.getCropID() + ".png";
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(new File("src/main/webapp/image/crop/" + name)));
stream.write(bytes);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
return "redirect:/cropList";
}
#RequestMapping("/cropList")
public String cropList(Model model) {
/*List<Book> bookList = bookService.findAll();*/
return "cropList";
}
}
I am trying to build an web application using Spring Boot and Spring Security.I am submitting a form with POST method as an admin to add some details into database but everytime I hit that submit button it shows the error page.I have added all the dependencies .The registration and login page works fine What am I suppose to do here?
I am facing some problem in spring -security whenever i clicked on
the submit it redirect to the below url and i got 404
HTTP Status 404 - for url
localhost:8080/TestingSecurity/login
I guess there is some issue in registering springsecurity filter
code for ConfigurationDefaultXml.java
package cms.config;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"cms.controller"})
#Import(value = { SecurityConfiguration.class })
public class ConfigurationDefaultXml extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver jspviewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public ViewResolver contentNegotiatingViewResolver(
ContentNegotiationManager manager) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(manager);
// Define all possible view resolvers
List<ViewResolver> resolvers = new ArrayList<ViewResolver>();
resolvers.add(jspviewResolver());
resolver.setViewResolvers(resolvers);
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/design/");
}
}
Code of SecurityConfiguration.java
package cms.config;
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("abc123").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("root123").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba1").password("root123").roles("ADMIN","DBA");//dba have two roles.
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.and().formLogin().loginPage("/logincustom")
.usernameParameter("ssoId").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
}
SecurityWebApplicationInitializer.java
package cms.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer{
}
code of SpringMvcInitializer.java
package cms.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpringMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { ConfigurationDefaultXml.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
coding of form button is given below
<form action="${loginUrl}" method="post" class="form-horizontal">
<c:if test="${param.error != null}">
<div class="alert alert-danger">
<p>Invalid username and password.</p>
</div>
</c:if>
<c:if test="${param.logout != null}">
<div class="alert alert-success">
<p>You have been logged out successfully.</p>
</div>
</c:if>
<div class="input-group input-sm">
<label class="input-group-addon" for="username"><i class="fa fa-user"></i></label>
<input type="text" class="form-control" id="username" name="ssoId" placeholder="Enter Username" required>
</div>
<div class="input-group input-sm">
<label class="input-group-addon" for="password"><i class="fa fa-lock"></i></label>
<input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" required>
</div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<div class="form-actions">
<input type="submit"
class="btn btn-block btn-primary btn-default" value="Log in">
</div>
</form>
Even though it will not be used as the login post URL, you need to add a loginProcessingUrl for your custom login:
.formLogin().loginPage("/logincustom").loginProcessingUrl("/doLogin")
.usernameParameter("ssoId").passwordParameter("password")