学习一下SpringMVC中几个常用的注解。
一、新建Dynamic Web Project工程SpringMVC02,jar包的添加以及Spring配置文件同上一节博客。这里在web.xml文件中把工程的默认首页改成index.jsp页面;
二、新建包com.test.model,新建类Student:
package com.test.model; public class Student { private int id; private String name; private int age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 三、新建控制层:StudentController
package com.test.controller; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import com.test.model.Student; @Controller @RequestMapping("/student") public class StudentController { private static List<Student> studentList = new ArrayList<Student>(); static{ studentList.add(new Student(1,"张三",11)); studentList.add(new Student(2,"李四",12)); studentList.add(new Student(3,"王五",13)); } @RequestMapping("/list") public ModelAndView list(){ ModelAndView mav = new ModelAndView(); mav.addObject("studentList",studentList); mav.setViewName("student/list"); return mav; } } 这里要重点说明一下几点:
1.在类上面使用了@RequestMapping("/student")进行注解,如果要想访问这个类中的方法,需要在方法名前加上这个前缀。比如要想访问这个类中的list方法,那么请求的时候要请求/student/list.do。在类名前添加这个注解是为了分模块用的。这个类中的list方法是用来查询所有学生信息的,如果工程中还有一个ClassController类,ClassController类中也有一个list方法用来查询所有的班级信息。那么请求的时候怎么区分是请求的哪个list方法呢?这里就要通过这种在类名前添加注解的方法了,在ClassController类前添加注解@RequestMapping("/class"),那么请求/class/list.do的时候就是访问的ClassController类中的list方法,请求/student/list.do就是访问的StudentController类中的list方法。
2.类中定义了一个studentList数组,里面放置了几个学生信息,把添加学生信息的代码放置在static代码块中,只会执行一次。以后和数据库一起使用就可以直接在数据库中读取数据。
3.list方法中使用了ModelAndView类对象,这个类用来返回模型和视图,返回模型就是向前台返回数据,返回视图就是要跳转到哪个页面。这个方法中向前台页面返回学生信息,把studentList放置在了mav中。根据springMVC配置文件中视图解析器的配置,项目会跳转到/WEB-INFO/jsp/文件夹下的.jdp页面中。这里返回的视图是/student/list,所以项目会跳转到/WEB-INFO/jsp/student/list.jsp页面中。这里要跳转到的页面就是“前缀”+视图+“后缀”,视图解析器中配置的前缀是“/WEB-INFO/jsp”,后缀是“.jsp”,方法返回的视图是"student/list",所以list方法处理了请求后会跳转到/WEB-INFO/jsp/student/list.jsp页面。
四、新建index.jsp页面为:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <% response.sendRedirect("student/list.do"); %> 这里直接进行了重定向,发起/student/list.do请求,根据刚才的介绍知道,list方法处理后会跳转到/WEB-INFO/jsp/student/list.jsp页面。五、在/WEB-INFO/jsp/文件夹下新建student文件夹,并在该文件夹中新建list.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="${pageContext.request.contextPath}/student/preSave.do">添加学生</a> <table> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> </tr> <c:forEach var="student" items="${studentList }"> <tr> <td>${student.id }</td> <td>${student.name }</td> <td>${student.age }</td> </tr> </c:forEach> </table> </body> </html> 这个页面中使用了jstl来显示从后台传递过来的数据,也就是studentList数组中的数据。要想使用jstl技术,首先要在页面的头部添加<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
页面中还有一个“添加学生”的超链接,发送/student/preSave.do请求。
六、运行程序,打开浏览器输入项目的IP地址,进入到index.jsp页面,根据index.jsp的内容最终会跳转到list.jsp页面:
可以看到这里取到了从后台传递过来的学生信息(使用ModelAndView类进行数据传递和页面跳转)。
七、点击添加学生会请求/student/preSave.do,这里在StudentController类中添加处理这个请求的方法为:
@RequestMapping("/preSave") public ModelAndView preSave(){ ModelAndView mav = new ModelAndView(); mav.setViewName("student/add"); return mav; } 这个方法中没有向前台传递数据,只是进行了页面的跳转,执行这个方法后会跳转到/student/add.jsp页面。
八、在student文件夹中新建add.jsp页面为:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="student/save.do" method="post"> <table> <tr> <th colspan="2">学生添加</th> </tr> <tr> <td>姓名</td> <td><input type="text" name="name"/></td> </tr> <tr> <td>年龄</td> <td><input type="text" name="age"/></td> </tr> <tr> <td colspan="2"> <input type="submit" value="提交"/> </td> </tr> </table> </form> </body> </html> 这里就是一个简单的添加表单。
九、重新运行程序,点击添加学生超链接:
这里跳转到了add.jsp页面。
十、上面是一个添加学生的功能,现在写一个修改学生信息的功能,修改list.jsp页面为:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a href="${pageContext.request.contextPath}/student/preSave.do">添加学生</a> <table> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> <th>操作</th> </tr> <c:forEach var="student" items="${studentList }"> <tr> <td>${student.id }</td> <td>${student.name }</td> <td>${student.age }</td> <td><a href="${pageContext.request.contextPath}/student/preSave.do?id=${student.id}">修改</a></td> </tr> </c:forEach> </table> </body> </html> 这里在<table>中添加了操作一列,这一列的内容是修改,点击修改的时候会发送/student/preSave.do请求。上面的添加学生也是发送/student/preSave.do请求,这里不同的是点击修改的时候在发送这个请求的时候携带了参数过去。这里携带的参数是学生的id。既然这里携带了参数,那么StudentController类中的preSave()方法中就要接收这个参数。十一、修改preSave()方法为:
@RequestMapping("/preSave") public ModelAndView preSave(@RequestParam(value="id",required=false) String id){ ModelAndView mav = new ModelAndView(); if(id != null){ mav.addObject("student",studentList.get(Integer.parseInt(id)-1)); mav.setViewName("student/update"); }else{ mav.setViewName("student/add"); } return mav; } 这里要特别注意了。这里preSave()方法中添加了形参String id(形参的名字可以是任意的),对这个形参使用了@RequestParam(value="id",required=false)注解。这个注解中value属性的值一定要和前台携带的参数名称相同,前台发送请求时携带的参数名称是id,这里value属性的值也要是id;注解中required属性的值是false,表示前台传递的这个参数值可有可无。如果required属性的值为true的话表示前台必须传递id的值过来,这时点击添加学生链接时程序会报错,因为添加学生的时候只是发送/student/preSave.do请求,而没有携带参数。所以这里required属性的值必须是false。preSave()方法中根据形参id的值判断当前是修改还是添加操作,如果id不为空,此时是修改操作,项目把要修改的学生信息传递 到update.jsp页面;如果id的值为空(点击添加学生没有携带参数,此时这个形参的值为null),则是添加学生,项目不传递任何数据,直接跳转到add.jsp页面。
重点学习@RequestParam注解的使用方法。
十二、student文件夹下新建update.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="student/save.do" method="post"> <table> <tr> <th colspan="2">学生修改</th> </tr> <tr> <td>姓名</td> <td><input type="text" name="name" value="${student.name }"/></td> </tr> <tr> <td>年龄</td> <td><input type="text" name="age" value="${student.age }"/></td> </tr> <tr> <td colspan="2"> <input type="hidden" name="id" value="${student.id }"/> <input type="submit" value="提交"/> </td> </tr> </table> </form> </body> </html> 这个页面中把后台传递的学生信息显示出来。当点击提交按钮的时候,发送student/save.do请求,这里写了一个隐藏域,发送student/save.do请求的时候携带参数id过去。
十三、重新运行程序,输入工程的默认IP地址,项目跳转到list.jsp页面:
点击修改按钮,项目跳转到update.jsp页面:
这里显示出来要修改的学生信息。
总结一下:这一篇博客中重点讲述了@RequestMapping注解在分模块中的应用,@RequestParam注解在接收请求参数时的用法,以及ModelAndView类在返回模型和视图方面的应用。