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
}
}
Related
This is my practice Spring project. I can not redirect to the right page in SpringMVC Interceptor.
spring-mvc.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: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">
<description>Spring MVC Configuration</description>
<context:property-placeholder ignore-unresolvable="true" location="classpath:myshop.properties"/>
<context:component-scan base-package="com.huahua.my.shop" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="${web.view.prefix}"/>
<property name="suffix" value="${web.view.suffix}"/>
</bean>
<mvc:resources mapping="/**/static/**" location="/static/" cache-period="31536000"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/static/**"/>
<mvc:exclude-mapping path="/loginOut"/>
<bean class="com.huahua.my.shop.web.admin.web.intercepter.LoginIntercepter" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean class="com.huahua.my.shop.web.admin.web.intercepter.PermissionIntercepter" />
</mvc:interceptor>
</mvc:interceptors>
</beans>
this is UserController class
#Controller
#RequestMapping(value = "/user")
public class UserController {
#Autowired
TbUserService tbUserService ;
#RequestMapping(value = "/list" , method = RequestMethod.GET)
public String userList(){
return "user_list" ;
}
}
this is my interceptor
public class LoginIntercepter implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o ) throws Exception {
TbUser tbUser =(TbUser) httpServletRequest.getSession().getAttribute(ConstantUtils.SESSION_USER); //SESSION_USER = user
System.out.println(httpServletRequest.getRequestURL());
if (tbUser == null){
httpServletResponse.sendRedirect("login");
}
return true;
}
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}
}
this is LoginController
#Controller
public class LoginController {
#Autowired
private TbUserService tbuserService ;
#RequestMapping(value = {"","login"},method = RequestMethod.GET)
public String login(){
return "login" ;
}
#RequestMapping(value = "login",method = RequestMethod.POST)
public String login(#RequestParam(required = true) String email ,
#RequestParam(required = true ) String password ,
#RequestParam(required = false) String isRemember,
HttpServletRequest request,
Model model){
TbUser user = tbuserService.loginRight(email, password);
isRemember = isRemember == "on" ? "checked" : null ;
if (user != null ){
request.getSession().setAttribute(ConstantUtils.SESSION_USER,user);
request.getSession().setAttribute("remember",isRemember);
return "redirect:/main" ;
}
else {
model.addAttribute("message","username or password is wrong");
return "login" ;
}
}
when I log in and request http://localhost:8080/user/list , I successfully entered user_list.jsp.
after a time, this session is out of time,I refresh this page,
the HTTP of refresh user_list page
I hope it is redirected to http://localhost:8080/login,
but I got this path http://localhost:8080/user/login
wrong with 404
how can I solve this wrong?
why there is extra a '/user' in the path?
and what are the relation between the /user in redirect path and the #RequestMapping(value = "/user") in UserController ?
Thank you very much!!!
As the API docs note for HttpServletResponse#sendRedirect:
Sends a temporary redirect response to the client using the specified
redirect location URL and clears the buffer. The buffer will be
replaced with the data set by this method. Calling this method sets
the status code to SC_FOUND 302 (Found). This method can accept
relative URLs;the servlet container must convert the relative URL to
an absolute URL before sending the response to the client. If the
location is relative without a leading '/' the container interprets it
as relative to the current request URI. If the location is relative
with a leading '/' the container interprets it as relative to the
servlet container root.
So because you have specified a relative URL is resolved relative to the current request URl /users/list
So you need to change it to:
httpServletResponse.sendRedirect("/login");
I want to add or remove some attributes before the View rendered, I think the interceptor can help me, but it does not work.
The mvc context xml:
<mvc:annotation-driven></mvc:annotation-driven>
<mvc:interceptors>
<bean class="org.tt.interceptor.FieldsInterceptor"></bean>
</mvc:interceptors>
<bean id="jsonWSResponseView" class="org.tt.view.JsonWSResponseView"></bean>
<bean id="xmlWSResponseView" class="org.tt.view.XmlWSResponseView"></bean>
<!-- ViewResolver -->
<bean id="viewResolver" class="org.tt.ws.WSViewResolver">
<property name="views">
<map>
<entry key="json" value-ref="jsonWSResponseView"></entry>
<entry key="xml" value-ref="xmlWSResponseView"></entry>
</map>
</property>
</bean>
Controller:
#Controller
#RequestMapping("/traffic/")
public class TrafficController {
private static org.slf4j.Logger logger = LoggerFactory.getLogger(TrafficController.class);
#RequestMapping("query")
public ModelAndView getTrafficInfo(ModelAndView modelAndView, #RequestParam String name){
modelAndView.setViewName("json");
modelAndView.addObject("test","test");
modelAndView.addObject("name",name);
return modelAndView;
}}
FieldsInterceptor:
public class FieldsInterceptor extends HandlerInterceptorAdapter {
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
try {
modelAndView.addObject("AA", "add attribute");
}catch (Exception e){
e.printStackTrace();
}
}
}
The View:
public class JsonWSResponseView implements View {
public String getContentType() {
return "application/Json";
}
public void render(Map<String, ?> map, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
OutputStreamWriter os = new OutputStreamWriter(httpServletResponse.getOutputStream());
os.write(JSON.toJSONString(map.get("modelAndView")));
os.close();
}
}
Request and Response:
doesn't have the attribute "AA"
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 have controller
#Controller
public class AuthorController {
#Autowired
private AuthorDAO authorDao;
#RequestMapping("/authors")
public String showAuthor(#RequestParam String name, ModelMap model) {
Author author = authorDao.findByName(name);
model.addAttribute("author", author);
return "authors";
}
}
I wrote test for it
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:test-application-context.xml"})
public class AuthorControllerTest {
private static final String JACK_C = "Jack C.";
#Autowired
AuthorController controller;
#Test
public void testShowAuthor() {
Author expectedAuthor = new Author();
AuthorDAO daoMock = mock(AuthorDAO.class);
when(daoMock.findByName(JACK_C)).thenReturn(expectedAuthor);
ModelMap model = new ModelMap();
String view = controller.showAuthor(JACK_C, model);
assertEquals("View name is incorrect","authors", view);
assertSame(expectedAuthor, model.get("author"));
verify(daoMock).findByName(JACK_C);
}
}
test-application-context.xml:
<context:annotation-config />
<context:component-scan base-package="com.github.futu" />
<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/blog" /> <property name="username"
value="blogger" /> <property name="password" value="blogger" /> </bean>
<bean id="com.github.futu.dao.AuthorDAO" class="com.github.futu.dao.impl.AuthorDAOXml"/>
<bean id="com.github.futu.dao.PostDAO" class="com.github.futu.dao.impl.PostDAOXml" />
<bean id="validator" class="com.github.futu.validator.PostValidator" />
But real dao is called. What have I missed?
You're creating a mock here
AuthorDAO daoMock = mock(AuthorDAO.class);
that is completely unrelated to your controller injected into your test class
#Autowired
AuthorController controller;
Of course the autowired AuthorDao target is going to come from your XML configuration
#Autowired
private AuthorDAO authorDao;
Ideally you would change your XML configuration only produce a #Controller bean and add a setter to it to set the AuthorDao from within the test, using your mock.
I have been trying out the new Spring MVC 3.0 Type Conversion Framework. I cannot find out how to trap conversion errors.
I am using the new mvc schema:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Scan this package and sub-packages for Annotated Controllers -->
<context:component-scan base-package="springmvc.simple"/>
<!-- New Spring 3.0 tag to enable new Converter and Formatting Frameworks -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
And a simple command class:
public class Amount {
#NumberFormat(style=Style.CURRENCY)
#Min(0)
private BigDecimal amount = BigDecimal.valueOf(10000, 2);
#DateTimeFormat(iso=ISO.DATE)
private Date date = new Date();
public Date getDate() {
return date;
}
public BigDecimal getAmount() {
return amount;
}
}
And an equally simple controller:
#Controller
#RequestMapping(value="/addVat.html")
public class AddVatController {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
}
#RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model) {
model.addAttribute("commandBean", new Amount());
return "addVatForm";
}
#RequestMapping(method = RequestMethod.POST)
public String onSubmit(#ModelAttribute("commandBean") #Valid Amount commandBean, BindingResult amountBinding, Model model) {
if (amountBinding.hasErrors()) {
return "addVatForm";
}
BigDecimal result = commandBean.getAmount().multiply(new BigDecimal("1.175"));
model.addAttribute("result", result);
return "result";
}
}
This works fine - I get validation error in my result.jsp if I enter a negative value for the BigDecimal. However if I try to send a Date such as 2010-07-024, which does not conform to ####-##-##, I get an error:
org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value 2010-07-024 from type 'java.lang.String' to type 'java.util.Date'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2010-07-024" is malformed at "4"
org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:135)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:169)
org.springframework.beans.DirectFieldAccessor.setPropertyValue(DirectFieldAccessor.java:125)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:50)
org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
org.springframework.validation.DataBinder.applyPropertyValues(DataBinder.java:665)
org.springframework.validation.DataBinder.doBind(DataBinder.java:561)
org.springframework.web.bind.WebDataBinder.doBind(WebDataBinder.java:190)
org.springframework.web.bind.ServletRequestDataBinder.bind(ServletRequestDataBinder.java:110)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.doBind(AnnotationMethodHandlerAdapter.java:696)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doBind(HandlerMethodInvoker.java:744)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:296)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:163)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
Which is fine - but how do I trap the error? I was expecting BindingResult to simply contain another error?
See if registering appropriate DateEditor can help you..... 15.3.2.12
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.initDirectFieldAccess();
**/* register appropriate date editor */**
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
According to Juergen Hoeller, this was fixed in Spring 3.0.2