springMVC基于注解开发
一.springMVC配置文件
DispatcherServlet-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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-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/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!--
Spring MVC主要由DispatcherServlet、
处理器映射【找控制器】、
适配器【调用控制器的方法】、
控制器【业务】、
视图解析器、
视图组成。
-->
<!--如果web.xml中的DispatcherServlet拦截的是 /* 需要在这里设置 对静态资源文件的访问-->
<!--<mvc:resources mapping="/js/*" location="/js/" />-->
<!-- 配置 注解扫描位置 在编写的Controller中添加Controller注解即可-->
<context:component-scan base-package="com.miracle.web.controller"/>
<!-- 如果写了下面这个,那么 处理器映射器,处理器适配器 就可以不用配置 -->
<!--<mvc:annotation-driven/>-->
<!-- 配置 处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<!-- 配置 注解处理器适配器来执行控制器的方法 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!--配置json转换器,告诉springMVC使用jackson来转换数据-->
<property name="messageConverters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</property>
</bean>
<!-- 配置 资源视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/views/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
二.controller编写
1 @RequestMapping 除了可以使用请求URL映射请求外,还可以使用请求方法,请求参数以及请求头映射请求
@RequestMapping的value,method,params以及heads分别表示请求URL,请求方法,请求参数以及请求头的映射条件,他们之间是与的关系,联合使用多个条件可以让请求映射更加精确化。
示例:
// 表示映射url为testMethod路径,接受的方式是post方法
@RequestMapping(value = "/testMethod", method = RequestMethod.POST)
params 和 headers 支持简单的表达式:
param1:表示请求必须包含名为param1的请求参数
!param1:表示请求不能包含名为param1的请求参数
param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1
{"param1=value1", "param2"}:请求必须包含名为param1 和 param2的两个请求参数,且param1参数的值必须为value1
// 表示请求路径是testParamsAndHeaders,必须有username参数,且age参数不为10,请求头必须含有参数Accept-Language
@RequestMapping(value = "/testParamsAndHeaders", params = {"username", "age!=10"}, headers = {"Accept-Language"})
2 @RequestMapping url映射还支持Ant风格的URL
Ant 风格资源地址支持3种匹配符:
- ?:匹配文件名中的一个字符
- *:匹配文件名中的任意字符
- **:**匹配多层路径
示例:
/user/*/createUser:匹配 /user/aaa/creatUser,/user/bbb/createUser 等URL
/user/**/createUser:匹配 /user/createUser,/user/aaa/bbb/createUser 等URL
/user/createUser??:匹配 /user/createUseraa,/user/createUserbb 等URL
3 @PathVariable 获取URL路径参数(使得springMVC支持REST风格)
REST风格介绍
REST:即 Representational State Transfer。资源表现层状态转化。是目前流行的一种互联网软件架构。它结构清晰,符合标准,
易于理解,扩展方便所以正得到越来越多网站的采用
资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本,一张图片,一首歌曲,一种服务,
总之就是一个具体的存在。可以用一个URL(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源(统一资源定位
符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URL就可以,因此URI即为每个资源的独一无二的标识符。
表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层,比如,文本可以用txt格式表现,也可以用HTML格式,
XML格式,JSON格式表现,甚至可以采用二进制格式。
状态转化(State Transfer):,每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有
的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"。二这种转化是建立
在表现成之上的,所以就是"表现成状态转化"。具体说,就是HTTP协议里面,四个表示操作方式的动词:GET,POST,PUT,
DELETE。他们分别对应四种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源
示例:
/order/1 HTTP GET:得到id = 1 的order
/order/1 HTTP DELETE:删除id = 1 的order
/order/1 HTTP PUT:更新id = 1 的order
/order HTTP POST:新增order
HiddenHttpMethodFilter:浏览器form表单只支持GET和POST请求,而DELETE,PUT等method并不支持,
Spring3.0添加了一个过滤器,可以将这些请求转化为标准的http方法,使得支持GET,POST,PUT与DELETE请求
如何发送PUT请求和DELETE请求?
1.在xml中配置HiddenHttpMethodFilter过滤器
2.前端需要发送POST请求是,携带一个name="_method"的隐藏域,值为DELETE 或 PUT
3.在controller中 定义相应的方法,接收对应的请求(GET,POST,PUT,DELETE)
示例:
1.web.xml
<!--配置 org.springframework.web.filter.HiddenHttpMethodFilter
可以把POST请求转为 DELETE 或 PUT 请求,使SpringMVC支持REST风格
-->
<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>
2.前端页面通过提交隐藏域告诉后台请求类型
<br>
<form action="/springmvc/testRest/1.do" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="TestRest PUT">
</form>
<br>
<form action="/springmvc/testRest/1.do" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="TestRest DELETE">
</form>
<br>
<form action="/springmvc/testRest.do" method="post">
<input type="submit" value="TestRest POST">
</form>
<br>
<a href="/springmvc/testRest/1.do">Test Rest Get</a>
<br>
3.controller
package com.miracle.springmvc.handlers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id){
System.out.println("testRestPut" + id);
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", method = RequestMethod.POST)
public String testRestPost(){
System.out.println("testRestPost");
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
public String testRestGet(@PathVariable("id") Integer id){
System.out.println("testRestGet" + id);
return SUCCESS;
}
}
通过注解 @PathVariable 可以将URL中路径参数绑定到控制器方法的参数中
例如
@RequestMapping("testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println(id);
return SUCCESS;
}
UserController
package com.miracle.web.controller;
import com.miracle.model.User;
import com.miracle.model.UserExt;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@SuppressWarnings("all")
@Controller // 声明这个Controller 相当于spring中配置一个bean
@RequestMapping("/user") // 绑定路径1
public class UserController{
/**
* RequestMapping 参数的写法
*
* RequestMapping(“list”)
* RequestMapping(“/list.do”)
* RequestMapping(value=”/list.do”)
* RequestMapping(value = "/list3",method=RequestMethod.POST) 只能使用POST方法访问
* RequestMapping(value = "/list3",method=RequestMethod.Get) 只能使用GET方法访问
*/
@RequestMapping("/list") // 绑定路径2 最终浏览器访问的路径是:绑定路径1 + 绑定路径2
public String list(Model model){ // 参数model用来存储数据返回给页面
List<User> userList = new ArrayList<>();
User user1 = new User("11", "11");
User user2 = new User("22", "22");
User user3 = new User("33", "33");
userList.add(user1);
userList.add(user2);
userList.add(user3);
model.addAttribute("userList", userList);
// 返回的字符串为服务器资源路径(返回字符串还要拼接 资源视图解析器 配置的前缀和后缀)
return "user/userlist";
}
@RequestMapping("/toRegister")
public String toRegister(){
return "user/register";
}
/**
* 第一种接收表单参数的方式
* 在方法中定义参数接收表单提交的数据,要求表单提交的name属性和参数名一致
* @return
*/
@RequestMapping("/register1")
public String register1(String username, String password, String gender, int age, Date birthday, String[] hobbysIds ){
// 在方法中定义参数用来接收前台传入的参数
/*
可以接收get请求 通过?username=aaa,password=bbb
也可以接收post请求的参数
*/
// 当请求是restful风格的url时,如 edit/5
/*
此时要想接收参数
注解的写法 @RequestMapping("/edit/{id}")
方法参数的写法 public String edit(@PathVariable int id){
}
*/
System.out.println(username);
System.out.println(password);
System.out.println(gender);
System.out.println(age);
System.out.println(birthday);
System.out.println(Arrays.toString(hobbysIds));
return "user/info";
}
/**
* 第二种接收表单参数的方式
* 在方法中定义POJO接收表单提交的数据,要求表单提交的name属性和POJO字段名一致
* @return
*/
@RequestMapping("/register2")
public String register2(User user){
System.out.println(user);
return "user/info";
}
/**
* 第三种接收表单参数的方式(JavaBean嵌套JavaBean)
* 在方法中定义POJO接收表单提交的数据,要求表单提交的name属性和POJO字段名一致
* @return
*/
@RequestMapping("/register3")
public String register3(UserExt userExt){
// 这里前端name属性为 user.username user.password
System.out.println(userExt);
return "user/info";
}
/**
* 第四种接收表单参数的方式(用List接收form数据)
* @return
*/
@RequestMapping("/register4")
public String register4(UserExt userExt){
// 这里前端name属性为 user.username user.password
System.out.println(userExt.getUserList());
return "user/info";
}
/**
* 第五种接收表单参数的方式(用map接收form数据)
* @return
*/
@RequestMapping("/register5")
public String register5(UserExt userExt){
// 这里前端name属性为 user.username user.password
System.out.println(userExt.getMap());
return "user/info";
}
/**
* restful风格请求处理 以及 springMVC请求转发,重定向
* @return
*/
@RequestMapping("/edit/{id}")
public String restful(@PathVariable int id, Model model){
System.out.println("id:"+id);
model.addAttribute("id", id);
// 重定向:forward + path
// 请求转发:redirect + path
return "forward:/user/forwardDemo.do";
// return "redirect:/user/redirectDemo.do";
}
@RequestMapping("/forwardDemo")
public String forward(){
return "user/forward";
}
@RequestMapping("/redirectDemo")
public String redirect(){
return "user/redirect";
}
/**
* 对方法参数进行一些说明 RequestParam
* value:参数名称
* defaultValue:默认值
* required:参数是否必须有值,如果为true,参数又为空,会报错
*/
@RequestMapping("/requestParamDemo")
public String requestParamDemo(@RequestParam(value = "id", required = true, defaultValue = "30") int id){
System.out.println(id);
return "user/info";
}
/*
SpringMVC还可以接收请求头参数
通过注解 @RequestHeader
用法同上
*/
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept-Language") String al){
System.out.println(al);
return SUCCESS;
}
}
StudentController
package com.miracle.web.controller;
import com.miracle.model.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@SuppressWarnings("all")
@Controller // 声明这个Controller 相当于spring中配置一个bean
@RequestMapping("/student") // 绑定路径1
public class StudentController {
@RequestMapping("/reg")
public String reg(){
return "student/add";
}
/**
* 接收,返回json数据
* @RequestBody:告诉框架把接收到的json数据转换成JavaBean对象(注意RequestBody后面只能跟javaBean)
* RequestMapping:将对象转换成json字符串返回
* @return
*/
@RequestMapping("/save")
@ResponseBody
public Student save(@RequestBody Student student){
System.out.println(student);
return student;
}
}
4 除了上述接收前端表单的传参,SpringMVC中controller类中的方法可以传入一些ServletAPI
例如:HttpServletRequest,HttpServletResponse,HttpSession等
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request, HttpServletResponse response){
System.out.println(request);
System.out.println(response);
return SUCCESS;
}
5 SpringMVC提供了以下几种途径向前端页面返回数据
- 1.ModelAndView
原理:SpringMVC会把ModelAndView中的mode的数据放到request域对象中,数据在单个请求中有效
controller写法
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
// 构造方法中指定视图名字
ModelAndView modelAndView = new ModelAndView(SUCCESS);
// 添加模型数据到modelAndView中
modelAndView.addObject("time", new Date());
return modelAndView;
}
jsp写法
time:${time}
- 2.在controller方法的参数中添加Map或Model参数
原理:SpringMVC会把Map,Model中的数据放到request域对象中,数据在单个请求中有效
传Map和Model的用法相同
@RequestMapping("/testMapAndModel")
public String testMapAndModel(Model model){
model.addAttribute("names", Arrays.asList("Tom", "Jerry", "Mike"));
return SUCCESS;
}
- 3.使用 @SessionAttributes 注解,将数据放到session域对象中
原理:SpringMVC会把Map,Model中的数据同时放到request和session域对象中,数据在整个session中有效
/*
[email protected]注解只能修饰类
2.value = {"user"} 属性指定了下面模型中哪些key是同时放到request和session中的
3.types = {Date.class} 属性指定了下面模型中哪些value是同时放到request和session中的
*/
@SessionAttributes(value = {"user"},types = {Date.class})
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Model model){
User user = new User("username", "password", "email", "age");
// 通过 @SessionAttributes 注解指定key,将user同时放到request和session域中
model.addAttribute("user", user);
// 通过 @SessionAttributes 注解指定value的类型,将time的值同时放到request和session域中
model.addAttribute("time", new Date());
// 由于没有指定,所以name的值只是方法request域中
model.addAttribute("name", "miracle");
return SUCCESS;
}
}
推荐阅读
-
基于jQuery的弹出框插件开发教程
-
如何基于SpringMVC实现断点续传(HTTP)
-
基于S2SH开发学生考勤管理系统 源码 BL
-
基于S2SH开发车辆租赁管理系统 源码 BL
-
基于Struts2+Hibernate开发小区物业管理系统 源码 B
-
详解基于Spring Cloud几行配置完成单点登录开发
-
基于go语言结合微信小程序开发的微商城系统
-
基于NetCore+SqlSugar+Layui开发出来的开源框架项目FytSoaCms问题处理
-
【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持
-
基于Maya API和PySide2的插件开发(用TextBrowser实现文件信息的显示)