Spring3 MVC - Controller class is getting called but not the controller method.
Controller:
package com.quizat.controller;
#Controller
public class QuizatController {
public QuizatController(){
System.out.println("in controller");
}
#RequestMapping("/")
#ResponseBody
public String home(Model model) throws Exception {
System.out.println("home is running");
return "success";
}
}
My web.xml
<display-name>Spring3Example</display-name>
<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/dispatcher-servlet.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>
</web-app>
My dispatcher-servlet.xml
<mvc:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="com.quizat" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/view/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Constructor of my controller runs. But my method inside the Controller is not getting called. What could be the error that I have made?
You are mapping / to your controller's method. Instead of that you should map a string like /home or /*.
#RequestMapping("/home")
#ResponseBody
public String home(Model model) throws Exception {
}
Also in the Controller you can use #RequestMapping(value = "/*") for the home() method.
Note: you should also be using Spring >= v3.0.3 due to SPR-7064
Reference: How do I map Spring MVC controller to a uri with and without trailing slash?
Related
I am trying SPRING MVC with JDBCTemplate with transactional save. When it is transactional, when there is any error while saving in database, I am expecting it to rollback all database operations. Here I have considered 2 tables and saving data in both tables in a single method which has annotation #Transactional. Purposefully I was sending more text than the size declared in db for a field to see whether first table data is getting rolled back, but it saves in the first table (not getting rolled back). Please help me to solve the issue.
Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
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 ">
<!-- Initialization for TransactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- Initialization for data source -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- Definition for studentJDBCTemplate bean -->
<bean id="studentJDBCTemplate" class="com.springjdbctemplate.StudentJDBCTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
StdentJDBCTemplate:
public class StudentJDBCTemplate implements StudentDAO {
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
#Override
public void setDataSource(DataSource ds) {
this.dataSource = ds;
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
}
#Transactional
#Override
public void create(String name, Integer age, int id, String address) {
String SQL = "insert into springstudent (name, age, id) values (?, ?, ?)";
jdbcTemplate.update(SQL, name, age, id);
System.out.println("Created Record Name = " + name + " Age = " + age + " id = " + id);
SQL = "insert into springaddress (name, address) values (?, ?)";
jdbcTemplate.update(SQL, name, address);
System.out.println("Created Record Name = " + name + " address = " + address);
}
#Override
public Student getStudent(Integer id) {
return null;
}
#Override
public List<Student> listStudents() {
String SQL = "select * from springstudent";
List<Student> students = jdbcTemplate.query(SQL, new StudentMapper1());
return students;
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringSampleApplications</display-name>
<servlet>
<servlet-name>welcome</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>welcome</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
MainApp:
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");
System.out.println("------Records Creation--------" );
studentJDBCTemplate.create("Zara", 11, 1, "addr1");
studentJDBCTemplate.create("Nuha", 2, 2, "addr2");
studentJDBCTemplate.create("Ayan", 15, 3, "addr3addr1addr1");
System.out.println("------Listing Multiple Records--------" );
List<Student> students = studentJDBCTemplate.listStudents();
for (Student record : students) {
System.out.print("ID : " + record.getId() );
System.out.print(", Name : " + record.getName() );
System.out.println(", Age : " + record.getAge());
}
Please help me what am I missing.. thankssss
Make sure your dataSource is not setup for "autoCommit=true".
And you need to add something like this to your Beans.xml:
<tx:annotation-driven transaction-manager="transactionManager" />
I am trying to use custom validation error messages by using properties file. I have placed messages.properties file in web content/web-inf/ folder.
NonEmpty.batchDomain.batchName=Invalid message 2.
My applicationContext file is :
<context:component-scan base-package="com.coaching.controller" />
<!-- Enable annotation driven controllers, validation etc... -->
<mvc:annotation-driven />
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views
directory -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:default-servlet-handler />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
</bean>
And my controller is :
#RequestMapping(method = RequestMethod.POST)
public ModelAndView addBatch(
#Valid #ModelAttribute("batchDomain") BatchDomain batchDomain,
BindingResult result, HttpServletRequest request,
HttpServletResponse response) throws Exception {
try {
if (result.hasErrors()) {
ModelAndView modelAndView = new ModelAndView("newBatch");
return modelAndView;
}
}
BatchDomain is :
public class BatchDomain {
#NotNull
#NotEmpty
#Size(min = 1, max = 100)
private String batchName;
#Min(1)
#Max(1000)
private int strength;
}
As far as I have seen in google, I am following the correct approach. So, what can be the reason behind this issue?
You may try to put file "messages.properties" in /src/main/resource directory.
once again iam looking a for help/guide from experts,
My problem is, i need to create Dynamic web site which calls to restfull server to get data, all the requests are POST and returns json object. Iam thinking of use of Spring RestTemplate to make calls to server. My Server works ok, meaning currently some android and Apple apps connects to same APIs and they work ok. But when i try to use RestTemplate to connect to server, it gives some errors
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
this is my server,
#Controller
public class ABCController
{
#RequestMapping(method = RequestMethod.POST, value = "/user/authenticate")
public #ResponseBody LoginResponse login(#RequestParam("email") String email,#RequestParam("password") String password,#RequestParam("facebookId") String facebookId) {
LoginRequest request = new LoginRequest(email, password, facebookId);
UserBusiness userBusiness = UserBusinessImpl.getInstance();
return userBusiness.login(request);
}
}
And this is my spring configs of server,
<?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"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean id="jsonViewResolver" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean name="abcController" class="com.abc.def.controller.ABCController" />
<mvc:annotation-driven />
</beans>
This is how i try to call the server using RestTemplate,
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<!-- <constructor-arg ref="httpClientFactory"/> -->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<ref bean="JacksonObjectMapper" />
</property>
</bean>
</list>
</property>
</bean>
<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
and this is how i use it (for testing)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("root-context.xml");
RestTemplate twitter = applicationContext.getBean("restTemplate", RestTemplate.class);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("email", "x1#test.com");
map.add("password", "abc");
map.add("facebookId", null);
HttpEntity<LoginResponse> response= twitter.exchange("https://abc.com/Rest/api/user/authenticate", HttpMethod.POST, map, LoginResponse.class);
my login response class, and its sub classes,
LoginResponse
public class LoginResponse extends BaseResponse {
private LoginBase data;
with getters and setters
}
Login Base
public class LoginBase {
private String token;
private User user;
with getters and setters
}
User
public class User {
private Integer userId;
private String email;
private Integer status;
private String name;
with getters and setters
}
finally BaseResponse
public class BaseResponse {
protected String statusCode;
with getter and setter }
My questions are,
1. Why do i get this error when i call the server
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#63de8f2d: defining beans [restTemplate,JacksonObjectMapper]; root of factory hierarchy
WARN : org.springframework.web.client.RestTemplate - POST request for "https://abc.com/Rest/api/user/authenticate" resulted in 400 (Bad Request); invoking error handler
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:90)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:494)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:451)
2. how do i map json response to java LoginResponse
You might have to add the content-type and accept headers to your request.
Mapping the response to LoginResponse can be done directly like this
LoginResponse lResponse = response.getBody();
or If you are using restTemplate.postForObject(), the reponse will be in the form of LoginResponse
i am making rest web services using spring.
with the help of rest client-ui i am Easily Insert update and Delete the User.
now i want to do the same things with the User JSP page but now am not able to call user Controller
User.jsp
<form action="adduser" name="user" id="my-form",method="POST"
onsubmit="com.mobile-app.controller"/>
UserController
#RequestMapping(method = RequestMethod.POST, value = "/adduser", headers="Accept=application/xml, application/json")
public void createuser(#RequestBody User user) {
try {
userManager.AddToUser(user);
} catch (Exception e) {
e.printStackTrace();
}
}
Web.Xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
Rest-Servlet.XML
<context:component-scan base-package="controller" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="adduser" class="com.mobileapp.controller.UserController">
<property name="userManager" ref="userManager" />
</bean>
Kindly please Help me To call Controller addUser Via JSP action
I will be very thankful
Create a POJO UserForm.java as
public class UserForm {
private Long id;
#NotEmpty(message = "Please enter name")
private String name;
#NotEmpty(message = "Please enter username")
private String username;
#NotEmpty(message = "Please enter password")
private String password;
private String address;
private String gender;
#Future(message = "Please enter valid DOB")
private Date dob;
private String email;
private String mobile;
//Getter & Setter
}
user.jsp page code will be
<c:url var="saveOrUpdateUrl" value="/app/user/saveOrUpdate" />
<form:form action="${saveOrUpdateUrl}" method="post" modelAttribute="userForm" id="userForm">
<form:input path="name"/>
// Other input fields
<input name="saveBtn" value="Save" type="submit">
</form:form>
In Controller you should have 2 method as
#Controller
#RequestMapping("/user")
public class UserController {
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(Model model) {
UserForm userForm = new UserForm();
model.addAttribute("userForm", userForm);
return "user";
}
#RequestMapping(value = "/saveOrUpdate", method = RequestMethod.POST)
public String saveOrUpdate(#RequestParam("id") Long id, #Valid UserForm userForm, BindingResult result, Model model) {
//Logic to save data from userForm
}
}
I am trying to use a MultiActionController in spring mvc, but I keep getting a 404 with the following message in the log
(org.springframework.web.servlet.PageNotFound)
No mapping found for HTTP request with
URI [/www.mysite.no/a/b/c] in
DispatcherServlet with name 'myServlet'
It looks like I'm following the book example, but it still doesn't work? Ideas, anyone?
Code samples: web.xml
<servlet-mapping>
<servlet-name>subscriptionServlet</servlet-name>
<url-pattern>/a/b/*</url-pattern>
</servlet-mapping>
Spring config: my-servlet.xml
<beans ...>
<bean id="myController" class="foo.bar.MyController">
<property name="methodNameResolver" ref="productMethodNameResolver"/>
</bean>
<bean id="productMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<value>
/*=view
</value>
</property>
</bean>
</beans>
The controller:
public class MyController extends MultiActionController {
Log logger = ...
#Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception{
logger.fatal("Never displayed in log");
return super.handleRequest(request, response);
}
public ModelAndView view(HttpServletRequest request, HttpServletResponse response) throws Exception {
logger.fatal("Never displayed in log");
return null;
}
I had included url mapping to methods within the controller, but lacked url mapping to the actual controller. The following must be added to the spring config
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*=myController
</value>
</property>
</bean>