目录
@RequestMapping(value = "/addUser",method = RequestMethod.POST) method:表示该接口接受的请求方式.不设置可以接受任意请求方式。
springmvc
springmvc概念
SpringMVC也叫spring web mvc,是spring内置的一个mvc框架。在spring3.0以后发布。springmvc解决了web开发中、常见的问题(参数接收、文件上传、表单验证等),使用简单,与spring无缝集成。支持restful风格URL请求,采用松散耦合可插拔组件,比其他MVC框架更具有扩展性和灵活性。
springmvc原理
在没有springmvc以前都是使用servlet进行web开发,但是使用servlet进行参数接收、数据共享、页面跳转相对复杂。servlet是java开发web的标准,既然springmvc是对servlet的封装,那么springmvc的底层就是servlet。
springmvc优势
基于mvc架构,功能分工明确。解决了页面代码与后台代码分离。
简单易用,springmvc轻量级,jar包很小。不依赖特定的接口和类就可以开发一个注解的springmvc项目。
作为spring框架的一部分,能够使用spring的IOC和AOP,方便整合Mybatis、Hiberate、JPA等框架。
注解强大易用。
MVC模式
- Model:模型层,javabean负责数据访问和业务处理 dao service pojo
- View:视图层,JSP技术 负责收集和展示数据
- Controller:控制层,servlet技术 中间调度
配置springmvc
1.创建一个meven-web工程
替换web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
2.在pom.xml中引入spring-webmvc依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.15.RELEASE</version>
</dependency>
版本选择中,RELEASE代表稳定版 ,我们就使用稳定版
3.在resources中创建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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://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.ytr"/>
</beans>
4. 包扫描范围是指定包下的所有子包,必须添加,否则springmvc不工作
5.注册DispatcherServlet到web.xml文件上,过滤器作用见下方乱码章节
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置springmvc的前端控制器,对浏览器发送的请求统一处理-->
<servlet>
<!-- 名字随意 -->
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置springmvc配置文件的位置和名称-->
<init-param>
<param-name>contextConfigLocation</param-name>
<!--classpath:表示编译后的路径-->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--将前端控制器DispatcherServlet的初始化时间提前到服务器启动时,可省去,那它初始化时间将为第一次访问时-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!-- 名字与上方名字一致 -->
<servlet-name>DispatcherServlet</servlet-name>
<!-- 设置拦截范围为所有请求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置过滤器-->
<filter>
<!-- 使用spring自己的过滤器-->
<filter-name>encodingfilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 设置编码方式-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
红色框的路径的文件名要与我们第三步创建的文件名一致
创建一个controller类
添加注解,注解所在的包,该注解标记该类为处理层类
写一个业务处理方法,并添加注解:
@RequestMapping,该注解表示把请求路径映射到该方法上。value中的值是访问路径,如果将此注解写在类上,那访问时就需要加上类上的value值和方法上的value值
简单测试
利用上一步创建一个hello.jsp页面
在浏览器地址栏访问,注意:这里的hello11是我们访问路径的hello11,不是hello.jsp。他会进入我们的方法,然后再转发到hello.jsp页面。注意是转发,虽然已经显示了hello.jsp页面的内容,但路径还是hello11。
如何在controller接受请求的参数
接受少量的参数。
只需要给定方法的参数,参数必须和请求的参数名称一致。这样可以直接取到,不用再用get的方法取出了。
接受大量的参数
例如接收表单,我们可封装一个实体类来接受大量参数,实体类名字要与提交的名字一致。要不然取不到。 提交的路径要与方法路径一致。
乱码问题
我们在接受中文的时候会产生乱码,解决方式两种,我们自己定义一个过滤器,或者使用springMVC提供的过滤器。
1.使用springMVC的过滤器
在web.xml文件中配置过滤器,见上方如何创建第五步
springMVC给我们提供的过滤器
文件配置
2.自己写一个过滤器
接受的参数为日期
我们想让接受的字符串为日期型,或直接接收的数据为日期型,那需要特殊处理。
日期型参数需要在时间类型的属性上添加一个注解:@DateTimeFormat(pattern = "yyyy-MM-dd")
在springmvc配置文件上开启注解驱动,注意:一定要以mvc结尾的包才对。
处理静态资源
由于我们的是设置,springmvc的前端控制器DispatcherSerlvet会把静态资源拦截。我们需要手动放行静态资源。在springmvc.xml文件添加
<mvc:default-servlet-handler/>
回显数据
第一种
Model 对象,生命周期同 request
用法
前端接收数据
第二种
将其转换为 session 对象延长生命周期,写在最头部
@SessionAttributes(value = {"l2","","".....})
用法:
前端接收:
第三种
使用 HttpSession,这是Tomcat的方法, 使用此方法表示与tomcat服务器绑定,只能部署在tomcat服务器上。
用法
前端接收
重定向页面
redirect:
用法
返回json数据
Ajax异步请求时需要返回json数据,springMVC自带json转换工具
在pom.xml包添加依赖
添加注解
@ResponseBody
全局异常处理
先创建一个异常处理类,并添加注解@ControllerAdvice,
该注解告诉springMVC本类为异常处理类
创建方法添加注解@ExceptionHandler,该注解指定发生何种异常时执行该方法
也能让他返回json对象
拦截器
创建拦截器类必须实现接口 HandlerInterceptor
将拦截器注册到springmvc.xml配置文件
<!--拦截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--mapping:哪些路径需要经过拦截器
/**: 表示n层路径
/*:表示一层路径
-->
<mvc:mapping path="/**"/>
<!--exclude-mapping:设置不经过该拦截的路径-->
<mvc:exclude-mapping path="/list2"/>
<mvc:exclude-mapping path="/list3"/>
<!--bean表示你自定义的拦截器类路径-->
<bean class="com.ytr.interceptor.Myinterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
文件上传
上传到本地服务器
1.加载依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency>
2.在springmvc中配置文件上传解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> </bean>
用表单提交文件
method: 提交方式 文件上传必须为post提交。
enctype:默认application/x-www-form-urlencoded 表示提交表单数据
multipart/form-data:可以包含文件数据
input的类型必须为file类型,而且必须有name属性
创建upload01接口方法
@Controller public class Upflle { @RequestMapping("/file01") //MultipartFile后面的名字一定要和表单里file提交的name一致。 public String upfileByFrom(MultipartFile myfile, HttpServletRequest request) throws IOException { // 获取保存的文件路径 String path = request.getSession().getServletContext().getRealPath("uploadimg"); // 将路径存到文件 File file = new File(path); //判断文件路径是否存在,不存在创建 if(!file.exists()){ file.mkdirs(); } // 生成随机字符串文件名加上原有名字 String filename = UUID.randomUUID().toString().replace("-","")+myfile.getOriginalFilename(); // 在这里吧存储路径和随机文件名拼成一个完整路径,想当于有了个保存文件的壳子。 //可以把不恰当的认为文件名是个壳子,文件名对应图片,我们新生成一个文件名,将原文件名弃用,把原文件名里的图片取出来放到新文件名内。 File tage = new File(path+"/"+filename); // 这里把传入的文件放入新壳子里。 myfile.transferTo(tage); return ""; } }
elementui+vue+axios完成文件上传
前端页面
<html>
<head>
<title>Title</title>
<link rel="stylesheet" href="css/index.css">
<script src="jquery/qs.min.js"></script>
<script src="jquery/vue.js"></script>
<script src="jquery/index.js"></script>
<script src="jquery/axios.min.js"></script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
</head>
<body>
<div id="mydiv">
<el-upload
class="avatar-uploader"
<%-- 后台对应的@RequestMapping("/elfilt")里的路径--%>
action="/elfilt"
:show-file-list="false"
<%-- 上传成功调用的函数--%>
:on-success="handleAvatarSuccess"
<%-- 上传之前调用的函数--%>
:before-upload="beforeAvatarUpload">
<%-- :src 上传成功将图片显示--%>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
<script>
var vue = new Vue({
el:"#mydiv",
data:{
imageUrl:''
},
methods:{
handleAvatarSuccess(res) {
this.imageUrl = res.data
},
beforeAvatarUpload(file) {
// 规定上传的图片的后缀名
const isJPG = file.type === 'image/jpeg';
// 规定上传的图片的大小
const isLt2M = file.size / 1024 / 1024 < 6;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
},
}
});
</script>
</body>
</html>
后台处理代码
@RequestMapping("/elfilt")
@ResponseBody
//elementui 默认传输name为file,这里一定要保持一致。
public CommonResult upfiltByElementFile(MultipartFile file, HttpServletRequest request){
//获取文件路径
try {
String path = request.getSession().getServletContext().getRealPath("uploadimg");
// 放入文件对象
File file1 = new File(path);
// 判断路径存在
if(file1.exists()){
file1.mkdirs();
}
// 随机生成文件名
String filename = UUID.randomUUID().toString().replace("-","")+file.getOriginalFilename();
// 文件拼接成完整文件
File tran = new File(path+"/"+filename);
file.transferTo(tran);
// 返回图片存储在服务器的路径
return new CommonResult(2000,"ok","http://localhost:8080/uploadimg/"+filename);
} catch (IOException e) {
e.printStackTrace();
}
return new CommonResult(5000,"no",null);
}
上传文件到云端(oss)
添加依赖
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency>
创建业务处理类
public static String alioss(MultipartFile file){
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
String accessKeyId = "";
String accessKeySecret = "";
// 填写Bucket名称,例如examplebucket。
String bucketName = "ytr-oos";
// 获取年月日
String riqi = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
System.out.println(riqi);
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "images/"+riqi+"/"+ UUID.randomUUID().toString().replace("-","")+file.getOriginalFilename();
// 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
InputStream inputStream = file.getInputStream();
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, inputStream);
}catch (Exception e) {
e.printStackTrace();
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
String imgUrl = "https://"+bucketName+"."+endpoint+"/"+objectName;
System.out.println(imgUrl);
return imgUrl;
}
调用
@RestController
public class ElemOos {
@RequestMapping("/eloos")
public Common eloos(MultipartFile file){
try {
String avatar = OssUitl.alioss(file);
return new Common(2000,"🆗",avatar);
} catch (Exception e) {
e.printStackTrace();
}
return new Common(5000,"no",null);
}
注解
@ControllerAdvice
- 全局异常处理
- 全局数据绑定
- 全局数据预处理
@SessionAttributes
将Request中的数据绑定到session中
@ResponseBody
支持将返回值放到response内,把响应的java对象转换为json对数据。从后端到前端
@RequestBody
把请求的json数据转换为java对象。从前端到后端
@ExceptionHandler
用于全局处理控制器里的异常。
@Controller
将当前类标记为控制层组件
@Component
将当前类标记为普通组件
@Service
将当前类标记为业务层组件
@Repository
将当前类标记持久层组件
@RequestMapping
把请求路径映射到响应的方法上。
属性
通过请求地址匹配请求映射(必须设置)
value="",一个
values={"",""},多个
通过请求的请求方式匹配映射
method={RequestMethod.GET,[RequestMethod.POST]}
所有可用参数
但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理
通过请求的请求参数匹配请求映射
param=""
param={"",""}
param="name=aaa" 参数必须携带name并且name必须为aaa
param="name!=aaa"
param="name" 参数必须携带name
param!="name"
"param":要求请求映射所匹配的请求必须携带param请求参数
"!param":要求请求映射所匹配的请求必须不能携带param请求参数
"param=value":要求请求映射所匹配的请求必须携带param请求参数且param=value
"paraml=value":要求请求映射所匹配的请求必须携带param请求参数但param!=value
headers
通过请求的请求头参数匹配请求映射
作用和用法同param
RequestMapping派生注解
(目前浏览器只支持get和post)
@GetMapping
请求方式必须为Get
@PostMapping
请求方式必须为Post
@PutMapping
请求方式必须为Put
@DeleteMapping
请求方式必须为Delete
@RestController
等价于 @COntroller+@ResponseBody该注解下所有的方法都是返回json数据
@RequestParam(value = "u")
设置你接受的请求参数名。查询参数,作用同上方param