Spring MVC - run application in absolute path - java

I have a demo application of Spring MVC - I just follow udemy course for it.
I have created the first controller and view. All is working fine, however I have one doubt about.
The pom file of application contains:
<groupId>eu.smartgroup</groupId>
<artifactId>spring-demo-mvc</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
So when I run application on tomcat server it starts, but it is available with url: http://localhost:8080/spring_demo_mvc_war
Is there possibility to configure application so it will be available in the root path: http://localhost:8080/ (without project name after slash)?
Edit:
Here is full application.yml
server:
servlet:
contextPath: /
HelloController.java
package eu.test.springdemo.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
#Controller
#RequestMapping("/")
public class HelloController {
#GetMapping("/")
public String showPage() {
return "main-menu";
}
}
DemoAppConfig.java
package eu.test.springdemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="eu.test.springdemo")
public class DemoAppConfig implements WebMvcConfigurer {
// define a bean for ViewResolver
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}

Add this line to your application.properties:
server.servlet.contextPath=/
I've tried it on my project and it works.
Write back is it working on your.

Check if you have a controller class that is annotated as such:
#Controller
#RequestMapping("spring_demo_mvc_war")
or
#RestController
#RequestMapping("spring_demo_mvc_war")
If that is the case, then make the string empty or remove the #RequestMapping (you can also change it to whatever else you like).

Related

Spring boot , i18n error, wrong implementation of LocaleResolver is choosen

I am developing a spring boot based application that supports internationalisation
My env:
Jdk11
Spring boot 2.7.0
Spring Security
Here is my web mvc conf
WebMvcConf.java
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;
import java.util.Locale;
#Configuration
public class WebMvcConf implements WebMvcConfigurer {
public static final Locale idnLocale = Locale.forLanguageTag("id-ID");
#Bean
public LocaleResolver defaultLocaleResolver(){
var resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(idnLocale);
return resolver;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
var interceptor = new LocaleChangeInterceptor();
interceptor.setIgnoreInvalidLocale(false);
interceptor.setParamName("lang");
return interceptor;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
And here is my security config:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.header.HeaderWriterFilter;
import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper;
#Configuration
#EnableWebSecurity
public class SecurityConf{
#Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.cors()//enable cors
.and()
.csrf().disable()//disable csrf
.sessionManagement(session->session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))//stateless session (Rest)
.authorizeHttpRequests(authz->authz
.antMatchers(HttpMethod.GET,"/").permitAll()
.antMatchers(HttpMethod.POST,"/users/login","users/register","users/forgot-password").permitAll()
.antMatchers(HttpMethod.PATCH,"/users/password").permitAll()
.anyRequest().authenticated());//authorize any request except ignored endpoint above
return httpSecurity.build();
}
}
Here is the structure of the message properties:
Here is my application.yml content:
Here is the content of messages_en.properties:
rest.welcome.ok=Welcome to ABC Backend Service, have fun!!!
rest.users.login.ok=Successfully Logged in
#Error Message
rest.500.err=Internal Server Error
rest.422.err=Constraint Violation Error
rest.400.err=Invalid request body
rest.required-req-body-missing.err=Required request body is missing
Here is content of messages.properties:
rest.welcome.ok=Selamat Datang di Service ABC, selamat bersenang-senang!!!
rest.users.login.ok=Login sukses
#Error message
rest.500.err=Kesalahan Internal di sistem
rest.422.err=Error pelanggaran constraint
rest.400.err=Kesalahan pada request body
rest.required-req-body-missing.err=Request body (payload) yang dibutuhkan tidak ditemukan
Here is my test to test the message source:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.MessageSource;
import java.util.Locale;
#SpringBootTest
public class MessageSourceTest {
#Autowired
private MessageSource messageSource;
#BeforeEach
void init(){
}
#Test
public void message_provided_should_correctly_localized(){
String msgEnglish = messageSource.getMessage("rest.500.err",null, new Locale("en"));
String msgIndo = messageSource.getMessage("rest.500.err",null,Locale.forLanguageTag("id-ID"));
Assertions.assertEquals("Internal Server Error",msgEnglish);
Assertions.assertEquals("Kesalahan Internal di sistem",msgIndo);
}
}
And the test is pass:
But when I try to hit a mvc rest controller and add query parameter lang=en , I always got an error response saying Cannot change HTTP accept header - use a different locale resolution strategy
So I debug the LocaleChangeInterceptor and found that spring boot provide a wrong implementation of the LocaleResolver, they provide AcceptHeaderResolver, which what I want is the SessionLocaleResolver as I state it in my WebMvcConf class. See following picture:
Anyone knows what is wrong and how to fix it?any response will be appreciated

upload file springboot Required request part 'file' is not present

I want to add an upload function to my spring boot application;
this is my upload Rest Controller
package org.sid.web;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.sid.entities.FileInfo;
#RestController
public class UploadController {
#Autowired
ServletContext context;
#RequestMapping(value = "/fileupload/file", headers = ("content-type=multipart/*"), method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<FileInfo> upload(#RequestParam("file") MultipartFile inputFile) {
FileInfo fileInfo = new FileInfo();
HttpHeaders headers = new HttpHeaders();
if (!inputFile.isEmpty()) {
try {
String originalFilename = inputFile.getOriginalFilename();
File destinationFile = new File(
context.getRealPath("C:/Users/kamel/workspace/credit_app/uploaded") + File.separator + originalFilename);
inputFile.transferTo(destinationFile);
fileInfo.setFileName(destinationFile.getPath());
fileInfo.setFileSize(inputFile.getSize());
headers.add("File Uploaded Successfully - ", originalFilename);
return new ResponseEntity<FileInfo>(fileInfo, headers, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
} else {
return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
}
}
}
but when testing this in postman with inserting http://localhost:8082/fileupload/file and adding a file to the body
i got this error: "exception": org.springframework.web.multipart.support.MissingServletRequestPartException",
"message": "Required request part 'file' is not present,
This is how your request in Postman should look like:
My sample code:
application.properties
#max file and request size
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=11MB
Main Application Class:
Application.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Rest controller class:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
#Controller
#RequestMapping("/fileupload")
public class MyRestController {
#RequestMapping(value = "/file", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String myService(#RequestParam("file") MultipartFile file,
#RequestParam("id") String id) throws Exception {
if (!file.isEmpty()) {
//your logic
}
return "some json";
}
}
pom.xml
//...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
....
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
//...
In your method you have specified like this
#RequestParam("file"). Hence it is expecting the key to be file. It is quite evident in the exception message. Use this name in the Key field in Postman when you upload file.
More information here integration test case and file upload
I also had similar issue and was getting the error request part file not present.
But I later realized that I have this code in my application which was causing problem:
#Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new
CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000000);
return multipartResolver;
}
I removed this and it started working for both RequestPart and RequestParam.
See the related issue below:
https://forum.predix.io/questions/22163/multipartfile-parameter-is-not-present-error.html
Except for other posted answers, the problem might be realated to missing multipart support for the servlet handling the request (spring's DispatcherServlet in case of Spring's app).
This can be fixed by adding multipart support to dispatcher servlet in web.xml declaration or during initialization (in case of annotation-based config)
a) web-xml based config
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>20971520</max-request-size>
<file-size-threshold>5242880</file-size-threshold>
</multipart-config>
</servlet>
</web-app>
b) for annotation-based configuration this would be following:
public class AppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) {
final AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
final ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
File uploadDirectory = new File(System.getProperty("java.io.tmpdir"));
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), 100000, 100000 * 2, 100000 / 2);
registration.setMultipartConfig(multipartConfigElement);
} }
Then we need to provide multipart resolver which can resolve files sent as multipart-request. For annotation config this can be done in following way:
#Configuration
public class MyConfig {
#Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}
For xml-based spring configuration you need to add this bean to the context via tag declaration declaration:
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
Alternatively to spring's standard multipart resolver you can use implementation from commons. This way however extra dependency is required:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>
I had similar issue with error Could not resolve parameter [0] in public org.springframework.http.ResponseEntity... Required request part 'file' is not present and tried many things but one change resolved this issue.
Had to update
// old
#RequestParam("file") MultipartFile inputFile
// new
#RequestParam(value = "file") MultipartFile inputFile
In my case, i have multi module project as;
core > api > admin
Admin and api are parent of core module.
Core/ImageController:
#RequestMapping(value = "/upload/image", method = RequestMethod.POST)
public ResponseEntity uploadBanner(#RequestParam(value = "file", required =
false) MultipartFile bannerFile){...}
AdminApplicationInitializer:
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AdminApplicationInitializer.class);
}
#Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//100MB
resolver.setMaxUploadSize(100 * (long) 1024 * 1024);
return resolver;
}
#Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize(DataSize.ofMegabytes(200L));
factory.setMaxRequestSize(DataSize.ofMegabytes(200L));
return factory.createMultipartConfig();
}
When i tried to upload file from api module with core service "/upload/image".
I had get an error : "Required request part 'file' is not present".
Cause of ApiInitializer had not configuration like AdminInitializer.
The Solution : i added multipartResolver() and multipartConfigElement() method to ApiApplicationInitializer.Then it worked.

No mapping found for HTTP request with URI [/proj/] in DispatcherServlet with name 'dispatcher'

I am following "Spring in action - Craig Walls" book and encountered the below error message. Lot of the issues were mentioned in relation to web.xml. I am using Java config and not web.xml.
Controller in spitter.web package:
package spitter.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value="/", method = RequestMethod.GET)
public String home(){
return "home";
}
}
Dispatcher servlet configuration in spittr.config package:
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
#Override
protected Class<?>[] getRootConfigClasses() {
//return new Class<?>[] {RootConfig.Class};
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
//return new Class<?>[] {WebConfig.Class};
return null;
}
}
Rootconfig in same package:
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages={"spitter"}, excludeFilters={#Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)})
public class RootConfig {
}
WebConfig:
package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("spitter.web")
public class WebConfig extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WebContent/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
I am using Maven to resolving dependencies and Tomcat 9 within eclipse to run.
Sep 17, 2016 4:46:48 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5007 ms Sep 17, 2016 4:46:49 PM
org.springframework.web.servlet.PageNotFound noHandlerFound WARNING:
No mapping found for HTTP request with URI [/SpringMVC/] in
DispatcherServlet with name 'dispatcher'
My view home.jsp is in WebContent/WEB-INF/views/home.jsp.
Thanks for your help. I made the below changes and it is working now.
I move the web.config to the same package as my constructor. Then created the war file and deployed in Apache Tomcat. Now i am able to access the website.

SpringMVC & Spring in Action: can't redirect to home.jsp in chapter 5

I'm learning SpringMVC and maven these days with the book Spring in Action but i have a question now. The default request to "/" should be mapped to "home.jsp" but not. You can also see the same question described in the book forum.
https://forums.manning.com/posts/list/38046.page
Here are the codes:
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected String[] getServletMappings(){
return new String[]{ "/" };
}
#Override
protected Class<?>[] getRootConfigClasses(){
return new Class<?>[]{ RootConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses(){
return new Class<?>[]{ WebConfig.class };
}
}
package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("spittr.web")
public class WebConfig extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages={"spitter"}, excludeFilters={
#Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)
})
public class RootConfig {
}
package spittr.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value="/", method=RequestMethod.GET)
public String home(){
return "home";
}
}
When i run this on tomcat 7.0, it should show home.jsp. However it still shows index.jsp.
-------------------- update -------------------------
The following test class indicates the controller class is right and this controller can response to the request "/" with home.jsp. So, where is wrong?
package spittr.web;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
public class HomeControllerTest {
#Test
public void testHomePage() throws Exception{
HomeController controller = new HomeController();
MockMvc mockMvc = standaloneSetup(controller).build();
mockMvc.perform(get("/")).andExpect(view().name("home"));
}
}
update or add in your web.xml
<welcome-file-list>home.jsp</welcome-file-list>
If you do not have web.xml you can generate by
Dynamic Web Project –> RightClick –> Java EE Tools –> Generate
Deployment Descriptor Stub.
Also you can do JSP redirect using JSTL libraries in index.jsp to redirect to home.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:redirect url="/home.jsp"/>
seems to be a path problem.
First check your path mapping in web.xml file for exact url-pattern for which you are redirecting to dispatcher servlet.Assuming that you have home.jsp views created under
/WEB-INF/views/
folder.
I had the same issue while working on Eclipse, Tomcat 9.0 on my Mac. I have spend hours to see (this small code) that where I was wrong.
However, I was able to make it run on Windows machine with Eclipse and Tomcat 8.5 and 9.0 .
I have the code hosted on GitHub at https://github.com/shortduck/ManningChapter5_SpringMVC
This is a Maven project and not Gradle. Also see the HomeController has the value as value = "/home", this is working as well as '/' will work too. If you have having value as '/' make sure index.jsp or any other "home" page is not on the root.
My next target to find out why is this code not working on Mac.

Spring MVC 4 configuration not finding my controllers

Hi I am new to Spring MVC 4 I am trying to do the java configuration setup but it seems Spring is not finding my Controller it is running fine no errors on startup I can even explicitly call a jsp but if I try to call my controller it does nothing
e.g.
localhost:8080/apollo/hello.jsp <-- this renders fine if I put my JSP in the webapp directory
What I want is to call my login.jsp using my controller
My project structure is
com
+apollo
-WebAppInitializer.java
-WebConfig.java
src
+main
+webapp
-**hello.jsp**
+WEB-INF
+view
-**login.jsp**
here is my Configuration
package com.apollo;
import java.util.Locale;
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.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.apollo")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/*registry.addResourceHandler("/pdfs/**").addResourceLocations("/WEB-INF/pdf/");
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/");*/
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
Here is my Initializer Class
package com.apollo;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.html");
}
private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
return context;
}
}
here is my Controller
package com.apollo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class LoginController {
#RequestMapping(value="/login")
public String greeting (Model model){
System.out.println("controller???");
model.addAttribute("greeting" , "Hello World");
return "login";
}
}
The basePackages mean the package contains the controller
Here is the problem:
#ComponentScan(basePackages = "com.apollo")
You should change to
#ComponentScan(basePackages = "com.apollo.controller")
If you put controller to modules, you should scan like this
#ComponentScan(basePackages = "com.apollo.**.controller")

Categories

Resources