Controller are not working in Spring - spring

I unable to understand why my controller are not redirecting to my html. Anyone can help me please?
WebConfig.java
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "com.udemy.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix("");
return resolver;
}
}
HelloWorldController.java
#Controller
#RequestMapping("/example")
public class HelloWorldController {
public static final String EXAMPLE_VIEW = "example.html";
#GetMapping("/")
public String fileUploadForm(Model model) {
return "fileDownloadView";
}
#GetMapping("/helloworld")
public String helloWorld(){
return "helloworld";
}
// #RequestMapping(value="/exampleString", method=RequestMethod.GET)
#GetMapping("/exampleString")
public String exampleString(Model model){
model.addAttribute("name","John");
return EXAMPLE_VIEW;
}
// #RequestMapping(value="/exampleMAV", method=RequestMethod.GET)
#GetMapping("/exampleMAV")
public ModelAndView exampleMAV() {
ModelAndView mav= new ModelAndView(EXAMPLE_VIEW);
mav.addObject("name", "Mike");
return mav;
}
AppInitializer
public class MyWebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
My project structure is well done. So my html and jsps, are inside of the root WEB-INF/views. Also, the anotation #ComponentScan, are detecting the controller. So, its not a problem of root. Anyone can tell me, why im am not redirecting to the .html , please..
Error says:
ADVERTENCIA: No mapping found for HTTP request with URI [/spring-mvc-download-example/WEB-INF/views/example.html] in DispatcherServlet with name 'dispatcher'

In your controller class, above the
#RequestMapping("/example")
Insert:
#Controller
Gonna be:
#Controller
#RequestMapping("/example")

you have to annotate class HelloWorldController with #Controller or #RestController, only then it will be picked by #Componentscan annotation.

Related

Spring MVC - Dispatcher Servlet can't find any page

I do really simple demo web app using Spring mvc, Java class annotations and .jsp instead of .html.
When I start Tomcat on localhost - I always get 404 error. Where do I do mistake?
Config.class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.mylov.springsecurity.demo.config")
public class Config {
//Define bean for ViewResolver
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
Dispatcher Servlet Initialization
public class DispatcherServletInit extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Config.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
Controller
#Controller
public class DemoController {
#GetMapping({"", "/"})
public String showHome() {
return "home";
}
}
Project Structure:
You need to scan packages under demo package. So Spring will find your Controllers and Config classes. But now you point to only config. So package 'controller' won't be scan.
Try to do this:
#ComponentScan(basePackages = "com.mylov.springsecurity.demo")
Try providing the mapping as below so that all url's are mapped with the servlet:
public class DispatcherServletInit extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{Config.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/*"};
}
}
Also change the base packages to as below so that the controller class is also picked up for component scanning :
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.mylov.springsecurity.demo")
public class Config {
..........
}

ReloadableResourceBundleMessageSource: No message found under code 'Size.userForm.username'

Help me please. I use Spring MVC and Freemarker 2.3.27 in my web application and I can't catch bindingResult.errors on my FTL page. When I attempt to create wrong user with empty username, I have error: No message found under code 'Required' for locale 'ru'. But when i create user with short name (<6 characters) the message displays in my registration form. Why is this happening? Here is my code:
#Component
public class UserValidator implements Validator {
#Autowired
private UserService userService;
#Override
public boolean supports(Class<?> aClass) {
return User.class.equals(aClass);
}
#Override
public void validate(Object o, Errors errors) {
User user = (User) o;
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"username","Required");
if(user.getUsername().length()<6||user.getUsername().length()>32){
errors.rejectValue("username","Size.userForm.username");
}
if(userService.findByUsername(user.getUsername())!=null){
errors.rejectValue("username","Duplicate.userForm.username");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"password","Required");
if(user.getPassword().length()<6||user.getPassword().length()>32){
errors.rejectValue("password","Size.userForm.password");
}
if(!user.getConfirmPassword().equals(user.getPassword())){
errors.rejectValue("confirmPassword","Different.userForm.password");
}
}
}
#Controller
#RequestMapping("/")
public class UserController {
....
#GetMapping("/registration")
public String goToRegistrationForm(Model model){
model.addAttribute("userForm", new User());
return "registration";
}
#PostMapping("/registration")
public String registration(#ModelAttribute("userForm")User userForm, BindingResult bindingResult, Model model){
userValidator.validate(userForm, bindingResult);
if(bindingResult.hasErrors()){
return "registration";
}
userService.saveUser(userForm);
securityService.autologIn(userForm.getUsername(),userForm.getPassword());
return "redirect:/hello";
}
}
My WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "aquaplant")
public class WebConfig extends WebMvcConfigurerAdapter {
.....
#Bean(name = "messageSource")
public ReloadableResourceBundleMessageSource getMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new
ReloadableResourceBundleMessageSource();
messageSource.setBasenames("validation");
messageSource.setDefaultEncoding("UTF-8");
//messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
}
My project structure:
{main
resources
Resource Bundle 'validation'
validation_en.properties
validation_ru.properties}
The problem was in my validation_ru.properties. I saved this file in UTF format in Notepad, but Notepad adds an invisible Unicode character BOM to the beginning of the file.....

unable to inject bean in simple spring mvc application

I am trying a simple application in the spring mvc using annotations only. In my service class, I am unable to inject DAO class even though I have used relevant annotations.Please let me know what mistake I am doing. Below are my class definitions.
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringRootConfig.class };
//return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfiguration.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.emp.controller")
public class SpringWebConfiguration extends WebMvcConfigurerAdapter{
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.emp.svc,com.emp.dao")
public class SpringRootConfig {
}
package com.emp.svc;
import org.springframework.beans.factory.annotation.Autowired;
import com.emp.dao.LoginDAO;
public class LoginSvc {
#Autowired
private LoginDAO dao;
public boolean validateLogin(){
System.out.println("In the svc method");
return dao.validateLogin();
}
}
package com.emp.dao;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
#Repository
public class LoginDAO {
public boolean validateLogin(){
System.out.println("In the DAO method");
return true;
}
}
package com.emp.controller;
import org.springframework.stereotype.Controller;
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.servlet.ModelAndView;
import com.emp.forms.LoginForm;
import com.emp.svc.LoginSvc;
#Controller
public class LoginController {
#RequestMapping(value = {"/login"},method = RequestMethod.GET)
public ModelAndView launchLoginPage(){
ModelAndView model = new ModelAndView();
model.setViewName("login");
return model;
}
#RequestMapping(value = {"/welcome"},method = RequestMethod.GET)
public ModelAndView validateLogin(#ModelAttribute LoginForm form){
ModelAndView model = new ModelAndView();
LoginSvc svc = new LoginSvc();
if(svc.validateLogin()){
model.setViewName("welcome");
}
else
{
model.setViewName("login");
}
return model;
}
LoginSvc is called from controller. I am expecting that in LoginSvc, LoginDAO will be injected and hence the call to dao dao.validateLogin() will be successful. But what I am getting is Null pointer at dao.validateLogin(), indicating LoginDAO is not injected.
If you can let me know what I am missing, it will be great help.
Add #Service annotation in your LoginSvc class.
package com.emp.svc;
import org.springframework.beans.factory.annotation.Autowired;
import com.emp.dao.LoginDAO;
#Service
public class LoginSvc {
#Autowired
private LoginDAO dao;
public boolean validateLogin(){
System.out.println("In the svc method");
return dao.validateLogin();
}
}
And autowire LoginSvc inside your controller. As you are creating the object yourself invoking constructor of LoginSvc, spring will not provide you autowire candidate.
#Controller
public class LoginController {
#Autowired
private LoginSvc svc;
#RequestMapping(value = {"/login"},method = RequestMethod.GET)
public ModelAndView launchLoginPage(){
ModelAndView model = new ModelAndView();
model.setViewName("login");
return model;
}
#RequestMapping(value = {"/welcome"},method = RequestMethod.GET)
public ModelAndView validateLogin(#ModelAttribute LoginForm form){
ModelAndView model = new ModelAndView();
if(svc.validateLogin()) {
model.setViewName("welcome");
} else {
model.setViewName("login");
}
return model;
}
}

#Bean Controller not getting picked up by #EnableMVC

Most of my #Controllers are picked up through component scanning. However, a few, such as those I use with Spring Social are created as #Beans. I just migrated from mostly xml to JavaConfig only and upgraded to Spring 4.1.9.
However, the Controller endpoints that are created as #Beans are creating 404s.
Any ideas?
package nl.project.webapp.config;
#Order(1)
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{WebAppConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{ServletConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
[...]
}
package nl.project.webapp.config;
#Configuration
#ComponentScan(basePackages = {"nl.project.webapp"},excludeFilters={
#ComponentScan.Filter(type=FilterType.ANNOTATION,value=Controller.class),
#ComponentScan.Filter(type=FilterType.ANNOTATION,value=RestController.class)
})
#Import({AppConfig.class,JPAConfig.class})
#PropertySource("classpath:msa.properties")
public class WebAppConfig {
[...]
}
package nl.project.webapp.config;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"nl.project.webapp.controller"},includeFilters={
#ComponentScan.Filter(type=FilterType.ANNOTATION,value=Controller.class),
#ComponentScan.Filter(type=FilterType.ANNOTATION,value=RestController.class)
})
public class ServletConfig extends WebMvcConfigurerAdapter{
[...]
}
package nl.project.webapp.social.config;
#Configuration
public class SocialConfig{
#Bean
public MyConnectController connectController(MessageSource messages, UsorManager userMgr, PhotoManager photoMgr) {
MyConnectController connectController = new MyConnectController(connectionFactoryLocator, connectionRepository);
connectController.setConnectInterceptors(Arrays.asList(new ConnectInterceptor<?>[]{
new TwitterConnectInterceptor(userMgr, photoMgr, messages),
new FacebookConnectInterceptor(userMgr, photoMgr, messages),
new LinkedInConnectInterceptor(userMgr, photoMgr, messages),
new GoogleConnectInterceptor(userMgr, photoMgr, messages),
}));
return connectController;
}
#Bean
public MySignInController signinController(MessageSource messages, UsorManager userMgr, PhotoManager photoMgr){
MySignInController signinController = new MySignInController(connectionFactoryLocator, usersConnectionRepository, new SimpleSigninAdapter(userMgr));
signinController.setSignInInterceptors(Arrays.asList(new ProviderSignInInterceptor<?>[]{
new FacebookSigninInterceptor(userMgr, photoMgr, messages),
new LinkedInSigninInterceptor(userMgr, photoMgr),
new GoogleSigninInterceptor(userMgr, photoMgr)
}));
return signinController;
}
}
package nl.project.webapp.social.controller;
#Controller
#RequestMapping("/signin")
public class MySignInController extends ProviderSignInController {
public MySignInController(
ConnectionFactoryLocator connectionFactoryLocator,
UsersConnectionRepository usersConnectionRepository,
SignInAdapter signInAdapter) {
super(connectionFactoryLocator, usersConnectionRepository, signInAdapter);
this.connectionFactoryLocator = connectionFactoryLocator;
}
[...]
The problem was caused by SocialConfig being imported by the WebAppConfig in stead of the ServletConfig. Although the documentation suggests that any Controller bean available in the context will be picked up by using '#EnableWebMVC', it is not very clear that this does not apply to Controller beans loaded through the webapp context.

How can i separate jsp in differents folders with Spring?

This is my AppInitializer:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.project.app")
public class AppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer implements
WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(AppConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet(
"dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
And this is my AppConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.acfcm.app")
#Import({ SecurityConfig.class })
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolverForClasses() {
ResourceBundleViewResolver viewResolver = new ResourceBundleViewResolver();
viewResolver.setOrder(1);
viewResolver.setBasename("views");
return viewResolver;
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setOrder(2);
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
"/resources/");
}
}
What I want is how to change the AppConfig to put .jsp in differents foldes into the project because right now only can save it in /WEB-INF/views/ and there is a lot of .jsp!! I want to have two more folders to see my project like:
WEB-INF/views/moduleOne/
WEB-INF/views/moduleTwo/
...
Thanks!
I think your code is all fine; it will look for your JSPs starting in /WEB-INF/views/
Most people do like you say and break up JSP views under folders like /admin, /common, etc.
The way you do this is to specify the subfolder in the controller. For example, in your controller, you could return:
#RequestMapping(value = "/admin/index.htm", method = RequestMethod.GET)
public ModelAndView index(HttpServletRequest request,
HttpServletResponse response)
{
Map<String, Object> myModel = new HashMap<String, Object>();
myModel.put("someValues", new ArrayList());
ModelAndView mv = new ModelAndView("admin/index","model", myModel);
return mv;
}
Doing it like the above, you can put your JSP under
/WEB-INF/views/admin/index.jsp
Of course, your mappings (/admin) doesn't have to match the directory structure (/WEB-INF/views/admin) but we chose to make both match, to make it faster to find the code (if controller mapping matches the dir structure).
The important thing to remember is that whatever you put in that ModelAndView first param, Spring will prepend and append the values you defined in your code:
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
So, if you return ModelAndview("/pierre/was/here/something"), Spring will try to find the JSP at location: "/WEB-INF/views/pierre/was/here/something.jsp"
The common practice is to have the configuration as yours, and in the request handler controller methods, use the view names as moduleOne/view1, moduleTwo/view2 etc.

Resources