SpringMVC中的文件上传和下载、异常处理和定时任务-文件上传

SpringMVC文件上传、异常处理、定时任务

面试题

1、SpringMvc中方法的返回值是什么?

 String :视图的名称
ModelAndView:模型视图

在方法前面加@ResponseBody;应对ajax

2、SpringMvc用什么对象从后台向前台传递数据的?

 同步:
public void test1(HttpServletResponse response, ModelMap map1, Model model,Map map){
//map1.put(, );
// model.addAttribute(, );
// map.put(, ) ;

// response.getWriter().print("hello");
//转发、重定向

}

异步:
@ResponseBody

3、怎么样把ModelMap里面的数据放入Session里面?

 @SessionAttributes(放在类前面)
注入HttpSession ;

4、SpringMvc里面拦截器是怎么写的

 实现HandlerInterceptor接口
推荐:继承HandlerInterceptorAdapter类
设计模式:接口适配,适配器模式

5、springmvc常用注解

 responsebody
requestbody
requestmapping
initbinder:初始化类型转换器
modelattribute
sessionattributes
requestparam
pathvariable
postmapping getmapping putmapping deletemapping

controller
service
repository
autowired:类型自动 qualifier:跟名字识别
resource:默认按名字,可以按类型

6、spring中的设计模式?

 单例模式:bean的默认作用域
工厂模式:创建bean
代理模式:Aop中(JDK动态代理,CGLIB的代理)
适配器模式:接口适配
mvc模式

学习目标

1、文件上传下载

2、异常处理

3、定时任务

学习内容

1、文件上传下载

1、文件 上传

步骤:

1、引入jar包

 <!--文件上传-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>

2、设计表单

 提交方式、多媒体类型
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>

3、配置文件中设置文件解析器

 <!--文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
</bean>

备注:指定id: id="multipartResolver"

4、控制器中接受数据

 @RequestMapping(value = "/upload")
public String upload(@RequestParam("file") MultipartFile file, HttpServletRequest request, Model model) throws IOException {
//获取指定目录的绝对路径
String path=request.getSession().getServletContext().getRealPath("/static/");
//获取待上传文件的原始的文件名
String fileName=file.getOriginalFilename();
//判断文件是否存在
File sourceFile=new File(path,fileName);
//不存在,再上传
if(!sourceFile.exists()){
//目标文件对象
File descFile=new File(path+File.separator+fileName);
file.transferTo(descFile);
}
model.addAttribute("file",file);
//?
/*
* 目标路径 :需要的是绝对路径
* 文件传输
* */

return "up";

}

2、文件下载

办法:超链接指向文件

使用控制器进行下载

 @RequestMapping("/download")
public ResponseEntity<byte[]> download(@RequestParam("filename") String filename,HttpServletRequest request) throws IOException {
//应对:中文文件名乱码
//filename.getBytes("iso-8859-1"):将原始的字符串以 西欧编码方式转换成字节数组
//"utf-8" : 重新以utf-8进行编码
filename=new String(filename.getBytes("iso-8859-1"),"utf-8");

//获取绝对路径
String path=request.getSession().getServletContext().getRealPath("/static/");
//待下载的文件对象
File downloadFile=new File(path+"/"+filename);

//头部信息对象
HttpHeaders headers=new HttpHeaders();
//响应类型:二进制数据流
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//浏览器如何接受数据
headers.setContentDispositionFormData("attachment", filename);

//FileUtils.readFileToByteArray(downloadFile): 将文件对象转换成字节数组
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(downloadFile), headers, HttpStatus.CREATED );
}

任务:如何实现多文件上传? 异步上传?

修改成数组 :@RequestParam("file") MultipartFile[] files

异步上传

2、异常处理

1、异常处理分析:

如何处理?:dao :try --catch service:try- catch controller:try -catch;

推荐:直接在最后的控制器中处理异常。

2、springmvc自带的简单异常处理器:SimpleMappingExceptionResolver

 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--默认的错误视图-->
<property name="defaultErrorView" value="error"/>
<!--可以使用该属性取值-->
<property name="exceptionAttribute" value="ex"/>
<!--不同的异常设定不同的错误页面-->
<property name="exceptionMappings" >
<props>
<prop key="异常类型">
错误页面
</prop>
</props>
</property>
</bean>

3 自定义全局的异常处理器:

1、使用@ExceptionHandler注解

作用:只处理当前控制器中的异常。

 @ExceptionHandler({Exception.class})
public String handler1(Exception ex, Model model){
model.addAttribute("ex", ex);
return "error";
}

设计一个BaseController,别的controller继承BaseController

2、定义一个类,实现HandlerExceptionResolver接口

 @Component
public class ExceptionHandler2 implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView=new ModelAndView("error");
modelAndView.addObject("ex", e);

// if(e instanceof A){
// modelAndView.setViewName("error1");
// } else if(e instanceof B){
// modelAndView.setViewName("error2");
// }

return modelAndView;
}
}

3、使用 @ControllerAdvice+ @ ExceptionHandler 注解

 @ControllerAdvice
public class ExceptionHandler3 {

@ExceptionHandler({Exception.class})
public ResponseEntity<Result> handler3(Exception ex){
//封装异常的相关的数据信息
Result result=new Result();
result.setStatus(500);
result.setMessage(ex.getMessage());
return new ResponseEntity<>(result, HttpStatus.OK);
}
}

SpringMVC中的文件上传和下载、异常处理和定时任务

异常显示

3、定时任务

1、借助于xml配置(略)

2、借助于注解,在mvc配置文件种添加 注解,注意引入task命名空间。

 <task:annotation-driven/>

Scheduled注解源码:

 @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
String CRON_DISABLED = "-";

String cron() default "";

String zone() default "";

long fixedDelay() default -1L;

String fixedDelayString() default "";

long fixedRate() default -1L;

String fixedRateString() default "";

long initialDelay() default -1L;

String initialDelayString() default "";
}

示例:

 @Controller
public class JobController {

@Scheduled(cron="0/5 * * * * ?")
public void job(){
//要处理的功能
System.out.println(new Date());
}
}

CronTrigger配置完整格式为: [秒] [分] [小时] [日] [月] [周] [年]

序号说明是否必填允许填写的值允许的通配符1秒是0-59, - * /2分是0-59, - * /3小时是0-23, - * /4日是1-31, - * ? / L W5月是1-12或JAN-DEC, - * /6周是1-7或SUN-SAT, - * ? / L W7年否empty 或1970-2099, - * /

CRON表达式 示例:

"0 0 12 * * ?" 每天中午十二点触发

"0 15 10 ? * *" 每天早上10:15触发

"0 15 10 * * ?" 每天早上10:15触发

"0 15 10 * * ? *" 每天早上10:15触发

"0 15 10 * * ? 2005" 2005年的每天早上10:15触发

"0 * 14 * * ?" 每天从下午2点开始到2点59分每分钟一次触发

"0 0/5 14 * * ?" 每天从下午2点开始到2:55分结束每5分钟一次触发

"0 0/5 14,18 * * ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发

"0 0-5 14 * * ?" 每天14:00至14:05每分钟一次触发

"0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发

"0 15 10 ? * MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发

"0 * * * * ?" 每分钟(0点0时0分)触发一次

"0 0 * * * ?" 每小时(0点0时0分)触发一次

例如:子表达式(天(星期))可以为 “MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT”

“*”字符代表所有可能的值

“/”字符用来指定数值的增量

例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟

在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样

“?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值

当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”

“L” 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写

如果在“L”前有具体的内容,它就具有其他的含义了。例如:“6L”表示这个月的倒数第6天

注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题

W 字符代表着平日(Mon-Fri),并且仅能用于日域中。它用来指定离指定日的最近的一个平日。大部分的商业处理都是基于工作周的,所以 W 字符可能是非常重要的。

例如,日域中的 15W 意味着 "离该月15号的最近一个平日。" 假如15号是星期六,那么 trigger 会在14号(星期五)触发,因为星期四比星期一离15号更近。

C:代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。

fixedDelay = 5000 每秒触发一次 这个周期是以上一个调用任务的完成时间为基准,在上一个任务完成之后,5s后再次执行

fixedRate = 5000 每5秒触发一次 固定速率执行,以上一个任务开始时间为基准,从上一任务开始执行后5s再次调用

initialDelay=3000 启动后延迟3秒后开始首次触发

总结

1、文件上传和下载

2、异常处理(3种)

3、定时任务

推荐阅读