I am setup a sample Code base using Spring MVC in Eclipse and JBoss 6.2.
But I get '404' with http://localhost:8080/rest/simple/main
Jboss log as below:
2015-07-29 11:51:27,356 ERROR [controller.simpleController] (http-/0.0.0.0:8080-1) get request
2015-07-29 11:51:27,391 WARN [org.springframework.web.servlet.PageNotFound] (http-/0.0.0.0:8080-1) No mapping found for HTTP request with URI [/rest/WEB-INF/views/main.jsp] in DispatcherServlet with name 'dispatcher'
Directory :
>rest-server-simple
> -src
> -main
-java
-config
-InitConfig.java
-ServletConfig.java
-controller
-simpleController.java
> -webapp
> -WEB-INF
-jboss-web.xml
>views
-main.jsp
InitConfig:
public class InitConfig implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(ServletConfig.class);
ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher",new DispatcherServlet(ctx));
registration.setLoadOnStartup(1);
registration.addMapping("/*"); }}
ServletConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages ="controller")
public class ServletConfig {
#Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
jboss-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<context-root>/rest</context-root>
</jboss-web>
simpleController:
#Controller
#RequestMapping(value = "/simple")
public class simpleController {
private static final Logger logger = LoggerFactory.getLogger(simpleController.class);
#RequestMapping(value = "/main", method = RequestMethod.GET)
public String hello(){
logger.error("get request");
return "main";
}
}
registration.addMapping("/*");
Change it to
registration.addMapping("/");
There is a difference between /* and / .
/* indicates that every request will be handled by DispatcherServlet, in this case retrieval of a jsp or anything like .../abc.xyz etc will also be forwarded to Dispatcher, so when controller requests for a view it actually looks for RequestMapping mapped for /WEB-INF/views/main.jsp but
/ tells container that only those requests that do not have pathinfo i.e /rest/simple/main will be handled by DispatcherServlet.
UPDATE#1
Hmm.. What I have found that jboss AS 7 doesn't like overriding default servlet i.e. / without web.xml and hence you are still getting 404 and not even getting anything on the logger, Reason being simple is that Dispatcher is never mapped to any url. If you want to check that just add following after addMapping("/*");
System.out.println("registration.getMappings() = " + registration.getMappings());
It works fine with Tomcat >= 7.0.15 or WildFly have checked on both.
To make it work on JBoss7 there are few options:
1. Change DispatcherServlet mapping from / to *.htm or something except DefaultServlet Mapping.
2. Switch your Configuration to web.xml. You will have to initialize DispatcherServlet there and pass Annotated class as `contextConfigLocation. Check here for REF
Related
I am trying to authenticate and authorize using role base in spring using hibernate in java configuration. When I run the server then it gives me error sarying no mapping found for the URI in servlet.
public class ShoppingInitializerWeb implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(ShoppingServletConfig.class);
ctx.setServletContext(container);
ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/*");
}
}
ShoppingServletConfig.java
#Configuration
#EnableTransactionManagement
#ComponentScan(basePackages = "com.project.shopping")
public class ShoppingServletConfig extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/ui/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
WebConfigStatic.java
#EnableWebMvc
#Configuration
#ComponentScan(basePackages="com.project.shopping")
public class WebConfigStatic extends WebMvcConfigurerAdapter{
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/js/**").addResourceLocations("/ui/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/ui/css/");
registry.addResourceHandler("/*.html/**").addResourceLocations("/ui/view/");
}
}
This is my controller:
#Controller
#RequestMapping("/")
public class UserController {
#RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("user", getPrincipal());
return "welcome";
}
And I have got welcome.jsp in webapp/WEB-INF/ui/view
Here is the error in console:
WARNING: No mapping found for HTTP request with URI [/Shoping/home] in DispatcherServlet with name 'dispatcher'
I looked up all the related errors and tried solving but couldn't get it solved.
I have faced a same project in my Spring project and I tried every possible way but no solution didn't work for that project however, finally I got a solution.
After adding maven dependencies into project deployment assembly, my project worked perfectly. So, you can try with below procedures, it should work if your code is perfect.
Right click on Project then select Properties > Deployment Assembly >
then click add button > Java Build path entries > Select Maven
dependencies > click Finish button.
then update maven project, and then mvn clean install ... then run.
I hope, it would work.
This has been a quite common problem here in stackOverflow, but none of the topics of the same problem solves mine.
We have a template configuration that uses xml config, but now we're trying to move away from that and start using Java config.
So I have a new project using Java config and Spring Boot. We're also using JSP and Tiles 3.
Problem is: it fails to render our admin login page.
Here is the code:
Main config class:
#SpringBootApplication
#EnableScheduling
#Import(OnAdminBeans.class)
public class AppConfig extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AppConfig.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AppConfig.class);
}
}
The AppConfig.class is is the main package. Through the #ComponentScan that #SpringBootApplication brings, it scans the other configurations that are on mainpackage.config, so it imports the view config class:
#Configuration
#EnableWebMvc
public class ViewConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/adm/static/**").addResourceLocations("/adm/static/");
}
// #Override
// public void addViewControllers(ViewControllerRegistry registry) {
// registry.addViewController("/adm/login").setViewName("login-template-tiles");
// }
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(viewResolver());
registry.viewResolver(jspViewResolver());
registry.viewResolver(tilesViewResolver());
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setCookieName("locale");
localeResolver.setCookieMaxAge(30);
localeResolver.setDefaultLocale(new Locale("pt", "BR"));
return localeResolver;
}
#Bean
public MultipleViewResolver viewResolver() {
Map<String, ViewResolver> viewsResolvers = new HashMap<String, ViewResolver>();
viewsResolvers.put(MultipleViewResolver.ViewType.JSP.getKey(), jspViewResolver());
viewsResolvers.put(MultipleViewResolver.ViewType.TILES.getKey(), tilesViewResolver());
MultipleViewResolver viewResolver = new MultipleViewResolver();
viewResolver.setViewsResolvers(viewsResolvers);
viewResolver.setOrder(1);
return viewResolver;
}
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
viewResolver.setOrder(2);
return viewResolver;
}
#Bean
public UrlBasedViewResolver tilesViewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(TilesView.class);
viewResolver.setOrder(3);
return viewResolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions("/WEB-INF/tile-defs/tiles-definitions.xml");
return configurer;
}
}
The LoginController.class is defined as:
#Controller
#RequestMapping(value = "/adm")
public class LoginController {
#RequestMapping(value = "/login")
public ModelAndView login() {
return new ModelAndView("login-template-tiles");
}
}
And in tiles-definitions.xml I have the following definition for login-template-tiles:
<definition name="login-template-tiles" template="/WEB-INF/jsp/adm/templates/login-template.jsp">
<put-attribute name="admin-title" value="Admin" />
<put-attribute name="content" value="/WEB-INF/jsp/adm/templates/sections/login/index.jsp" />
</definition>
Note that both files exist.
Given all that the LoginController.login() does get called when i try to access /adm/login. But it fails to find the proper jsp file, aparently.
It returns a 404. With TRACE enabled, I get the following log:
DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#2118c09a] in DispatcherServlet with name 'dispatcherServlet'
Looking up handler method for path /WEB-INF/jsp/adm/templates/login-template.jsp
Did not find handler method for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping#2c148974] in DispatcherServlet with name 'dispatcherServlet'
No handler mapping found for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#784c3547] in DispatcherServlet with name 'dispatcherServlet'
No handler mapping found for [/WEB-INF/jsp/adm/templates/login-template.jsp]
Testing handler map [org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping#533e0604] in DispatcherServlet with name 'dispatcherServlet'
Testing handler map [org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping#cfd1b4e] in DispatcherServlet with name 'dispatcherServlet'
No mapping found for HTTP request with URI [/WEB-INF/jsp/adm/templates/login-template.jsp] in DispatcherServlet with name 'dispatcherServlet'
Any suggestions are appreciated!
EDIT:
Ok. By debugging, I found out that it has something to do with the embedded Tomcat. Other than that, I have no clue what is going on.
EDIT 2:
Found that the problem is in org.springframework.web.servlet.DispatcherServlet#getHandler. It simply doesn't find a HandlerMapping for that request. Do I have to register one?
OK! Found the problem.
This link helped me: https://samerabdelkafi.wordpress.com/2014/08/03/spring-mvc-full-java-based-config/
More specifically this configuration:
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
By setting a default handler, I would no longer get a white page but instead the JSP code as html, which clearly tells me that the JSP was being found but not rendered.
So the answer was on this page: JSP file not rendering in Spring Boot web application
I was missing the tomcat-embed-jasper artifact.
Add below dependency to your pom.xml
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
The tips here helped me when I got stuck with a similar problem. I fixed it after adding this fragment on my configuration
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
I'm using Spring Framework 4.1.5, Spring Security 4.0.0.RC2, Spring Webflow 2.4.0.RELEASE and Tomcat 8.0.15.
I followed the example in the webflow documentation, but I can't get the file in my form bean.
The form
<form:form action="${flowExecutionUrl}" method="post" commandName="fileForm" enctype="multipart/form-data">
<form:input type="file" value="" path="multipartFileUpload"/>
<button type="submit" name="_eventId_forward"><spring:message code="signup.forward"/></button>
<sec:csrfInput/>
</form:form>
The form bean
public class FileForm implements Serializable {
private static final long serialVersionUID = 1L;
private transient MultipartFile multipartFileUpload;
public MultipartFile getMultipartFileUpload() {
return multipartFileUpload;
}
public void setMultipartFileUpload(final MultipartFile multipartFileUpload) {
this.multipartFileUpload = multipartFileUpload;
}
}
The flow
<view-state id="companyLogo" view="signup/company-logo" model="fileForm">
<var name="fileForm" class="it.openex.pmcommonw.form.FileForm"/>
<transition on="back" to="chooseProfile" bind="false" validate="false"/>
<transition on="forward" to="companyInfo">
<evaluate expression="userCommonBean.uploadImage(fileForm)"/>
</transition>
</view-state>
The backing object
#Component
public class UserCommonBean {
public static void uploadImage(final FileForm fileForm) throws IOException, ServletException {
fileForm.getMultipartFileUpload(); // always null!!!
}
}
The multipartResolver
#Bean
public CommonsMultipartResolver filterMultipartResolver() {
final CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(10 * 1024 * 1024);
multipartResolver.setMaxInMemorySize(1048576);
multipartResolver.setDefaultEncoding("UTF-8");
return multipartResolver;
}
webflow configuration
#Configuration
public class WebFlowConfig extends AbstractFlowConfiguration {
#Autowired
TilesViewResolver viewResolver;
#Bean
public FlowDefinitionRegistry flowRegistry() {
return getFlowDefinitionRegistryBuilder()
.setFlowBuilderServices(flowBuilderServices())
.setBasePath("/WEB-INF/flows/")
.addFlowLocation("signup.xml", UrlMap.SIGNUP_WEBFLOW)
.addFlowLocation("user-edit.xml", UrlMap.PROFILE_EDIT_WEBFLOW)
.build();
}
#Bean
public FlowExecutor flowExecutor() {
return getFlowExecutorBuilder(flowRegistry()).build();
}
#Bean
public FlowHandlerAdapter flowHandlerAdapter() {
final FlowHandlerAdapter flowHandlerAdapter = new FlowHandlerAdapter();
flowHandlerAdapter.setFlowExecutor(flowExecutor());
return flowHandlerAdapter;
}
#Bean
public FlowHandlerMapping flowHandlerMapping() {
final FlowHandlerMapping flowHandlerMapping = new FlowHandlerMapping();
flowHandlerMapping.setFlowRegistry(flowRegistry());
// this has to be less than -1
flowHandlerMapping.setOrder(-2);
return flowHandlerMapping;
}
#Bean
public MvcViewFactoryCreator mvcViewFactoryCreator() {
final MvcViewFactoryCreator mvcViewFactoryCreator = new MvcViewFactoryCreator();
final List<ViewResolver> viewResolvers = Collections.singletonList(viewResolver);
mvcViewFactoryCreator.setViewResolvers(viewResolvers);
return mvcViewFactoryCreator;
}
#Bean
public FlowBuilderServices flowBuilderServices() {
return getFlowBuilderServicesBuilder().setViewFactoryCreator(mvcViewFactoryCreator())
.setValidator(localValidatorFactoryBean()).build();
}
#Bean
public LocalValidatorFactoryBean localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
}
Inside Tomcat's context.xml I already added allowCasualMultipartParsing="true"
Debugging the application I can see the file data inside the request, and I can get it if I try to post the form to a normal controller.
I tried also to remove Spring Security but it still didn't work inside Spring WebFlow.
In the requestParameters object there are only 3 objects:
execution
_eventid_forward
_csrf
There are some relevant rows in the logs
DEBUG 2015-03-13 18:03:15,053: org.springframework.web.multipart.support.MultipartFilter - Using MultipartResolver 'filterMultipartResolver' for MultipartFilter
DEBUG 2015-03-13 18:03:15,053: org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'filterMultipartResolver'
DEBUG 2015-03-13 18:03:15,053: org.springframework.web.multipart.support.MultipartFilter - Resolving multipart request [/registrazione] with MultipartFilter
DEBUG 2015-03-13 18:03:15,060: org.springframework.web.multipart.commons.CommonsMultipartResolver - Found multipart file [multipartFileUpload] of size 469217 bytes with original filename [PoliziaMunicipale.png], stored in memory
....
DEBUG 2015-03-13 18:03:15,072: org.springframework.binding.mapping.impl.DefaultMapper - Beginning mapping between source [org.springframework.webflow.core.collection.LocalParameterMap] and target [it.openex.pmcommonw.form.FileForm]
DEBUG 2015-03-13 18:03:15,072: org.springframework.binding.mapping.impl.DefaultMapping - Adding mapping result [TargetAccessError#34bc31ea mapping = parameter:'execution' -> execution, code = 'propertyNotFound', error = true, errorCause = org.springframework.binding.expression.PropertyNotFoundException: Property not found, originalValue = 'e1s2', mappedValue = [null]]
DEBUG 2015-03-13 18:03:15,072: org.springframework.binding.mapping.impl.DefaultMapper - Completing mapping between source [org.springframework.webflow.core.collection.LocalParameterMap] and target [it.openex.pmcommonw.form.FileForm]; total mappings = 1; total errors = 1
The multipartFileUpload property is not binded in the FileForm bean.
I'm not sure if it's useful, but inside org.springframework.webflow.context.servlet.HttpServletRequestParameterMap at line 52
if (request instanceof MultipartHttpServletRequest) {
// ... process multipart data
}
it fails the check because the request is an instance of org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper
Update 1
I can confirm that multipartRequest.getFile("file") also works.
I can't enable the org.springframework.web.multipart.support.MultipartFilter filter though.
If it's enabled the multipartRequest is an instance of StandardMultipartHttpServletRequest containing a Servlet3SecurityContextHolderAwareRequestWrapper, wrapping a Servlet3SaveToSessionRequestWrapper, finally containing an unreachable DefaultMultipartHttpServletRequest with the multipartFile I need, but I can't get it.
Disabling it I'm able to get it because multipartRequest became an instance of DefaultMultipartHttpServletRequest, but there's no file validation and the maxUploadSize limit of CommonsMultipartResolver is not respected.
Plus if Tomcat launches an exception because the file is too big for Tomcat's maxPostSize limit, the exception is caught by my CustomAccessDeniedHandler because its type is org.springframework.security.access.AccessDeniedException, and the error message is Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'..
Looking at the request object I can see the original Tomcat exception org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException. It seems like there's nothing to handle it properly, but, as I said, if I enable the MultipartFilter I can't get the file.
We ran into the same problems, since we use Spring Security 4.xx in our web application.
The Problem is that a org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper isn't instance of org.springframework.web.multipart.MultipartHttpServletRequest but it contains one. A cast to won't work and ClassCastException will occur.
Thats the reason why
if (request instanceof MultipartHttpServletRequest) {
// ... process multipart data
}
never can be true.
The idea was to create a org.springframework.web.multipart.support.StandardMultipartHttpServletRequest from the native HttpServletRequest and it works.
In our WebApp we use Pojo Actions indicated in Spring Webflow documentation Section 6.5.1. Invoking a POJO action.
Our Workaround:
PojoAction.java
public String fileUpload(RequestContext requestContext) {
final ServletExternalContext context = (ServletExternalContext) requestContext.getExternalContext();
final MultipartHttpServletRequest multipartRequest = new StandardMultipartHttpServletRequest((HttpServletRequest)context.getNativeRequest());
final File file = multipartRequest.getFile("file");
fileUploadHandler.processFile(file); //do something with the submitted file
}
In flow.xml we have an action state like this:
<action-state id="upload-action">
<evaluate expression="pojoAction.uploadFile(flowRequestContext)"/>
<transition to="show"/>
</action-state>
In this case the binding to a model is not needed.
I hope it helps!
According to Update 1
In web.xml the CSRF-Protection Filter must declared before SpringSecurityFilterChain.
In our application the web.xml looks like this
<filter>
<filter-name>csrfFilter</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>csrfFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
I wrote a simple controller for uploading files:
#RestEndpoint
public class ImageController {
#Autowired
GridFsTemplate mTemplate;
#RequestMapping(value = "images", method = RequestMethod.POST)
public #ResponseBody String testPhoto(#RequestParam String name, #RequestParam String directory, #RequestParam MultipartFile file) throws IOException {
if(!file.isEmpty()){
final byte[] bytes = file.getBytes();
InputStream inputStream = new ByteArrayInputStream(bytes);
mTemplate.store(inputStream, "name");
return "uploaded photo";
}
return "failed";
}
}
#RestEndpoint annotation is:
#Target({ ElementType.TYPE })
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Controller
public #interface RestEndpoint
{
String value() default "";
}
My ContextCOnfiguration class is:
#Configuration
#EnableWebMvc
#ComponentScan(
basePackages = "com.questter.site",
useDefaultFilters = false,
includeFilters =
#ComponentScan.Filter({RestEndpoint.class, RestEndpointAdvice.class})
)
public class RestServletContextConfiguration extends WebMvcConfigurerAdapter {
#Bean
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
return resolver;
}
...
}
--- UPDATED ---
web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>Spring Application</display-name>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>true</scripting-invalid>
<include-prelude>/WEB-INF/jsp/base.jspf</include-prelude>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
<default-content-type>text/html</default-content-type>
</jsp-property-group>
</jsp-config>
<!--<context-param>-->
<!--<param-name>spring.profiles.active</param-name>-->
<!--<param-value>development</param-value>-->
<!--</context-param>-->
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<distributable />
</web-app>
---- UPDATED ----
public class Bootstrap implements WebApplicationInitializer
{
#Override
public void onStartup(ServletContext container) throws ServletException
{
container.getServletRegistration("default").addMapping("/resource/*");
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfiguration.class);
container.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext =
new AnnotationConfigWebApplicationContext();
webContext.register(WebServletContextConfiguration.class);
ServletRegistration.Dynamic dispatcher = container.addServlet(
"springWebDispatcher", new DispatcherServlet(webContext)
);
dispatcher.setLoadOnStartup(1);
dispatcher.setMultipartConfig(new MultipartConfigElement(
null, 20_971_520L, 41_943_040L, 512_000
));
dispatcher.addMapping("/");
AnnotationConfigWebApplicationContext restContext =
new AnnotationConfigWebApplicationContext();
restContext.register(RestServletContextConfiguration.class);
DispatcherServlet servlet = new DispatcherServlet(restContext);
servlet.setDispatchOptionsRequest(true);
dispatcher = container.addServlet(
"springRestDispatcher", servlet
);
dispatcher.setLoadOnStartup(2);
dispatcher.addMapping("/rest/*");
rootContext.refresh();
DbBootstrap dbBootstrap = rootContext.getBean(DbBootstrap.class);
dbBootstrap.init();
}
}
When perfoming a post request (using postman) i'm getting:
HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException:Expected MultipartHttpServletRequest: is a MultipartResolver configured
I've looked over some similar questions over stackoverflow but none of the answers helped
me.
Spring version is: 4.0.4
Any help will be greatly appreciated (with a thumbs up of course).
Thanks
I don't know why they did this, but the MultipartResolver bean in the context needs to be named multipartResolver. Rename your #Bean method to
public CommonsMultipartResolver multipartResolver(){ // lowercase 'P'
Or give it the name explicitly
#Bean(name = "multipartResolver")
public CommonsMultipartResolver canBeCalledAnything(){
allowCasualMultipartParsing="true"
on context tag inside context.xml, it's work for me
It is straight forward from the exception that no multi-part configuration is found. Though you have provided multipartResolver bean.
The problem is that while specifying the MultipartFilter before the Spring Security filter, It tries to get the multipartResolver bean but can't find it. Because it expect the bean name/id as filterMultipartResolver instead of multipartResolver.
Do yourself a favor. Please change the bean configuration like following -
#Bean
public CommonsMultipartResolver filterMultipartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
or
#Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
The answer by R. Ali Ashik worked for me.
Following is the relevant part of pom.xml of the project that I am working on:
<properties>
<springframework.version>5.0.2.RELEASE</springframework.version>
<springsecurity.version>5.0.0.RELEASE</springsecurity.version>
<hibernate.version>5.2.17.Final</hibernate.version>
<mysql.connector.version>8.0.11</mysql.connector.version>
Since, I have a custom login page with persistent authentication setup, I also needed to have the following:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}
}
But the actual clincher was this as pointed out by R. Ali Ashik:
#Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
CommonsMultipartResolver resolver = new
CommonsMultipartResolver();
return resolver;
}
The relevant reference material in the context is this:
Class MultipartFilter
And the relevant text is as follows:
Looks up the MultipartResolver in Spring's root web application context. Supports a "multipartResolverBeanName" filter init-param in web.xml; the default bean name is "filterMultipartResolver". Looks up the MultipartResolver on each request, to avoid initialization order issues (when using ContextLoaderServlet, the root application context will get initialized after this filter).
I am creating a spring security application using Spring 4.0.2.RELEASE and Spring Security 3.2.3.RELEASE using entirely java configuration, no xml. The configuration for security seems to be working correctly and is generating the login page correctly and authenticating. However I get 404 errors for all of my pages.
I have controllers and jsp pages set up for each page. When I run the application, I see log messages showing that the controllers were mapped
Mapped "{[/ || /welcome] ... onto ... WelcomeController.welcome()
However, when I try to hit one of those URLs, I get the login page, then on sucessfull login get a 404 and I see nothing in the log.
Below you will find my controller, my 2 configuration classes, and my 2 initializes.
WelcomeController.java
#Controller
public class WelcomeController {
#RequestMapping(value = {"/", "/welcome"})
public ModelAndView welcome() {
System.out.println("welcome invoked");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("welcome");
return modelAndView;
}
}
Below You will find my configuration files
WebConfig.java
#EnableWebMvc
#Configuration
#ComponentScan({ "com.myproject.pagegen.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver
= new InternalResourceViewResolver();
resolver .setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
SecurityConfig.java
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").hasRole("USER")
.antMatchers("/welcome").hasRole("USER")
.anyRequest().anonymous()
.and().formLogin();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
WebAppInitializer.java
public class WebAppInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { WebConfig.class, SecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
SecurityWebAppInitializer.java
public class SecurityWebAppInitializer
extends AbstractSecurityWebApplicationInitializer { }
UPDATE:
I did find something interesting. If I changed my servletMapping to /* instead of /, I would then get a log message showing that the controller was invoked, but it would have no mapping for the jsp. It seems like it is trying to map the jsp url to the controllers.
welcome invoked
org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/ROOT/WEB-INF/jsp/welcome.jsp] in DispatcherServlet with name 'dispatcher'
I had a similar issue when running a project using Eclipse and Tomcat. Try running the application using Spring Tool Suite and use the VMware vFabric tc server.
I also got it to work in Eclipse and Tomcat by manually updating the version of Tomcat installed. Try the latest version 7.0.54 https://tomcat.apache.org/download-70.cgi
It seems to me that all troubles in your authentication mechanism and not in controller mapping for URL-s.
It is a good tutorial about Security Java config LINK
When you try go to your pages without authentifications you are redirected to 'login page'. If I've understand right - your authentification process is fail all the time. In your configuration you can't go to '/welcome' and '/' pages without being authorized.
Try to add and change next things:
protected void configure(HttpSecurity http) throws Exception {
// Here you can define your custom redirections
.loginPage("[some url]")
.failureUrl("[some url]")
.loginProcessingUrl("[some url]")
.defaultSuccessUrl("[some url]")
// Here the credentials, sended to the authentification mechanizm (If you use clasic 'UsernamePasswordAuthenticationFilter')
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
// Permitions for access pages
http.authorizeRequests()
.antMatchers("/welcome", "/").permitAll()
// Access restriction without using roles
.antMatchers([some other URL-s]]).authenticated()
// or using ROLES
.antMatchers([some other URL-s]]).hasRole("USER")
// Here you can define your custom redirections for logout
.and()
.logout()
.logoutUrl("/logOut")
.logoutSuccessUrl("/welcome");
}
If you use clasic 'UsernamePasswordAuthenticationFilter' you must define it as bean (If you use another fllter, of course you must define it):
#Bean
public UsernamePasswordAuthenticationFilter filter() {
UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter();
filter.setAuthenticationManager(providerManager());
return filter;
}
And then in JSP page use form like this ('j_username' and 'j_password' parameters required in default authentication with 'UsernamePasswordAuthenticationFilter')
<form name="signIn" action="[your SignIn URL]" method="POST">
<input type="text" name="j_username"></label>
<input type="password" name="j_password"></label>
<input type="submit" value="Log In">
</form>
You must try the remote debugging to find what fail in your authentication process.