1.注解开发的准备工作
(1)导包:
(2)为了加载spring的配置文件
方式1:使用contextConfigLocation来加载spring配置文件:
<?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>springmvc-1</display-name>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
方式2:不使用
contextConfigLocation来加载spring配置文件,采用默认形式,形式为:/WEB-INF/<servlet-name>-servlet.xml
(3)工程目录
2.@RequestMapping注解
场景:使用@RequestMapping注解为控制器指定可以处理哪些URL请求。
使用范例:
springmvc.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:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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/aop
http://www.springframework.org/schema/aop/spring-aop-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="cn.spy"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
编写HelloWorld.java:
@Controller
@RequestMapping("/helloworldClass")
public class HelloWorld {
//使用超链接来跳转
@RequestMapping(value="/helloworldMethod")
public String printHelloWorld(){
System.out.println("Hello World");
return "success";
}
//使用post请求方式来跳转
@RequestMapping(value="/helloworldMethodByPOST",method=RequestMethod.POST)
public String printHelloWorldByPOST(){
System.out.println("Hello World");
return "success";
}
//使用带有通配符的URL跳转
@RequestMapping(value="/*/helloworldMethodByANT")
public String printHelloWorldByANT(){
System.out.println("Hello World");
return "success";
}
}
请求页面index.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>index</title>
</head>
<body>
直接超链接跳转:
<a href="helloworldClass/helloworldMethod">跳转</a>
<br/>
使用post方式请求跳转:
<form action="helloworldClass/helloworldMethodByPOST" method="post">
<input type="submit" value="提交"/>
</form>
<br/>
使用通配符的url跳转:
<a href="helloworldClass/838hdfg8ge8r/helloworldMethodByANT">跳转</a>
</body>
</html>
响应页面success.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>success</title>
</head>
<body>
跳转成功!
</body>
</html>
解释:
(1)@RequestMapping注解都可以定义在哪里?
可以定义在类上,提供了初步的请求映射信息。相对于web应用的根目录。
可以定义在方法上,提供了进一步细化请求映射信息,如果类上未定义此注解,则相当于web应用的根目录。
(2)@RequestMapping注解支持URL中使用通配符?
?:匹配文件名中的一个字符。*:匹配文件名中的任意字符。**:匹配多层路径。
3.@PathVariable注解
场景:这个注解是为了映射URL绑定的占位符,将占位符中参数绑定到控制器中的参数中。
使用范例:
编写控制器:
@RequestMapping("/SpringAnnotation")
@Controller
public class SpringAnnotation {
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable:"+id);
return "success";
}
}
请求页面index.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>index</title>
</head>
<body>
<a href="SpringAnnotation/testPathVariable/1">跳转</a>
</body>
</html>
结果:
4.Restful风格中put请求和delete请求
Restful风格中的CRUD:
增加:/result POST、修改:/result/1 PUT、获取:/result/1 GET、删除:/result/1 DELETE
范例:
web.xml中配置org.springframework.web.filter.HiddenHttpMethodFilter类,可以把post请求转为delete或put。
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
控制器:
@RequestMapping(value="/testRest/{id}",method=RequestMethod.GET)
public String testRest(@PathVariable("id") Integer id){
System.out.println("testRestGet:"+id);
return "success";
}
@RequestMapping(value="/testRest",method=RequestMethod.POST)
public String testRest(){
System.out.println("testRestPost");
return "success";
}
@RequestMapping(value="/testRest/{id}",method=RequestMethod.DELETE)
public String testRestDelete(@PathVariable("id") Integer id){
System.out.println("testRestDelete:"+id);
return "success";
}
@RequestMapping(value="/testRest/{id}",method=RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id){
System.out.println("testRestPut:"+id);
return "success";
}
请求页面:
<!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>index</title>
</head>
<body>
<a href="SpringAnnotation/testRest/1">TestRestGet</a>
<br/><br/>
<form action="SpringAnnotation/testRest" method="post">
<input type="submit" value="TestRestPost"/>
</form>
<br/><br/>
<form action="SpringAnnotation/testRest/1" method="post">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="TestRestDelete"/>
</form>
<br/><br/>
<form action="SpringAnnotation/testRest/1" method="post">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="TestRestPut"/>
</form>
</body>
</html>
如何发送DELETE和PUT请求?
(1). 需要配置 HiddenHttpMethodFilter (2). 需要发送 POST 请求(3). 需要在发送 POST 请求时携带一个 name="_method" 的隐藏域, 值为 DELETE 或 PUT
5.@RequestParam注解
使用这个注解用来映射请求参数。
例程:
控制器:
@RequestMapping("/SpringAnnotation")
@Controller
public class SpringAnnotation {
@RequestMapping(value="/testRequestParam")
public String testRequestParam(@RequestParam(value="username") String un,
@RequestParam(value="age") Integer age){
System.out.println("testRequestParam:"+un+","+age);
return "success";
}
}
请求页面:
<%@ 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>index</title>
</head>
<body>
<a href="SpringAnnotation/testRequestParam?username=sunpy&age=24">testRequestParam</a>
<br/><br/>
</body>
</html>
结果:
6.@RequestHeader注解
场景:映射请求头信息。
范例:
控制器:
@RequestMapping(value="/testRequestHeader")
public String testRequestHeader(@RequestHeader(value="Accept-language") String al){
System.out.println("testRequestHeader:"+al);
return "success";
}
请求页面:
<a href="SpringAnnotation/testRequestHeader">testRequestHeader</a>
<br/><br/>
结果:
7.@CookieValue注解
场景:映射一个cookie值。
范例:
控制器:
@RequestMapping(value="/testCookieValue")
public String testCookieValue(@CookieValue(value="JSESSIONID") String sessionID){
System.out.println("testCookieValue:"+sessionID);
return "success";
}
请求页面:
<a href="SpringAnnotation/testCookieValue">testCookieValue</a>
<br/><br/>
结果:
8.使用pojo对象作为参数传递
场景:在提交表单时,往往会提交多个属性,而这样我们可以使用pojo对象来接收,而不是一个一个接收。
范例:
控制器:
@RequestMapping("/SpringAnnotation")
@Controller
public class SpringAnnotation {
@RequestMapping(value="/testPojo")
public String testPojo(User user){
System.out.println("testPojo:"+user);
return "success";
}
}
请求页面:
<form action="SpringAnnotation/testPojo" method="post">
用户名:<input type="text" name="username"/>
<br/>
价格:<input type="text" name="price"/>
<br/>
省份:<input type="text" name="address.province"/>
<br/>
城市:<input type="text" name="address.city"/>
<br/>
<input type="submit" value="提交"/>
</form>
结果:
------------------------------------------------------
总结:springmvc会按请求参数名和pojo属性名进行自动匹配,自动为该对象填充属性值。毫无疑问支持级联属性。
9.使用原生ServletAPI作为参数
场景:在springmvc中如果,我们想使用HttpServletRequest或者其他原生ServletAPI中的对象都可以使用。
范例:
控制器:
@RequestMapping("/SpringAnnotation")
@Controller
public class SpringAnnotation {
@RequestMapping(value="/testServletAPI")
public String testServletAPI(HttpServletRequest req,HttpServletResponse resp){
System.out.println("testServletAPI:"+req);
System.out.println("testServletAPI:"+resp);
return "success";
}
}
请求页面:
<a href="SpringAnnotation/testServletAPI">testServletAPI</a>
结果:
10.使用ModelAndView进行模型数据的传递
场景:我们可以将对象模型放入到ModelAndView中,然后ModelAndView对象作为方法的返回值(其中包含了视图和对象的信息),然后springmvc会将ModelAndView中的对象信息放入到request域中。
范例:
控制器:
@RequestMapping("/SpringmvcModel")
@Controller
public class SpringmvcModel {
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
ModelAndView modelAndView =new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("time", new Date());
return modelAndView;
}
}
请求页面:
<a href="SpringmvcModel/testModelAndView">TestModelAndView</a>
响应页面:
<%@ 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>success</title>
</head>
<body>
time:${time}
</body>
</html>
结果:
11.使用Map作为模型数据的传递
范例:
控制器:
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map){
map.put("names", Arrays.asList("Tom","Bryant","Allen","Blues"));
return "success";
}
请求页面:
<a href="SpringmvcModel/testMap">TestMap</a>
响应页面:
<%@ 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>success</title>
</head>
<body>
names:${names}
</body>
</html>
结果:
12.@SessionAttribute注解
场景:想将模型对象pojo放到session域中。
范例:
控制器:
@SessionAttributes(value="user")
@RequestMapping("/SpringmvcModel")
@Controller
public class SpringmvcModel {
@RequestMapping("/testSessionAttribute")
public String testSessionAttribute(Map<String,Object> map){
map.put("user", new User("sunpy",120.02,null));
return "success";
}
}
请求页面:
<a href="SpringmvcModel/testSessionAttribute">testSessionAttribute</a>
响应页面:
<%@ 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>success</title>
</head>
<body>
Session User:${sessionScope.user}
</body>
</html>
结果:
注意:@SessionAttribute注解只能注解在类上面。
13.@ModelAttribute注解
场景:如果我们不使用ModelAndView注解,那么如果当我们从数据库获取一条记录时,展示在页面,如果我们此时在展示的页面上想修改其中的字段,而其他的字段不改变,那么就会出现不改变的字段为空,这时使用ModelAttribute注解就会解决该问题。
范例:
控制器:
@RequestMapping("/SpringmvcModel")
@Controller
public class SpringmvcModel {
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false) Integer id,
Map<String ,Object> map){
if(id !=null){
User user =new User(1,"jake","123456",208.09);
System.out.println("从数据库获取user:"+user);
map.put("user", user);
}
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("testModelAttribute:"+user);
return "success";
}
}
请求页面:
<form action="SpringmvcModel/testModelAttribute" method="post">
<input type="hidden" name="id" value="1"/>
username:<input type="text" name="username" value="jake"/><br/>
price:<input type="text" name="price" value="120"/><br/>
<input type="submit" value="提交"/>
</form>
结果:
解释:由ModelAttribute注解的方法在每个方法执行之前,先被springmvc执行。所以虽然我之前没有修改密码,但是控制器依然可以获取到原来的密码。