前言:
小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。
这个SpringMVC基础学习系列是用来记录我学习SpringMVC框架基础知识的全过程 (这个系列是参照B站狂神的SpringMVC最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)
之后我将尽量以两天一更的速度更新这个系列,还没有学习SpringMVC框架的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。最后,希望能够和大家一同进步吧,加油吧,编程人!
特别提醒:如果对SpringMVC基础学习系列感兴趣,可以阅读本系列往期博客:
第一篇:SpringMVC基础学习之简单回顾MVC架构和Servlet的使用
第二篇:SpringMVC基础学习之初识SpringMVC
第三篇:SpringMVC基础学习之初识
第四篇:SpringMVC基础学习之使用注解开发
第五篇:SpringMVC基础学习之Controller的两种实现方式和RequstMapping注解的使用
今天我们来到了SpringMVC基础学习的第六站:Restful风格的简单使用 。废话不多说,让我们开始今天的学习内容吧。
在SpringMVC中实现RestFul风格之前,首先我们需要了解一下什么是RestFul风格以及RestFul风格的主要功能是什么?
Restful就是一个==资源定位及资源操作的风格==,不是标准也不是协议,只是一种风格;基于这个风格设计的软件可更加简洁,更有层次,更易于实现缓存等机制。
主要用于实现资源操作 (互联网所有的事物都可以被抽象为资源),即使用不同方法对资源进行操作。例如使用的请求方式为POST、DELETE、PUT和GET,分别对应添加、删除、修改和查询操作
在了解了RestFul风格的基本概念后,我们再来对比一下使用传统方式和RestFul风格来操作资源的区别
传统方式操作资源:通过不同的参数来实现不同的效果,方法单一,例如使用post和get请求
使用RestFul操作资源:可以通过不同的请求方式来实现不同的效果!
如下,请求地址一样,但功能可以不同!
在了解了RestFul风格的基本概念后,我们开始学习ResultFul风格的具体使用
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
/**
* 使用默认方式的进行访问
* 使用@RequestMapping注解, 设置请求映射的访问路径
* 其真实访问路径为: http://localhost:8888/add?a=1&b=2
*/
@RequestMapping("/add")
public String test(int a, int b, Model model) {
// 设置一个结果
int result = a + b;
// 封装数据: 向模型中添加属性msg与其值,进行视图渲染
model.addAttribute("msg","结果为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
结果:访问页面失败,报HTTP状态500错误!
分析:
由于我们并未传递参数给后端,因此无法访问页面和得出结果
结果:访问页面成功,并且在页面中显示结果!
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
/**
* 使用RestFul风格进行访问
* 使用@RequestMapping注解, 设置请求映射的访问路径
* 其真实访问路径为: http://localhost:8888/add/a/b
* 而使用默认方式的访问路径则为:http://localhost:8888/add?a=1&b=2
*/
@RequestMapping("/add/{a}/{b}")
// 使用@PathVariable注解,让方法参数的值对应绑定到一个URL模板变量上
public String test(@PathVariable int a, @PathVariable int b, Model model) {
// 设置一个结果
int result = a + b;
// 封装数据: 向模型中添加属性msg与其值,进行视图渲染
model.addAttribute("msg","结果为"+result);
// 返回视图逻辑名,交由视图解析器进行处理
return "user/hello";
}
}
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
/**
* 使用@RequestMapping注解, 设置映射请求路径
* 使用"{}"将参数a和b括起来, 参数之间使用"/"分开
*/
@RequestMapping("/add/{a}/{b}")
// 使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test2(@PathVariable String a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
/**
* 使用@RequestMapping注解, 设置映射请求路径
* 使用{}将参数a和b括起来, 参数之间使用/分开
*/
@RequestMapping("/add/{a}/{b}")
// 使用@PathVariable注解,将方法值对应绑定到URL的模板变量上
public String test3(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
//封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果为"+result);
// 返回视图逻辑名,交由视图解析器进行处理
return "user/hello";
}
}
结果:访问页面成功,显示两个整数和的结果!
结果:访问页面成功,显示两字符串拼接的结果!
结果:访问页面成功,显示一个整数和字符串拼接的结果!
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* 该注解用于将web请求映射到具有灵活方法签名的请求处理类中的方法
*
* 注意: 该注解可以使用在类和方法级别上.
* 在大多数情况, 在方法级别, 应用程序更喜欢使用特定于HTTP方法的变体之一:
* @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping.
*
* 注意: 若使用controller(控制器)接口(例如AOP动态代理), 确保持你所有的映射注解都是一致的:
* 例如 @RequestMapping(请求映射)和@SessionAttributes(会话属性)在控制器接口上, 而不是实现类上
*
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5
* @see GetMapping
* @see PostMapping
* @see PutMapping
* @see DeleteMapping
* @see PatchMapping
*/
// 使用@Target注解, 设置作用目标, 元素类型为类和方法上
@Target({ElementType.TYPE, ElementType.METHOD})
// 使用@Retention注解, 设置保留政策为运行时策略
@Retention(RetentionPolicy.RUNTIME)
// 使用@Documented注解, 该注解将由javadoc和类型工具记录, 并且成为注解元素公共API的一部分
@Documented
// 使用@Mapping注解, 表示该注解为Web映射注解
@Mapping
public @interface RequestMapping {
/**
* 主要作用: 给这个映射分配一个名字, 它支持在类级别和方法级别使用
* 若使用两种级别, 派生的组合名将使用"#"分隔符连接
* @see org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder(Mvc的Uri组件构筑器)
* @see org.springframework.web.servlet.handler.HandlerMethodMappingNamingStrategy(处理器方法映射命名策略)
*/
String name() default "";
/**
* 主映射由该注解表达, 这是path(路径)的别名, 同样支持类级别和方法级别
* 例如, 使用@RequestMapping("/foo")等同于@RequestMapping(path="/foo")
* 若使用类级别, 所有的方法级别映射包含该主映射, 为特定的处理器方法缩小范围
* 注意: 若一个处理器方法没有显式映射到任何路径, 它将被有效地映射到一个空路径
*/
@AliasFor("path")
String[] value() default {};
/**
* 路径映射URI(例如"/profile"), 也支持"Ant-style"路径格式(例如"/profile/**")
* 在方法级别, 在类级别表示的主映射中支持相对路径(例如"edit"), 路径映射URIs包含占位符(例如"/${profile_path}"), 支持类级别和方法级别
* 若使用类级别, 所有的方法级别映射包含该主映射, 为指定的处理器方法缩小范围
* 注意: 若一个处理器方法没有显式映射到任何路径, 它将被有效地映射到一个空路径
* @since 4.2
*/
@AliasFor("value")
String[] path() default {};
/**
* HTTP请求要方法映射到的方法, 缩小主映射:
* GET(查询), POST(增加), HEAD, OPTIONS, PUT(修改), PATCH, DELETE(删除), TRACE
* 支持在类型级别和方法级别使用
* 若使用类型级别, 所有的方法级别映射包含这个HTTP方法限制
*/
RequestMethod[] method() default {};
/**
* 映射请求的参数, 缩小主映射范围
*/
String[] params() default {};
/**
* 映射请求的头部, 缩小主映射范围
* @see org.springframework.http.MediaType(媒介类型)
*/
String[] headers() default {};
/**
* 根据映射处理程序可以使用的媒体类型缩小主映射
* 由一个或者多个媒介类型组成, 其中一个必须与请求"Content-Type"(内容类型)头相匹配
* @see org.springframework.http.MediaType(媒介类型)
* @see javax.servlet.http.HttpServletRequest(HttpServlet的请求)#getContentType()(获取内容类型)
*/
String[] consumes() default {};
/**
* 通过映射处理器可以生成媒介类型来缩小主映射.
* 由一个或多个媒介类型组成, 必须根据请求的"可接受"媒介类型通过内容协商选择其中之一
* @see org.springframework.http.MediaType(媒介类型)
*/
String[] produces() default {};
}
package org.springframework.web.bind.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该元注解表示一个Web映射注解
*
* @author Juergen Hoeller
* @since 3.0
* @see RequestMapping
*/
// 使用@Target注解, 设置作用目标, 元素类型为注解类型
@Target({ElementType.ANNOTATION_TYPE})
// 使用@Target注解, 设置保留策略为运行时策略
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {
}
package org.springframework.web.bind.annotation;
// 枚举类RequestMethod(请求方法)
public enum RequestMethod {
GET, // get请求(对应查询操作)
HEAD, // 请求头
POST, // post请求(对应增加操作)
PUT, // put请求(对应修改操作)
PATCH,
DELETE, // delete请求(对应删除操作)
OPTIONS,
TRACE;
private RequestMethod() {
}
}
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@RequestMapping注解, 设置映射请求路径
@RequestMapping(name = "/add/{a}/{b}",method = RequestMethod.GET)
// 使用@PathVariable注解, 将方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@RequestMapping注解, 设置映射请求路径 (默认使用GET请求方式)
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
// 使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值,进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@RequestMapping注解设置映射请求路径 (默认使用GET请求方式)
@RequestMapping(path = "/add/{a}/{b}",method = RequestMethod.GET)
// 使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据:向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
结果:访问失败,HTTP状态404找不到!
方法级别的注解变体有如下几个组合注解
@GetMapping:对应get请求, 查询操作
@PostMapping:对应post请求, 添加操作
@PutMapping:对应put请求,修改操作
@DeleteMapping:对应delete请求,删除操作
@PatchMapping:对应patct请求,多条数据修改和删除操作
@GetMapping是一个组合注解,相当于@RequstMapping(method=ReustMethod.GET),平常使用的会比较多
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@PostMapping注解, 设置映射请求路径, 请求方式为post请求
@PostMapping("/add/{a}/{b}")
// 使用@PathVariable注解,让方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值,进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名,交由视图解析器进行处理
return "user/hello";
}
}
结果:访问失败,HTTP状态405方法不允许!
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
/**
* 使用@GetMapping注解, 设置映射请求路径, 请求方式为get
* 其真实访问路径为: http://localhost:8888/add/123/hello
*/
@GetMapping("/add/{a}/{b}")
//使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test5(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果2为"+result);
// 返回视图逻辑名, 交由视图解析器进行处理
return "user/hello";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%-- 直接在action中设置a和b的参数值
注意from.jsp页面要放在web文件夹下 --%>
结果:访问成功,并且显示整数和字符串的拼接结果"123hello"!
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@RequestMapping注解, 设置映射请求路径, 请求方式为get类型, 这里推荐使用使用value属性
@RequestMapping(value= "/add/{a}/{b}",method = RequestMethod.GET)
// 使用@PathVariable注解,让方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值,进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名,让视图解析器进行处理
return "user/hello";
}
// 使用@GetMapping注解, 设置映射请求路径, 请求方式为get类型
@GetMapping("/add/{a}/{b}")
// 使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test5(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果2为"+result);
// 返回视图逻辑名,让视图解析器进行处理
return "user/hello";
}
}
结果:报错:Ambiguous mapping. Cannot map restfulController’ method,即RestfulController类中存在模棱两可的映射
由于RequestMapping使用的请求方法就是GET类型,同时使用@GetMapping相当于定义了两次,因此RestfulController出现模棱两可的映射!
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@RequestMapping注解, 设置映射请求路径, 请求方式为get类型, 推荐使用value属性
@RequestMapping(value= "/add/{a}/{b}",method = RequestMethod.GET)
// 使用@PathVariable注解, 将方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b, Model model) {
// 设置一个结果
String result = a + b;
// 封装数据:向模型中添加属性msg与值,进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名,交由视图解析器进行处理
return "user/hello";
}
// 使用@PostMapping注解, 设置映射请求路径, 请求方式为get类型
@PostMapping("/add/{a}/{b}")
// 使用@PathVariable注解,让方法值对应绑定到URL模板变量上
public String test5(@PathVariable int a, @PathVariable String b, Model model) {
// 设置一个结果
String result = a + b;
// 封装数据:向模型中添加属性msg与值,进行视图渲染
model.addAttribute("msg","结果2为"+result);
// 返回视图逻辑名,让视图解析器进行处理
return "user/hello";
}
}
结果:访问成功,并且显示整数和字符串的拼接结果"123hellospring"!
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
// 使用@Controller注解, 将该类注册为Controller层, 交由Spring的IOC容器统一管理
@Controller
public class RestfulController {
// 使用@PostMapping注解, 设置映射请求路径, 请求方式为post类型
@PostMapping("/add/{a}/{b}")
// 使用@PathVariable注解,让方法值对应绑定到URL模板变量上
public String test4(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据:向模型中添加属性msg与值,进行视图渲染
model.addAttribute("msg","结果1为"+result);
// 返回视图逻辑名,让视图解析器进行处理
return "user/hello";
}
// 使用@GetMapping注解, 设置映射请求路径, 请求方式为get类型
@GetMapping("/add/{a}/{b}")
// 使用@PathVariable注解,将方法值对应绑定到URL模板变量上
public String test5(@PathVariable int a, @PathVariable String b,Model model) {
// 设置一个结果
String result = a + b;
// 封装数据: 向模型中添加属性msg与其值, 进行视图渲染
model.addAttribute("msg","结果2为"+result);
// 返回视图逻辑名,交由视图解析器进行处理
return "user/hello";
}
}
结果:访问成功,并且显示整数和字符串的拼接结果"123hellospringmvc"!
好了,今天的有关 Restful风格的简单使用 的学习就到此结束啦。欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连。我们下期见,拜拜啦!
参考视频链接:【狂神说Java】SpringMVC最新教程IDEA版通俗易懂