Spring MVC
- SpringMVC 概述
① Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一。
② Spring3.0 后全面超越 Struts2,成为最优秀的 MVC 框架。
③ Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
④ 支持 REST 风格的 URL 请求。
⑤ 采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
Spring框架结构图(新版本):
1.新建第一个SpringMVC_Helloworld程序
第一步 导包 SpringMVC是Spring的web波快 所有模块的运行都是依赖核心模块(IOC)
我的第一个MVC项目
1.新建一个jsp页面 发送一个 hello请求
2.配置WEB.xml配置文件
3.在自己创建的Spring 配置文件中开启组件扫描
4.新建一个类处理请求并跳转到success.jsp页面
package com.ycx;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
//告诉Spring MVC这是一个处理器 可以处理请求
@Controller
public class MyFirstController {
// /代表从当前形目下开始 处理当前项目下的hello请求
@RequestMapping("/hello")
public String firstRequest(){
System.out.println("成功了");
return "/WEB-INF/pages/Success.jsp";
}
}
这样写 return “/WEB-INF/pages/Success.jsp”; 转到新页面还不是很简单 我们可以 在Spring配置文件里配置一个视图解析器 自动识别前缀后缀地址
这样方便多了
HelloWord 细节
运行 流程:
1.客户端点击链接会发送请求
2.来到tomcat服务器
3.SpringMVC前端控制器收到所有请求
4.来看请求地址和@RequestMapping 标注的那个匹配,来找到底使用哪个类的哪个方法来处理
5. 前段控制器找到了目标处理类和目标方法 直接利用反射执行目标方法
6. 方法执行完以后会有一个返回值,SpringMVC认为这个返回值就是要去的页面地址
7. 拿到方法返回值以后,用视图解析器进行拼串得到完整的页面地址
8. 拿到页面地址前端控制器会帮我们转发到页面。
@RequestMapping
作用 :告诉SpringMVC 这个方法来处理什么请 其中/ 可以省略 习惯加上比较好
如果不指定配置文件位置
如果不指定和配置文件位置 会默认去找一个文件/WEB-INF/xxx 其中 xxx 是你xml中起的名
想要运行成功可以在web应用的/WEB-INF 目录下创建一个名叫xxx-servlet的xml文件
注意 一个方法只能处理一个请求
@RequestMapping
在控制器的类定义及方法定义处都可标注 @RequestMapping
标记在类上:提供初步的请求映射信息。相对于 WEB 应用的根目录
标记在方法上:提供进一步的细分映射信息。相对于标记在类上的 URL。
例如 只标记在类上实现 hello请求 这时候 的请求地址
若在类上加上
@RequestMapping(/haha) 则此时的地址为
@RequestMapping 的其他属性
上面的 属性都是默认value 的属性
1.method : 限定请求方式 GET POST
如果不是规定的请求方式就会报错
2.params : 规定请求参数
表示请求必须带上一个叫username的参数 没带的就会404报错
params={“username=123”} 表示请求必须包含名为username并且值为123的请求参数
param1: 表示请求必须包含名为 param1 的请求参数
!param1: 表示请求不能包含名为 param1 的请求参数
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
{“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
3.headers 规定请求头,也和params也可以写简单的请求头
**4.consumes ** 只接受内容类型是哪种的请求,规定请求头中的Content-Type
5.produces 告诉浏览器返回的内容类型是什么,给响应头中加上Context-Type:text/html;charset=utf-8
@RequestMapping的模糊匹配
有多个匹配上的请求 精确优先
url地址可以写模糊的通配符
@RequestMapping(/hello) 匹配 hello
@RequestMapping(/hello?) 可以匹配 hello1 hello2 … hello后面只能由一个字符
@RequestMapping(/hello*) 可以匹配 hello1 hello11 hello111 … hello后面任意字符都可以
? 替代任意一个字符
星号 能替代任意多个字符,和一层路径
双星号 能替代多层路径
路径上可以有占位符:占位符语法就是可以在任意路径的地方写一个{ 变量名}
@RequestMapping("/user/{id}")
public String ABC(@PathVariable("id")String id){
System.out.println("路径上的占位符的值"+id);
return "success";
Rest风格 四种请求替换原来的起名 :
系统希望以非常简洁的URL地址来发请求 怎样表示对一个资源的增删改查用请求方式区分**
以前操作
/getbook?id=1 表示查询图书 /deleteBook?id=1 表示删除图书。。。。。
用Rest风格后
/资源名/资源标识符
/book/1 :发送GET请求表示查询图书
/book/1 :发送PUT请求 表示更新一号图书
/book/1 发送DELETE 表示删除一号图书
/book/2 发送PUST请求 表示添加2号图书
问题 : 从页面只能发 PUST 和 GET请求 其他请求没法使用
使用Rest来构建一个增删改查方法
从页面发起 put 和delete 请求
1.SpringMVC中有一个Filter,他可以把普通的请求转化为规定形式的请求 配置这个filter 在web.xml中配置
<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.如何发送其他形式请求?
1.创建一个post类型的表单 2 表单项中携带一个_method的参数 3.这个_method的值就是Delete Put
tomcat 7之前的版本可用
tomcat 及以上版本需要在跳转的那个页面上头部加上
服务器代码如下
package com.ycx;
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;
@Controller
public class BookController {
@RequestMapping(value="/book/*",method=RequestMethod.POST)
public String addBook(){
System.out.println("添加成功");
return "success";
}
@RequestMapping(value="/book/{bid}",method=RequestMethod.DELETE)
public String deleteBook(@PathVariable("bid")Integer id){
System.out.println("删除了"+id+"图书");
return "success";
}
@RequestMapping(value ="/book/{bid}",method=RequestMethod.PUT)
public String updateBook(@PathVariable("bid")Integer id){
System.out.println("更新了"+id+"图书");
return "success";
}
@RequestMapping(value="/book/{bid}",method=RequestMethod.GET)
public String getBook(@PathVariable("bid")Integer id ){
System.out.println("查询到了"+id+"图书");
return "success";
}
}
web.xml中代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>SpringMVC3</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<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>
</web-app>
springmvc-servlet中代码
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描所有组件 -->
<context:component-scan base-package="com.ycx"></context:component-scan>
<!-- 配置一个视图解析器,能帮我们拼接页面地址 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
获取请求参数
SpringMVC如何获取请求带来的各种信息
默认方式获取请求参数 :
直接给方法写一个和请求参数名相同的变量,这个变量就来接收请求参数的值
@RequestParam 获取请求参数 用了这个注解后默认参数是必须的带的不然报400异常
注解中有 value ()
required() 是否是必须的 boolean 类型 如果为false的话 就可以不带参数传入了
defaultValue() 默认值
@RequestHeader 获取请求头中的某个值 @RequestHeader(" ")String xxx 如果请求头中没有这个值就会报错
@CookieValue 获取某个cookie
解决获取参数乱码问题!!!!
在web.xml配置文件中加上字符过滤器 一定要在其它过滤器之前!!!!!!!!!!!!!!!!!!
<!-- 字符过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<!-- encoding 指定解决POST请求乱码-->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<!-- forceEncoding 顺手解决相应乱码-->
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果我们的请求参数是一个POJO SpringMVC会自动的为这个POJO进行赋值
将POJO中每一个属性 从request参数中尝试获取出来 并封装即可 还可以级联封装(属性的属性)
处理这个请求 我们可以建一个类 属性和这个表单的属性一一对应
package com.ycx;
public class Book {
private String bookName;
private String author;
private Double price;
private Integer stock;
private Integer sales;
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public Integer getSales() {
return sales;
}
public void setSales(Integer sales) {
this.sales = sales;
}
@Override
public String toString() {
return "Book [bookName=" + bookName + ", author=" + author + ", price=" + price + ", stock=" + stock + ", sales="
+ sales + "]";
}
public Book(String bookName, String author, Double price, Integer stock, Integer sales) {
super();
this.bookName = bookName;
this.author = author;
this.price = price;
this.stock = stock;
this.sales = sales;
}
public Book() {
super();
}
}
然后接收处理请求的时候可以直接把这个类当作参数 这样spring会自动找类中的属性一一对应
其次我们还可以进行级联赋值 假如我们还需要作者的地址信息 而作者的地址信息在另一个Address类中 这时候我们可以这样写(都需要有get set 方法)
结果
SpringMVC可以直接在参数上写原生API
MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale 国际化有关的区域信息对象
- InputStream
- OutputStream
- Reader
- Writer
举例
@RequestMapping("/handle03")
public String handle03(HttpSession session,HttpServletRequest req){
req.setAttribute("requestParam", "我是request域中的");
session.setAttribute("sessionParam", "我是session域中的");
return "Success";
}