springmvc
Posted xue_yun_xiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springmvc相关的知识,希望对你有一定的参考价值。
一、跨域请求
域:由ip/域名:端口组成,就是提供一个网络服务
localhost:8080 一个域
127.0.0.1:8080 一个域
10.8.163.53:8080 一个域
localhost:8085 一个域
以上都不是同一个域
什么是跨域请求?
就是在一个域下的服务/网页 通过Ajax等工具访问 另外一个 域下的请求 就是跨域,tomcat服务器为了保证安全,默认情况下不允许跨域请求
第一步:在loalhost:8080 创建服务,允许跨域
/**
* 跨域请求
*/
@RestController
@CrossOrigin(origins = "http://localhost:8085") //允许另外一个域对应的网页中ajax 访问 注意最后不要加
// /标记在类上 表明当类下所有的处理器都允许 http://localhost:8085下 的界面发起跨域请求
public class CrossOriginController {
@RequestMapping("/findStudentById")
public Student findStudentById(int id){
Student student = new Student();
student.setSex("F");
student.setId(id);
student.setName("XXX");
return student;
}
}
第二步:另一域中 localhost:8085 创建html 发起跨域请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/js/jquery-3.3.1.js"></script>
</head>
<body>
<button onclick="getStudentById()">获取学生 id=1</button>
<script>
/*
* 此时 $.ajax 请求 和 当前 html/crossorgin.html 处于同一域下
* http://localhost:8080/findStudentById?id=1 html/crossorgin.html 处于同一域下
*
*
*
* */
function getStudentById(){
$.ajax({
url:"http://localhost:8080/findStudentById?id=1",
type:'get',//
success:function (data) {
alert(data)
},
error:function () {
alert("服务器错误")
},
dataType:'json'
})
}
</script>
</body>
</html>
二、文件上传下载
文件上传
使用表单上传
多数文件上传都是通过表单形式提交给后台服务器的,因此,要实现文件上传功能,就需要提供一个文件上传的表单,而该表单必须满足以下3个条件:
-form表单的method属性设置为post;
-form表单的enctype属性设置为multipart/form-data;
-提供的文件上传输入框。
<!--
上传文件
1.method="post"
2.enctype="multipart/form-data"
3.<input type="file" name="file">
-->
<form action="/xx" method="post" enctype="multipart/form-data">
文件名:<input type="text" name="filename"><br>
文件:<input type="file" name="file">
<input type="submit" value="上传">
</form>
处理器接收文件
当form表单的enctype属性为multipart/form-data时,浏览器就会采用二进制流来处理表单数据,服务器端就会对文件上传的请求进行解析处理。Spring MVC通过MultipartResolver实现文件上传功能。MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver来完成文件上传工作。
1、导入依赖
<!--文件上传依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
2、在springmvc-servlet.xml 添加
<!--
配置文件大小 字节 <property name="maxUploadSize" value="1024000000"></property>
编码格式 <property name="defaultEncoding" value="utf-8"></property>
id 必须为 multipartResolver
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="1024000000"></property>
</bean>
3、接收文件
/**
* 接收文件
*
* List<MultipartFile> file 对应 form <input type="file" name="file">
* @param filename
* @param file
* @return
*/
@RequestMapping("/fileUpload")
@ResponseBody // 返回json 字符串
public String fileUpload(String filename, List<MultipartFile> files) throws IOException {
System.out.println("filename = " + filename);
if (files==null || files.size()==0){
return "error";
}
for (MultipartFile multipartFile:files){
File rootFile = new File("c:/java2102");
if (!rootFile.exists()){// 如果文件不存在
rootFile.mkdirs(); // 创建文件夹
}
// 得到文件上传的名字
String realName = multipartFile.getOriginalFilename();
// UUID.randomUUID().toString() 唯一字符串 防止文件 被覆盖
// File.separator /
File file = new File("c:/java2102"+File.separator + UUID.randomUUID().toString() +realName);
// 将接收到的文件保存到本地磁盘
multipartFile.transferTo(file);
}
return "success";
}
文件下载
在后台使用Spring MVC提供的ResponseEntity类型对象完成文件下载,使用它可以很方便的定义返回的HttpHeaders对象和HttpStatus对象,通过对这两个对象的设置,即可完成下载文件时所需的配置信息。
/**
* 文件下载
* @param filename
* @return
* @throws IOException
*/
@RequestMapping("/downloadFile")
public ResponseEntity<byte[]> downloadFile(String filename,HttpServletRequest request) throws Exception {
File file = new File("c:/java2102"+File.separator +filename);
HttpHeaders headers = new HttpHeaders();
// 设置下载的文件名称
// 对应文件名称重编码 让浏览器识别
headers.setContentDispositionFormData("attachment",getFilename(request,filename));
// 通知浏览器以下载的形式 打开文件
//浏览器以 二进制文件流 下载文件
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// (@Nullable T body,
// @Nullable MultiValueMap<String, String> headers, Object status
return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
}
解决中文文件名乱码问题:
/**
* 根据浏览器的不同进行编码设置,返回编码后的文件名
*/
public String getFilename(HttpServletRequest request,
String filename) throws Exception {
// IE不同版本User-Agent中出现的关键词
String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
// 获取请求头代理信息
String userAgent = request.getHeader("User-Agent");
for (String keyWord : IEBrowserKeyWords) {
if (userAgent.contains(keyWord)) {
//IE内核浏览器,统一为UTF-8编码显示
return URLEncoder.encode(filename, "UTF-8");
}
}
//火狐等其它浏览器统一为ISO-8859-1编码显示
return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
拦截器
拦截器:就是springmvc可以拦截过滤前端的请求,和过滤器的作用一样,但是拦截器只对经过Dispathcher的请求有效
拦截器 过滤器 Aop:抽取公共代码 拦截 过滤 鉴权
事务:只能用aop
springmvc 拦截器的实现:
第一种方式:通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。
第一种方式: 通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。
示例
1、实现HandlerInterceptor接口
/**
* 继承HandlerInterceptor 实现 拦截器
*
*
*/
public class CustomerInterceptor implements HandlerInterceptor {
@Override// 在处理器之前调
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("CustomerInterceptor ----preHandle 请求前");
String idStr = request.getParameter("id");
if (idStr!=null){
int id = Integer.valueOf(idStr);
if (id>0){ // 如果大于放行
return true;
}
}
// 拦截
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("被拦截了");
return false;
}
@Override// 处理器 响应请求后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("CustomerInterceptor ----postHandle 处理器响应请求后");
}
@Override //整个 请求响应成功之后调用 渲染成功之后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("CustomerInterceptor ----afterCompletion 处理器响应前端完成渲染成功 后");
}
}
public class MyInterceptor1 implements HandlerInterceptor {
@Override// 在处理器之前调
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1 ----preHandle 请求前");
// 放行
return true;
}
@Override// 处理器 响应请求后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1 ----postHandle 处理器响应请求后");
}
@Override //整个 请求响应成功之后调用 渲染成功之后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor1 ----afterCompletion 处理器响应前端完成渲染成功 后");
}
}
声明拦截器
<!--
配置拦截器
拦截器的顺序有 声明标签的顺序决定:越靠上越优先
-->
<mvc:interceptors>
<!-- 声明一个全局拦截器 对所有的请求 进行拦截-->
<!-- <bean class="com.qfedu.filter.CustomerInterceptor"></bean>-->
<mvc:interceptor>
<!-- 配置局部拦截器 只对部分
/student/** 拦截
忽略 /student/findAllStudent
-->
<mvc:mapping path="/student/**"/>
<mvc:exclude-mapping path="/student/findAllStudent"/>
<bean class="com.qfedu.filter.MyInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<!-- 局部拦截器 三者之间有顺序规定 必须先
<mvc:mapping
<mvc:exclude-mapping
<bean
-->
<mvc:mapping path="/findStudentById"/>
<bean class="com.qfedu.filter.CustomerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器顺序优先级
以上是关于springmvc的主要内容,如果未能解决你的问题,请参考以下文章
Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]