上传与下载
一、Jackson解析
概述
jackson解析,是基于返回的json数据中属性的显示形式。
使用Jackson解析,需要导入依赖包。
应用
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@JsonProperty("new_id")
private Integer id; //改ID的别名
@JsonIgnore //忽略该属性
private String name;
@JsonInclude(JsonInclude.Include.NON_NULL) //null值 属性不输出
private String password;
//解析之后的日期格式
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date birth;
@JsonInclude(value= JsonInclude.Include.NON_EMPTY) // 若hobby长度为0或==null 忽略此属性
private List<String> hobby;
}
自定义序列化
自定义序列化,表示可以自己定义属性的配置效果
//实体属性----
//主要针对属性进行格式处理; 不常用,可以在前端使用jstl格式库来处理
@JsonSerialize(using = MySerializer.class)
private Double salary; //10000.126 在输出此属性时,使用MySerializer输出
//序列化接口
public class MySerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
// 将Double salary的值 四舍五入
String number = BigDecimal.valueOf(value).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
// 输出 四舍五入后的值
gen.writeNumber(number); //值会注入到User实体属性中
}
}
二、异常解析器
概述
如果没有异常解析器,那么我们目标handler中如果有异常,每个handler中都要处理
如果有了异常解析器,则可以统一在解析器中进行处理异常。
配置
public class MyExResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
e.printStackTrace();//打印异常
ModelAndView mav = new ModelAndView();
//根据不同的异常类型,重定向到不同的处理页面
if(e instanceof NullPointerException){
mav.setViewName("redirect:/err1.jsp");
}else if(e instanceof ArithmeticException){
mav.setViewName("redirect:/err2.jsp");
}else{
mav.setViewName("redirect:/err3.jsp");
}
return mav;
}
}
需要在mvc容器中产生bean:
<!-- 异常解析器的bean -->
<bean class="com.qf.ex.MyExResolver"></bean>
三、拦截器
概述
与web中的过滤器一致,在访问目标资源前的一道拦截技术
应用场景:可以统一的编码处理及权限验证
应用
案例:如果没有登录凭证,则无法进入到目标handler。
拦截器中的权限配置:
//拦截器的类
public class MyInter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器...");
//在访问目标handler之前进行的触发
String username = (String) request.getSession().getAttribute("username");
if(username==null){ //没有登录凭证,则跳转到登录
response.sendRedirect("/login.jsp"); //重定向
return false;
}
return true; //此处如果返回false则进行拦截;返回true放行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//在handler之后执行:进一步的响应定制
System.out.println("post...");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//在页面渲染完毕之后,执行:资源回收
System.out.println("after...");
}
}
mvc容器中进行拦截路径的筛选:
<!-- 拦截器的配置... -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/json/**"/> <!--拦截json下的所有路径-->
<mvc:exclude-mapping path="/json/login"/><!--不拦截login -->
<!-- 绑定拦截器的bean -->
<bean class="com.qf.inter.MyInter"></bean>
</mvc:interceptor>
</mvc:interceptors>
在目标handler中可以进行登录与测试:
@RequestMapping("/hello")
public String hello(){
System.out.println("访问到目标handler");
return "ok";
}
@RequestMapping("/login")
public String login(HttpSession session){
System.out.println("登录成功~");
session.setAttribute("username","zs");
return "ok";
}
四、上传
概述
上传功能,需要从前端传二进制资源到服务器中
前端配置
<%--请求方式:post enctype:编码类型为multipart/form-data --%>
<form action="/upload/test1" method="post" enctype="multipart/form-data">
文件上传:<input type="file" name="source" /><br>
<input type="submit" value="提交">
</form>
后端配置
后端控制层配置:
@RestController
@RequestMapping("/upload")
public class UploadController {
@RequestMapping("/test1") //从file控件中得到二进制资源
public String test1(MultipartFile source, HttpSession session) throws IOException {
String fileName = source.getOriginalFilename(); //获取文件名
//为了安全性,可以设置uuid名字前缀 xxdfff_a.jpg
//String uuidName = UUID.randomUUID().toString()+"_"+fileName;
System.out.println("fileName:"+fileName);
//文件上传,往往上传到项目指定路径 获取真实路径-带盘符
String realPath = session.getServletContext().getRealPath("/upload");
System.out.println("真实路径:"+realPath);
File dir = new File(realPath); //封装成File对象
if(!dir.exists()){ //判断目录不存在,则创建
System.out.println("不存在,则创建目录");
dir.mkdirs();
}
source.transferTo(new File(dir,fileName)); //上传图片完成
return "ok";
}
}
mvc容器配置上传解析:
<!-- 上传解析器
id必须是:“multipartResolver”
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大可上传的文件大小 单位:byte 超出后会抛出MaxUploadSizeExceededException异常,可以异常解析器捕获 -->
<property name="maxUploadSize" value="1048576"></property>
</bean>
导入上传的依赖:
<!-- 上传的依赖 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
五、下载
从服务器中下载资源。
前端
<a href="/download/test1?name=006.png">下载</a>
后端
@RestController
@RequestMapping("/download")
public class DownloadController {
@RequestMapping("/test1")
public void test1(String name, HttpSession session, HttpServletResponse response) throws IOException {
System.out.println(name);
//获取真实路径
String realPath = session.getServletContext().getRealPath("/upload");
System.out.println(realPath);
String path = realPath+"/"+name; //拼接
//设置响应头 告知浏览器,要以附件的形式保存内容 filename=浏览器显示的下载文件名
response.setHeader("content-disposition","attachment;filename="+name);
//先读取到输入流,后写到响应的输出流
IOUtils.copy(new FileInputStream(path),response.getOutputStream());
}
}
六、验证码
导包
导入验证码包:
<!-- Kaptcha -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
映射路径
<!-- 配置映射路径 -->
<servlet>
<servlet-name>cap</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<init-param>
<param-name>kaptcha.border</param-name>
<param-value>no</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.length</param-name>
<param-value>4</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.string</param-name>
<param-value>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</param-value>
</init-param>
<init-param>
<param-name>kaptcha.background.clear.to</param-name>
<param-value>211,229,237</param-value>
</init-param>
<init-param>
<!-- session.setAttribute("captcha","验证码") -->
<param-name>kaptcha.session.key</param-name>
<param-value>captcha</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>cap</servlet-name>
<url-pattern>/captcha</url-pattern>
</servlet-mapping>
前端展示与刷新
<%-- 验证码图片 --%>
<img src="/captcha" onclick="reload(this)"><br>
<script>
function reload(obj){
obj.src="captcha?date="+new Date();
}
</script>
七、Rest
概述
是一种开发风格,遵从此风格开发软件,符合REST风格,则RESTFUL。
两个核心要求:
- 每个资源都有唯一的标识(URL)
- 不同的行为,使用对应的http-method
注意:Rest风格往往需要使用ajax传数据,返回字符串
handler
@RestController
public class UserController {
//请求方式为get请求,路径为/users
//@RequestMapping(value = "/users",method = RequestMethod.GET)
@GetMapping("/users") //查询 等价于上面的注解
public List<User> users(){
List<User> list = new ArrayList<>();
list.add(new User());
return list;
}
@PostMapping("/users") //添加操作
public String addUser(User user){
System.out.println("user-->"+user);
return "ok";
}
@PutMapping("/users") //修改操作
public String updateUser(@RequestBody User user){
System.out.println("update user-->"+user);
return "update OK";
}
@GetMapping("/user/{id}") //查询单个对象 --路径传参
public User user(@PathVariable Integer id){
System.out.println("id-->"+id);
User user = new User(id,"zs","123",null,null,null);
return user;
}
@DeleteMapping("/delete/{id}") //路径传参
public String delete(@PathVariable Integer id){
System.out.println("删除-->"+id);
return "delete ok";
}
}
ajax请求
function updateUser() { //修改功能 put请求
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("put","/users",true);
// 设置请求头
xmlHttp.setRequestHeader("content-type","application/json");
var user = {id:10,name:"zsf",password:"333"};
xmlHttp.send(JSON.stringify(user));
xmlHttp.onreadystatechange=function () { //接收回调数据
if(xmlHttp.readyState==4&&xmlHttp.status==200){
alert(xmlHttp.responseText);
}
}
}
$(function(){ /* 删除功能*/
$("#delete").click(function () {
$.ajax({
type:"delete",
url:"/delete/1",
success:function(data) {
alert(date);
}
})
})
})
八、SpringMVC执行流程
浏览器发请求,到达前端控制器–>HandlerMapping映射处理(包含处理器和拦截器)–>HandlerAdapter进行handler适配,并到达目标handler,然后返回ModelAndView对象–>视图解析对象—>重定向或转发跳转–>渲染到JSP文件。
九、总结与作业
总结
1.Jackson解析
概述-按规则显示属性;应用
2.异常解析器
好处-统一handler的异常处理;配置
3.拦截器(重点)
概述-过滤器;应用-权限验证
4.上传(重点)
前端配置-post,二进制编码,file类型;
后端配置-上传解析器,上传功能处理
5.下载
将资源先读后写
6.验证码
导包,映射路径配置,前端展示操作
7.Rest(重点)
概述;handler处理-增删改查编写,ajax请求-put,delete
作业
1.使用Rest风格完成Student的增删改查
晨考
1.异常解析器的作用
2.拦截器的作用
3.上传的客户端需要注意什么?
4.Rest风格是怎样的一种规范?