I have spring project with web.xml 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>/WEB-INF/spring/appServlet/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>
Here is my servlet-context.xml
resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**" />
<default-servlet-handler/>
<context:component-scan base-package="pk.training.basitMahmood.web.controller" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jspx" />
</beans:bean>
Here is my controller
#RequestMapping("/contacts")
#Controller
public class ContactController {
final Logger logger = LoggerFactory.getLogger(ContactController.class);
#Autowired
private ContactService contactService;
#RequestMapping(method = RequestMethod.GET)
public String list(Model uiModel) {
logger.info("Listing contacts");
List<Contact> contacts = contactService.findAll();
uiModel.addAttribute("contacts", contacts);
logger.info("No. of contacts: " + contacts.size());
return "contacts/list";
}
} //end of class ContactController
Now when i select run on server then i get the following page
But when i change the url to http://localhost:9090/ch17_i18nSupport/contacts then i get the error that
I have list.jspx in my contacts folder. Why i am getting not found error?
Thanks
Although this was solved by Basit in the comments, I've also added it as an answer:
No adapter for handler indicates that the #RequestMapping methods in your controller aren't being picked up. Do you have a <mvc:annotation-driven /> tag in your servlet-context.xml?
Related
I have started some spring mvc application and deployed to WAR to web server. Deployed with out any issue but when using the URL on browser, i'm getting 404 error.
Web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 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/appServlet/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>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>
</web-app>
App Struture
Controller class
public class WeatherController {
#RequestMapping(value = "/CityWeather", method = RequestMethod.GET)
public String weather( Model model) {
return "home";
}
}
servlet-context.xml
<resources mapping="/resources/**" location="/resources/" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.weather" />
My application doesn't work with requestmapping, the request always works with the same method handleRequest, the controller is RestController.java and the URLs redirects to it when has the path /REST2/*, it works well but always with the same method. But the method "update" never works when I send the request to locahost:9080/myapp/REST2/rrr and if I change the URL i.e. localhost:9080/myapp/REST2/XXX also the request is going to handleRequest method.
The RequestMapping doesn't work well, I tried with other solutions but doesn't work..
Do you have any idea?
Restcontroller.java
public class RestController implements Controller{
private Configuration config;
private static String[] requestHeaders = {"accept", "pragma"};
private static String[] responseHeaders = {};
public void setConfig(Configuration config)
{
this.config = config;
}
#RequestMapping(value="/rrr") public ModelAndView update(HttpServletRequest request, HttpServletResponse response) throws Exception
{
String asset_name = request.getParameter("assetid");
response.setContentType("text/plain"); // Set content type of the response so that jQuery knows what it can expect.
response.setCharacterEncoding("UTF-8"); // You want world domination, huh?
String values = "Working"+ asset_name;
response.setContentLength(values.length());
PrintWriter out = response.getWriter();
out.println(values);
return null;
}
#RequestMapping(value ="/home")public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
{
Arrays.sort( requestHeaders );
Arrays.sort( responseHeaders );
String values;
String asset_name = request.getParameter("assetid");
...
response.setContentLength(values.length());
//
PrintWriter out = response.getWriter();
out.println(values);
return null;
}}
spring-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- View resolver. Prepends prefix /WEB-INF/jsp and suffix .jsp to view names. -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Always use full path when mapping URLs to bean names. -->
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="alwaysUseFullPath" value="true" />
</bean>
<!-- Home page. -->
<bean name="/home.app" class="com.fatwire.wem.sample.HomeController">
<property name="config" ref="config" />
</bean>
<!-- Installation page. -->
<bean name="/install.app" class="com.fatwire.wem.sample.InstallController">
<property name="config" ref="config" />
</bean>
<!-- Layout page. -->
<bean name="/layout.app" class="com.fatwire.wem.sample.LayoutController" />
<!-- REST proxy page. -->
<bean name="/REST/**" class="com.fatwire.wem.sample.ProxyController">
<property name="config" ref="config" />
</bean>
<!-- REST proxy page. -->
<bean name="/REST2/**" class="com.fatwire.wem.sample.RestController">
<property name="config" ref="config" />
</bean>
</beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
<!-- Bootstrap Spring configuration to be used by both SSO and MVC -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- WEM SSO Listener -->
<listener>
<listener-class>com.fatwire.wem.sso.SSOListener</listener-class>
</listener>
<!-- Configure Spring MVC -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.app</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/REST/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/REST2/*</url-pattern>
</servlet-mapping>
<!-- WEM SOO Filter -->
<filter>
<filter-name>WEM SSO Filter</filter-name>
<filter-class>com.fatwire.wem.sso.SSOFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>WEM SSO Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Request AJAX
function load_form(data){
var asset_id = data;
$.post('REST2/home', {
assetid : data,
}, function(responseText) {
alert(responseText);
});
}
function update_form(){
var asset_id = "XXX";
$.post('REST2/rrr', {
assetid : asset_id,
}, function(responseText) {
alert(responseText)
});
Try to add #Controller and #RequestMapping annotations to RestController classlike this:
#Controller
#RequestMapping(value="/REST2")
public class RestController implements Controller{
And add method=RequestMethod.POST the #RequestMapping of methods like this:
#RequestMapping(value ="/home", method=RequestMethod.POST)
...
#RequestMapping(value ="/rrr", method=RequestMethod.POST)
I have made a small spring mvc app. In my controller i have 2 methods which returns the names of the jsp files in the web-inf folder.
Now the application works perfectly, but if i try to add a url path it doesn't work.
What i mean is something like this:
#Controller
#RequestMapping("/start") //if add this it doesn't work
public class SalesController {
#RequestMapping(value = "/greeting")
public String sayGreeting(Model model) {
model.addAttribute("greetingMsg", "Hello Spring");
return "welcome";
}
#RequestMapping(value = "/hello")
public String getHello(Model model) {
model.addAttribute("greeting", "Yo man");
return "hello";
}
}
Here is my servletConfig configuration
<mvc:annotation-driven />
<context:component-scan base-package="com.myCompany" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/jsps/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
If i give the path "myApplicationName"/start/greeting it give error. But if i remove start it works.
What seems to be the problem here?
Thank you
Update:
Below is my web.xml configuration
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servletConfig.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
Add /.html* in your URL Pattern:
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servletConfig.xml</param-value>
</init-param> </servlet>
<servlet-mapping>
<servlet-name>SpringServlet</servlet-name>
<url-pattern>/*.html</url-pattern> </servlet-mapping>
I decided to move my authorization functionality to another controller, however this caused some issues for me. Mainly, my callback controller cannot forward the GET request to the appropriate dispatcher servlet
DispatcherServlet with name 'Auth' processing GET request for [/user/username] (this should be 'Dashboard' dispatcher servlet)
My view layer is making use of spring, tiles 2, and thymeleaf integration. I have found this comment on stackoverflow, which shed some light on my situation. https://stackoverflow.com/a/13406096/2276284
"Secondly, when using Spring + Tiles, and returning some JSP in your tiles definition, it is treated as an internal forward request, and handled by the same servlet as the original request."
I found this stackoverflow comment as well, but it did not work for me. https://stackoverflow.com/a/17232532/2276284 Suggesting returning a new ModelAndView, or using the HttpServletResponse to redirect.
How can I successfully redirect to another controller/view?
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="pue" version="3.1">
<!-- webapp properties -->
<display-name>PUE</display-name>
<description>Personal User Engagement for Instagram</description>
<!-- session listener -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- root context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/app-context.xml</param-value>
</context-param>
<!-- spring security filter -->
<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>
</filter-mapping>
<!-- custom redirect filter -->
<filter>
<filter-name>pueUsernameAuthFilter</filter-name>
<filter-class>abnd.pue.auth.service.impl.PUEUsernameAuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>pueUsernameAuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- servlet config -->
<servlet>
<servlet-name>Auth</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlets/auth-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>IgOauth</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlets/igoauth-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>Dashboard</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/servlets/dashboard-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- servlet mapping config -->
<servlet-mapping>
<servlet-name>Auth</servlet-name>
<url-pattern>/logout</url-pattern>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>IgOauth</servlet-name>
<url-pattern>/ig/oauth/callback</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Dashboard</servlet-name>
<url-pattern>/user/{username}</url-pattern>
<url-pattern>/user/{username}/profile</url-pattern>
<url-pattern>/user/{username}/assets</url-pattern>
</servlet-mapping>
<!-- mime types -->
<mime-mapping>
<extension>ico</extension>
<mime-type>image/x-icon</mime-type>
</mime-mapping>
</web-app>
spring-thymeleaf-tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- thymeleaf view resolvers with tiles integration -->
<bean id="tilesConfigurer" class="org.thymeleaf.extras.tiles2.spring4.web.configurer.ThymeleafTilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles/tiles.xml</value>
</list>
</property>
</bean>
<!-- template resolver -->
<bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/tiles/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="characterEncoding" value="utf-8" />
<property name="cacheable" value="false" />
</bean>
<!-- template engine -->
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean id="tilesDialect" class="org.thymeleaf.extras.tiles2.dialect.TilesDialect" />
</set>
</property>
</bean>
<!-- tiles view resolver -->
<bean id="tilesViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="viewClass" value="org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView" />
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="utf-8" />
<property name="order" value="1" />
</bean>
</beans>
IgOauthController
package abnd.pue.ig.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import abnd.pue.ig.service.intf.IgOauthService;
#Controller
public class IgOauthController {
#Autowired
private IgOauthService igOauthService;
private static final Logger logger = LoggerFactory.getLogger(IgOauthController.class);
/**
*
* #param request
* #return String
* #throws IOException
*/
#RequestMapping(value="/ig/oauth/callback")
public ModelAndView igCallback(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
// get code parameter
String code = request.getParameter("code");
// attempt to get user name from callback
String username = igOauthService.processCallbackRequest(request, session, code);
// if username isn't empty redirect to user page
if (!username.isEmpty()) {
logger.info("username set: " + username);
return new ModelAndView ("redirect:/user/" + username);
}
logger.info("no username set");
// otherwise return to index TODO error display
return new ModelAndView("redirect:/");
}
}
Alright, thanks for the help guys. So, the issue was that I could not redirect my view away from the default DispatcherServlet. I was also using invalid url patterns in my web.xml, while trying to create dynamic urls.
The answer was restructuring the wiring of my servlet paths, and changing the default servlet from Auth, to Dashboard. I also implemented UrlRewriteFilter to redirect all traffic from root context ("/") to "/login"
Here are the affected changes.
web.xml
<!-- servlet mapping config -->
<servlet-mapping>
<servlet-name>Auth</servlet-name>
<url-pattern>/login</url-pattern>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>IgOauth</servlet-name>
<url-pattern>/ig/oauth/callback</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Dashboard</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
IgOauthController
#Controller
#RequestMapping(value = "/ig/oauth")
public class IgOauthController {
#Autowired
private IgOauthService igOauthService;
private static final Logger logger = LoggerFactory.getLogger(IgOauthController.class);
/**
*
* #param request
* #return String
* #throws IOException
*/
#RequestMapping(value="/callback")
public void igCallback(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
// get code parameter
String code = request.getParameter("code");
// attempt to get user name from callback
String username = igOauthService.processCallbackRequest(request, session, code);
// if username isn't empty redirect to user page
if (!username.isEmpty()) {
logger.info("username set: " + username);
response.sendRedirect("/" + username + "/dashboard");
return;
}
logger.info("no username set");
// otherwise return to index TODO error display
response.sendRedirect("/login");
return;
}
}
DashboardController
#Controller
#RequestMapping(value = "/{username}")
public class DashboardController {
#RequestMapping(value = "/dashboard", method=RequestMethod.GET)
public ModelAndView userDashboard() throws InstagramException {
...
}
#RequestMapping(value = "/profile", method=RequestMethod.GET)
public ModelAndView userProfile() throws InstagramException {
...
}
#RequestMapping(value = "/assets", method=RequestMethod.GET)
public ModelAndView userAssets() throws InstagramException {
...
}
}
I am getting the following error:
No mapping found for HTTP request with
URI [/my-app] in DispatcherServlet
with name 'web'
My web.xml looks like:
<servlet>
<servlet-name>web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>web</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
And my web-servlet.xml looks like:
<bean name="myController" class="com.app.web.MyController" />
<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>
Any help / explanation would be great. Also, what should the view parameter be to new ModelAndView(?) in the controller?
My goal is to be able to hit http://localhost:8080/my-app and be routed to MyController which would then load a given jsp.
Your configuration looks fine to me. In your MyController, make sure you have a request mapping for my-app, like this:-
#Controller
public class MyController {
#RequestMapping(value="/my-app", method=RequestMethod.GET)
public String mainPage() {
return "index";
}
}
When you call http://localhost:8080/my-app, the server will return the index.jsp from /WEB-INF/jsp/ folder.
Looks like DispatcherServlet is trying to process the request for /my-app, which suggests to me that your web.xml servlet-mapping is directing requests for that space to DispatcherServlet.
You might have something like this?
<servlet-mapping> <servlet>dispatcher</servlet> <url-pattern>/*</url-pattern> </servlet-mapping>
Try calling your controllers with a different extension (.do for example) and update the servlet-mapping to suit
<servlet-mapping> <servlet>dispatcher</servlet> <url-pattern>*.do</url-pattern> </servlet-mapping>
or change /* to /
Hope that helps.