Spring: servlet-mapping -> url-pattern : /* working but can't display - java

web.xml
<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/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
/WEB-INF/spring/webmvc-config.xml
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml" />
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
</list>
</property>
</bean>
Controller
#Controller
#RequestMapping ( "/" )
public class IndexController extends BaseController
{
#RequestMapping ( "/" )
public String index ( Model model ){
System.out.println("AA");
return index2(model);
}
#RequestMapping ( "/index" )
public String index2 ( Model model ){
System.out.println("BB");
return "index";
}
}
And exist index.jsp File
I guess that is very good working
BBBBBBBBBBBUUUUUUUUUTTTTTTTTT, BUT!
WHY????
WHY????
WHY????
WHY????
And More strange
??????????????????????????????????????????????????????????????????
Controller work it!! but don't display browser
What's going on?
Please help me.
And Log
DispatcherServlet with name 'dispatcher' processing GET request for [/WEB-INF/views/index.jsp]
No mapping found for HTTP request with URI [/WEB-INF/views/index.jsp] in DispatcherServlet with name 'dispatcher'

Servlet containers have rules for how they map and handle URI requests. These can be found in the Servlet Specification. It's also important to note that most Servlet containers have a Servlet to handle JSPs, mapped to *.jsp, which is an extension mapping. Tomcat has a JspServlet to do this.
You've mapped your DispatcherServlet to
<url-pattern>/*</url-pattern>
which is a path mapping. Path mappings take precedence over extension mappings. So when you submit your view name
return "index";
Spring will use the ViewResolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
to resolve a path to use with a RequestDispatcher's forward method. That path will be /WEB-INF/views/index.jsp. Now the Servlet container will receive that path and attempt to find a Servlet to handle it. Since you have a Servlet mapped to /* it will use it, but your DispatcherServlet doesn't have a mapping for that path and therefore responds with a 404.
The simple solution is to change your mapping to /, which is the default handler if no other matches are found. In this case, when you submit your view and the container must find a mapped Servlet, it will find the JspServlet and use it.

Related

Spring MVC - Multipart file upload with Ajax (Could not parse multipart servlet request)

I'm trying to upload a multipart file using Ajax, Spring MVC 3.2.0, Tomcat 8.0.9, but can't get it work. I read a lot of blogs and similar posting here on stackoverflow (Spring upload file problems, MultipartConfig with Servlet 3.0 on Spring MVC, …) which seem to have similar causes but couldn't figure out how to solve it. The weird thing is that the upload works when the file is smaller than 1MB, but when ever the recorded video exceeds that size, the following error is raised:
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:163)
org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:110)
In the following you can see all the configurations I made:
The AJAX POST-Request:
var videoBlob = e.data;
var pathArray = window.location.pathname.split( '/' );
var userID;
for (i = 0; i < pathArray.length; i++) {
if (pathArray[i].toString() == "edit"){
userID = pathArray[i+1];
}
}
var fd = new FormData();
fd.append('fname', 'video');
fd.append('data', videoBlob);
$.ajax({
url: '/user/edit/uploadVideo/' + userID,
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data)
{
$('#result').html(data + "uploaded by FormData!");
}
});
The web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:root-context.xml</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>common</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<display-name>springMultipartFilter</display-name>
<filter-name>springMultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springMultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The servlet-context.xml
<mvc:annotation-driven />
<mvc:resources mapping="/**" location="/resources/" />
<context:component-scan base-package="de.talentwuerfel"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/schema"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="packagesToScan">
<array>
<value>de.talentwuerfel</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
The root-context.xml where I defined the MultipartResolver
<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
<property name="maxInMemorySize" value="4096"/>
</bean>
The Java-Controller
#RequestMapping(value = "/edit/uploadVideo/{id}", method = RequestMethod.POST)
public #ResponseBody String uploadVideo(#PathVariable long id, MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
//.... file handling
}
How can I solve this problem?
EDIT:
I tried the suggested approach and used the Servlet implementation to manage my video-file upload. The following adjustments have been made, but it's still resulting in a similar error:
Adjusted #Controller:
#RequestMapping(value = "/edit/uploadVideo/{id}", method = RequestMethod.POST)
public String uploadVideo(#PathVariable long id, #RequestParam("data") Part file) {
//...
}
The root-controller has been deleted and I added the multipartResolver to the servlet-context.xml
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>
The tag was in the web.xml has been extended by the following Multipart-Configuration:
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<location>/tmp</location>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
However, I'm still getting an exception and can't upload a blob file larger than 1MB:
Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. null
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:927)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
I implemented a similar file upload where a single file was simply picked and it totally worked to send large files while using the same configuration. So I believe it has rather something to do with the Ajax POST or the attached blob file?!
you can add this in you application to active Servlet3.0 MultiParsing:
#Bean
public MultipartConfigElement multipartConfigElement() {
MultiPartConfigFactory factory = new MultiPartConfigFactory();
factory.setMaxFileSize("128KB");
factory.setMaxRequestSize("128KB");
return factory.createMultipartConfig();
}
or do it in XML.
Not really an answer to your exact question, just my 2 cents. There are basically 2 ways of uploading files with the help of Spring MVC :
using Jakarta Commons FileUpload, the only way (aside from implementing one yourself) before the appearance of the servlet 3.0 API
using the Servlet implementation of your server (only if servlet impl version >= 3.0)
Since you are using Tomcat 8.0.9, the Servet 3.0 option is available to you which I definitely recommend since it doesn't introduce yet another external dependency in your project. Also, since it follows the Servlet 3.0 spec, the configuration of such upload mechanism is now java standard which is nice in case you decide to move from Spring MVC to another MVC framework (your configuration values would remain the same).
In case you can't figure out your IOFileUploadException, I think you should give it a try.

I can't find answer that Could not resolve view with name 'index' in servlet with name 'DispatcherServlet'

I started study Spring MVC and tomcat just.
I want to display html page by Spring and ThymeLeaf VewTemplate Engine.
But It doesn't work.
below my configure File and Controller.
web.xml File
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/webapp/WEB-INF/DispatcherServlet-serlvet.xml
<context:component-scan base-package="com.everblog.controller" />
<!-- ViewResolver be configured by thymeleaf -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="characterEncoding" value="UTF-8" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="order" value="1" />
<property name="viewNames" value="*.html" />
</bean>
And Controller
#Controller
public class PostItemController {
#RequestMapping(value="/hello", method = RequestMethod.GET)
public String helloWorld() {
System.out.println("IS IN");
return "index";
}
}
I typed localhost:9000/hello on browser, then browser display this error messages.
HTTP Status 500 - Could not resolve view with name 'index' in servlet with name 'DispatcherServlet'
type Exception report
message Could not resolve view with name 'index' in servlet with name
'DispatcherServlet'
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: Could not resolve view with name
'index' in servlet with name 'DispatcherServlet'
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1190)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
note The full stack trace of the root cause is available in the Apache
Tomcat/7.0.50 logs.
index.html is located on /webapp/WEB-INF/view/
What I to do Configure anymore?
Take a look at the javadoc of ThymeleafViewResolver#setViewNames(String[]). It states
Specify a set of name patterns that will applied to determine whether
a view name returned by a controller will be resolved by this resolver
or not.
The view name your #Controller handler method returns is
return "index";
That view name definitely does not match the pattern
*.html
You would have to use
return "index.html";
for Spring to use your ThymeleafViewResolver, though that would fail at a later step since no such resolved JSP exists.
Instead, just get rid of the viewNames <property> or fix it and your #Controller method accordingly.
replace the last bean alone in thymeleaf resolver with this code it will work fine
<beans:bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<beans:property name="templateEngine" ref="templateEngine" />
</beans:bean>

spring mvc #pathvariable not working with url file extension

i am facing an issue while invoking spring mvc method which has pathvariable
#RequestMapping(value="/retrieveData/{userId}", method=RequestMethod.POST)
public #ResponseBody
ModelAndView retrieveData(#PathVariable Long userId , HttpSession session) {
i have web.xml servlet mapping as below
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
in my jsp , i have my javascript
document.getElementById("form1").action = "retrieveData.html/2";
document.getElementById("form1").submit();
so my question is, will path variable works with url file extension in my case i have *.html , which i eventually want my servlet to map /retrieveData/{userId}
while submitting the page i am getting HTTP Status 400 error. help needed
EDIT:- i have ContentNegotiationManagerFactoryBean configure in my spring context
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>

Spring message bundle issue

I've got a spring-security setup in my web-app. I want to replace some messages of spring security with my custom messages i.e.
Instead of Bad Credentials I want AbstractUserDetailsAuthenticationProvider.badCredentials to have value invalid username or password, please try again
This is my spring setup :
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages/messages"/>
<!-- Tried this as well <property name="basename" value="/WEB-INF/messages/messages.properties"/> -->
<property name="cacheSeconds" value="0" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
And I have created folder in the WEB-INF called messages. Inside this folder there is file called messages.properties. Inside this file is one line :
AbstractUserDetailsAuthenticationProvider.badCredentials=invalid username or password, please try again
What am I doing wrong here?
Update :
This servlet-context is defined in the web xml :
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Problem solved, moved the messageSource bean definition to another context.
Everything looks right. Try to get the message using spring message tag in order to check if the problem is with your configuration or with the security message:
<spring:message code="AbstractUserDetailsAuthenticationProvider.badCredentials" />
If this does work, problem is not with your configuration (that looks fine for me).
Anyway, try to put your messages files in the classpath (source folder) and this:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages/messages"/>
<property name="cacheSeconds" value="0" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
Also, check that the bean is being declared in a application context file that Spring is aware of.

Spring 3: map page.html to page.jsp

I'm using Spring 3 and i don't know how to map somepage.htm to somepage.jsp without a controller.
That is: if i go to somepage.htm, i want it to show me the jsp. But of course without redirect. I dontw want anyone to see ".jsp" only ".htm"
<servlet>
<servlet-name>Training01</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Training01</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
The way to do is to use the <mvc:view-controller..> tag in combination with a view resolver.
See here for more documentation:
The <mvc:view-controller..> tag maps urls to views. So if you want to map the relative url /login to a view names login you would do it by adding the following line to you webmvc-context.xml file:
<mvc:view-controller path="/login" view-name="login" />
Of course to get this to work you'll have to have a view resolve - something that maps logic names to specific views - setup in your context. In your case since you are using straight jsps for you view layer you'll want to add something like this to your configuration:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
So with this setup if you had a jsp login.jsp located in you /WEB-INF/jsp directory then you would be able to directly reference that jsp from the url www.myapp.com/mycontenxtroot/login
See here for some more info on view resolvers:
You might be interested in UrlRewriteFilter. This is the approach I would recommend. If you're serious about clean URLs you'll likely need it at some point anyway.
On the other hand, if it's a one-off, a minimal controller might be easier:
#Controller
public class Somepage {
#RequestMapping("/somepage")
public String handler() {
return "somepage.jsp";
}
}

Categories