Spring controller not created - java

There is a small Struts application and I am trying to enable Spring-mvc on it. It's already using Spring to handle the DB transactions. I have two questions:
Component scan will not pick up my controllers if I try to add a new base package.
If I place my controllers in an existing base package, I can see them created in Spring application context. But then the request mapping still does not work.
Here are my relevant code snippets:
web.xml:
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>*.site</url-pattern>
</servlet-mapping>
Here is springDispatcher-servlet.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.mycom.eps.test, com.mycom.epsadmin"/>
<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/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="exceptionHandler" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">error</prop>
<prop key="org.hibernate.exception.GenericJDBCException">jdbcerror</prop>
</props>
</property>
</bean>
</beans>
Here's part of ApplicationContext.xml:
<context:annotation-config />
<context:component-scan base-package="com.mycom.eps, com.mycom.tiff" />
<tx:annotation-driven proxy-target-class="true" />
I've got two Controllers:
package com.mycom.eps.test;
// import statements
#Controller
public class TestController {
#RequestMapping(value="/test", method={RequestMethod.GET, RequestMethod.POST})
public ModelAndView test(HttpServletRequest request, HttpServletResponse response) throws EpsException {
Map<String, Object> modelMap = new HashMap<String, Object>();
return new ModelAndView("/details", modelMap);
}
}
Another controller:
//This is a new package I am trying to create
package com.mycom.epsadmin.controller;
// import statements
#Controller
public class PackageController {
#RequestMapping(value="/sendPackage", method={RequestMethod.GET, RequestMethod.POST})
public ModelAndView sendPackage(HttpServletRequest request, HttpServletResponse response) throws EpsException {
Map<String, Object> modelMap = new HashMap<String, Object>();
return new ModelAndView("/details", modelMap);
}
}
My first question is, why is the com.mycom.epsadmin.controller.PackageController never created in web application context (I inspected the spring log and couldn't find it)?
While trying to figure out about my first question, I created another controller com.mycom.eps.test.TestController (hence the name of the controller). While this one does get created in the Web application context, the request is never intercepted (404 error).
Here's how I am trying to call it:
$.ajax({
type: "POST",
url: "test.site",
cache: false
});
When I try to go to the page through browser http://http://localhost:8080/mycom/test.site, I am getting 404 error as well.
Sorry for the lengthy post! But can someone kindly point me in the right direction? Thanks a bunch!
UPDATE:
Just found out that the test controller is actually picking up the request (really sorry about that)! So my second question is moot.

Try after adding com.mycom.epsadmin in the ApplicationContext
<context:component-scan base-package="com.mycom.epsadmin, com.mycom.eps, com.mycom.tiff" />

Related

Keep Getting Status 404 with Warning: No mapping found for HTTP request with URI [/motion-comics/welcome/] in DispatcherServlet

I am having issue in spring3 frameowrk.org.springframework.web.servlet.DispatcherServlet
file name is WelcomeController.java
package com.rethink.controller;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/welcome")
public class WelcomeController {
#RequestMapping(method = RequestMethod.GET)
public String displayMessage(Map<String, String> map){
System.out.println("In");
map.put("loginmessage","Please Login with Your Details");
return "index";
}
}
this is my web.xml and motion-comics-servlet.xml
Click here for web.xml and motion-comics-servlet.xml screen shot
I have placed my view in Web Pages/Web-INF/jsp/index.jsp
no matter what i try i just can't make it to work....
my help and advise will be much appreciated ....
thanks in advance
I tried some examples and found out couple of configuration changes are required in your code.
Add < mvc:annotation-driven /> to your motion-comics-servlet.xml file.
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Add this to your xml file -->
<mvc:annotation-driven/>
<!-- Make sure that you are scanning all your packages required for your application -->
<context:component-scan base-package="com.rethink.controller"></context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
Change motion-comics servlet-mapping to the following configuration. Change '/*' to '/'. Remove *.
<servlet-mapping>
<servlet-name>motion-comcis</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Please let me know if you run into any issues.
You can verify the spring web mvc logs, whether the controller is getting registered for that URL or not. Also verify whether the component scan is properly set or not.
Further you can verify the view resolver is configured appropriately or not.
For more detailed understanding check this post

Spring Framework Project not loading?

I have been working with the Spring framework for a few days trying to set up a project, based off of something like this tutorial.
Unfortunately, when i deploy the project using Tomcat, I get a screen that looks something like this:
I'm not really sure to go from here. I've checked the web.xml and any other relevant .xml files that would maybe affect the error, but I can't see an error. Below I will post my web.xml and spring-config.xml files.
web.xml
<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_2_5.xsd"
version="2.5">
<display-name>Campaign Spring V2</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring_config.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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.bridge.campaignspring.controller" />
<context:property-placeholder location="classpath:application.properties" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.bridge.campaignspring.Campaign</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="CampaignDao" class="com.bridge.campaignspring.dao.CampaignDAOImpl" />
<bean id="CampaignService" class="com.bridge.campaignspring.service.CampaignServiceImpl" />
</beans>
If need be, I can post the project to GitHub to see if there is an even larger flaw that could be found in the code. Also, if any other parts of the project need to be posted I will update the OP to display anything. Thanks!
EDIT: http://localhost/ does not load either, I was incorrect with my previous statement.
EDIT2: Here is a link to the project on GitHub.
EDIT3: After going through the Spring tutorial again this was resolved!
You didn't follow the tutorial well. The controller mapping starts with
#RequestMapping("/")
public class AppController {
The first annotation #RequestMapping("/") is important for spring to calculate the path used by the request.
And this code is missing
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.bridge.compaignspring.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
Without it Spring cannot autowire properties that depend on sessionFactory.
Just done a quick check through the github project, you have more problems that I thought.
You are using XML config to create the DispatchServer with the config at Spring-config.xml, while also having a AppInitializer on the class path.
The AppInitializer uses AppConfig which creates a Datasource bean, your XML also creates a Datasource bean and also a SessionFactory.
Tomcat will find the AppInitializer and is running through that first.
This means it tries to autowire the SessionFactory before the one in the XML have been created.
To move your code off this problem do the following things.
move spring_config.xml from /webapp/WEB-INF to /resources
add the following #import line to AppConfig.java
#Configuration
#EnableWebMvc
#ImportResource("classpath:spring-config.xml")
#ComponentScan(basePackages = "com.bridge.campaignspring")
public class AppConfig {
Now you need to remove 1 of the 2 DataSource beans you are creating. I would suggest removing the one in the XML as that is using invalid property values. i.e. ${database.driver} does not exist.
After you have made those changes, you will still have other problems, but you are further along than you were.
did u set Web Module Path in tomcat settings ?
refer these question Unable to run Spring REST application using Tomcat

how to make rest service in spring mvc?

I am trying to make simple rest service which is used by everybody example it will consume by mobile developer.so I need to send static data to every one .I am trying to send static this data .
{
name:"abcd"
}
in other word if some one hit my system like this
http://192.168.12.61:8080/springfirst/hello .then user get above json.
I follow this like to make
http://www.programming-free.com/2014/03/spring-mvc-40-restful-web-service-json.html
I follow this step
download these jar files(-- jackson-annotations-x.x.x.jar
-- jackson-core-x.x.x.jar
-- jackson-databind-x.x.x.jar) and include in lib folder.
here is my code
web.xml
<web-app id="WebApp_ID" 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">
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>HelloWeb</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWeb</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
hello-servelts.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.tutorialspoint" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
controller.js
package com.tutorialspoint;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/hello")
public class HelloController{
#RequestMapping( method = RequestMethod.GET,headers="Accept=application/json")
public String printHello(ModelMap model) {
return "abcd";
}
}
you have configuration problems:
If you register DispatcherServlet in web.xml with out context configuration file path, then you should name the context file as per your servletName-servlet.xml.
So rename hello-servelts.xml as HelloWeb-servlet.xml.
and add #ResponseBody in your controller handler method to return JSON like:
#RequestMapping( method = RequestMethod.GET,headers="Accept=application/json")
public #ResponseBody Map printHello(ModelMap model) {
Map<String,String> json = new HashMap<String,String>();
json.put("name", "abcd");
return json;
}
Here is the working application using ContentNegotiatingViewResolver.
how to make rest service in spring mvc?
Ans, there is different ways are available. I am listing below some of:
To read/write JSON data from HTTP request or response you should use #RequestBody to read from HTTP request and #ResponseBody to write a object as JSON into HTTP response.
Spring provides ContentNegotiatingViewResolver where you can use it to resolve Views by request URL extension OR request ACCEPT header value. for example if URL is /view.html then it will return a view which has text/html content-type. same you can configure it to return JSON as well.
ContentNegotiatingViewResolver configuration for JSON View will look like:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
</map>
</property>
<property name="defaultViews">
<list>
<!-- JSON View -->
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
Note: Jackson mapper or any other mapper should be available on buildpath in order to work JSON serialize and deserialize.
If you use Maven, then confirm this dependency available in pom.xml:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
SEE ALSO:
How to return object from controller to ajax in spring-mvc
New features in spring mvc 3.1
You can follow this guide which is an official documentation and it is using spring-boot which will do easy your way to start writing services.
You rest service would be something like
#RestController
#RequestMapping("/hello")
public class HelloController{
#RequestMapping( method = RequestMethod.GET,headers="Accept=application/json")
#ResponseBody
public String printHello() {
return "abcd";
}
}

Spring MVC Handler Interceptor does not run

I have following interceptor class :
package cz.coffeeexperts.feedback.server.web.interceptors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class RestAuthorizationInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
System.out.println("fuu");
response.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
return false;
}
}
I configured it inside my spring-webmvc.xml as following :
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<mvc:annotation-driven/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/rest/api/01/status" />
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
However when I go to http://localhost:8080/myserver/rest/api/01/status, I get regular answer with status code 200 (same as before I added interceptor). Also, message "fuu" is not printed (so the preHandle method is not called).
Any ideas? I started to do it with this example : http://javapapers.com/spring/spring-mvc-handler-interceptor/, but all other examples look the same, I cant find where I go wrong.
I am using Spring 3.2.4.RELEASE
Important edit, it works with this :
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
So the question is, what is wrong with my path?
Ok, I found solution, because my path is defined with following :
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
And this is how my controller looks like
#Controller
#RequestMapping(value = "/api")
public class ApiController {
#RequestMapping(value = "/01/status", method = RequestMethod.GET)
#ResponseBody
public ServerStatusJSON getStatus(HttpServletResponse response) {
...
}
}
The working configuration for this address : http://localhost:8080/myserver/rest/api/01/status is as following :
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/01/status" />
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
PS : My thanks to geoand, he pushed me to the right way.
I solved this problem by changing the value of mvc:mapping. My working configuration is:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.mmd.micro.common.TokenInterceptor">
<property name="excludeUrls">
<list>
<value>/app/token</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
Providing additional explanation as to why this method worked for libik. As he has mentioned his controller looks like -
#Controller
#RequestMapping(value = "/api")
public class ApiController {
#RequestMapping(value = "/01/status", method = RequestMethod.GET)
#ResponseBody
public ServerStatusJSON getStatus(HttpServletResponse response) {
...
}
}
And also remember interceptors are at HandlerMapping level. In this case it would be RequestMappingHandlerMapping (Spring 3.1+ with mvc:annotation-driven) or DefaultAnnotationHandlerMapping. and the mapping here would be for
/api/01/status which is precisely what he has done.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/01/status" />
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
If you want it to be applied for all patterns you can simply do <mvc:mapping path="/**"/> - this will match all URLs (including subpaths) or you can simply invoke interceptors for all HandlerMappings -
<mvc:interceptors>
<bean class="cz.coffeeexperts.feedback.server.web.interceptors.RestAuthorizationInterc‌​eptor" />
</mvc:interceptors>

Configuring Spring MVC to map GET requests to one method in a controller and OPTIONS requests to another method

This would be pretty easy using annotations:
#Controller
public class MyController {
#RequestMapping(value="/hitmycontroller", method= RequestMethod.OPTIONS)
public static void options(HttpServletRequest req,HttpServletResponse resp){
//Do options
}
#RequestMapping(value="/hitmycontroller", method= RequestMethod.GET)
public static void get(HttpServletRequest req,HttpServletResponse resp){
//Do get
}
}
but I can't find how to do this in XML. Is there some mapping handler that will do something like this:
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<mapping>
<url>/hitmycontroller</url>
<httpMethod>GET</httpMethod>
<method>get</method>
<controller>MyController</controller>
</mapping>
<mapping>
<url>/hitmycontroller</url>
<httpMethod>OPTIONS</httpMethod>
<method>options</method>
<controller>MyController</controller>
</mapping>
</property>
</bean>
Any pointers would be appreciated.
With the SimpleUrlHandlerMapping it is not possible specify the http method. Probably you have to use other mapping like the MethodUrlHandlerMapping in the Spring MVC REST project (http://spring-mvc-rest.sourceforge.net/).
The way to declare the mappings using the MethodUrlHandlerMapping should be something like this:
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="GET /hitmycontroller">MyController</prop>
<prop key="OPTIONS /hitmycontroller">MyController</prop>
</props>
</property>
</bean>
You can see the example in their page:
http://spring-mvc-rest.sourceforge.net/introduction.html
Look at the part 2.
Your #RequestMapping annotations should work. Just delete the handlerMapping bean from your xml configuration and enable MVC annotations.
Here is a sample configuration. Change base-package to the package that contain your controller classes
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scan base-package="your.package" />
<mvc:annotation-driven>
</beans>

Categories