码迷,mamicode.com
首页 > 编程语言 > 详细

第7章 Spring MVC的高级技术

时间:2018-07-15 16:15:23      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:ack   就会   自己   erro   roo   组件   round   config   开头   

 

1、配置其它的Servlet和Filter

按照 AbstractAnnotationConfigDispatcherServletInitializer 的定义,它会创
建 DispatcherServlet 和 ContextLoaderListener 。但是,如果你想注册其他的 Servlet 、 Filter 或 Listener 的话,那该怎么办呢?
基于 Java 的初始化器( initializer )的一个好处就在于我们可以定义任意数量的初始化器类。因此,如果我们想往 Web 容器中注册其他组件的
话,只需创建一个新的初始化器就可以了。最简单的方式就是实现 Spring 的 WebApplicationInitializer 接口。

技术分享图片

技术分享图片

不过,如果你只是注册 Filter ,并且该 Filter 只会映射到 DispatcherServlet 上的话,那么
在 AbstractAnnotationConfigDispatcherServletInitializer 中还有一种快捷方式。
为了注册 Filter 并将其映射到 DispatcherServlet ,所需要做的仅仅是重
载 AbstractAnnotationConfigDispatcherServletInitializer 的 getServlet-Filters() 方法。例如,在如下的代码中,重
载了 AbstractAnnotationConfig-DispatcherServletInitializer 的 getServletFilters() 方法以注册 Filter :

技术分享图片

2、处理 multipart 形式的数据

简单的说就是form表单的文件框上传的处理,spring mvc需要配置处理器

从 Spring 3.1 开始, Spring 内置了两个 MultipartResolver 的实现供我们选择:

  • CommonsMultipartResolver :使用 Jakarta Commons FileUpload 解析 multipart 请求;
  • StandardServletMultipartResolver :依赖于 Servlet 3.0 对 multipart 请求的支持(始于 Spring 3.1 )

这里我们只说Servlet3.0形式的配置,也推荐这种方式,至少不会需要其它第三方的jar包:

第一步

兼容 Servlet 3.0 的 StandardServletMultipartResolver 没有构造器参数,也没有要设置的属性。这样,在 Spring 应用上下文中,将其
声明为 bean 就会非常简单,如下所示:

 技术分享图片

第二步

如果我们配置 DispatcherServlet 的 Servlet 初始化类继承了 Abstract
AnnotationConfigDispatcherServletInitializer 或 AbstractDispatcher-ServletInitializer 的话,那么我们不会直
接创建 DispatcherServlet 实例并将其注册到 Servlet 上下文中。这样的话,将不会有对 Dynamic Servlet registration 的引用供我们使用
了。但是,我们可以通过重载 customizeRegistration() 方法(它会得到一个 Dynamic 作为参数)来配置 multipart 的具体细节:

技术分享图片

构造器支持设置参数:

  • 上传文件的最大容量(以字节为单位)。默认是没有限制的。
  • 整个 multipart 请求的最大容量(以字节为单位),不会关心有多少个 part 以及每个 part 的大小。默认是没有限制的。
  • 在上传的过程中,如果文件大小达到了一个指定最大容量(以字节为单位),将会写入到临时文件路径中。默认值为 0 ,也就是所有上传
  • 的文件都会写入到磁盘上

第三步

配置好了我们需要在控制器把文件接过来呀,可以使用MultipartFile,当然我们还可以使用Part,

通过 Part 参数的形式接受文件上传,那么就没有必要配置 MultipartResolver 了。只有使
用 MultipartFile 的时候,我们才需要 MultipartResolver 。不过需要注意临时路径必须配置,当然自己可以在接受过来之后自己不用提供的接口,自己写保存的逻辑。

@RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ModelAndView upload(@RequestParam("file") MultipartFile file, HttpServletRequest request){
        String msg = "";
        try {
            File root = new File("D:/uploads/");
            if(!root.exists()){
               root.mkdir();
            }
            File f = new File("/uploads/"+file.getOriginalFilename());

            FileOutputStream fos = new FileOutputStream(f);
            fos.write(file.getBytes());
            fos.flush();
            fos.close();
            msg = "上传成功!";
        } catch (IOException e) {
            e.printStackTrace();
            msg = "上传失败!";
        }
        ModelAndView mav = new ModelAndView("result");
        mav.addObject("msg",msg);
        return mav;
    }
    @RequestMapping(value = "/upload2" , method = RequestMethod.POST)
    public ModelAndView upload2(@RequestParam("file") Part file){
        String msg = "";
        try {
            System.out.println(file.getSubmittedFileName());
            File f = new File("/uploads/"+file.getSubmittedFileName());
            InputStream is = file.getInputStream();
            FileOutputStream fos = new FileOutputStream(f);
            int index;
            byte[] bytes = new byte[1024];
            while ((index = is.read(bytes)) != -1) {
                fos.write(bytes, 0, index);
                fos.flush();
            }
            fos.close();
            is.close();
            msg = "上传成功!";
        } catch (IOException e) {
            e.printStackTrace();
            msg = "上传失败!";
        }
        ModelAndView mav = new ModelAndView("result");
        mav.addObject("msg",msg);
        return mav;
    }

3、处理异常

Spring 提供了多种方式将异常转换为响应:

  • 特定的 Spring 异常将会自动映射为指定的 HTTP 状态码;
  • 异常上可以添加 @ResponseStatus 注解,从而将其映射为某一个 HTTP 状态码;
  • 在方法上可以添加 @ExceptionHandler 注解,使其用来处理异常。

特定异常转换为http状态码

技术分享图片

异常上可以添加 @ResponseStatus 注解,从而将其映射为某一个 HTTP 状态码

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value = HttpStatus.NOT_FOUND , reason = "not found!")
public class CodeFoundException extends RuntimeException {
    public CodeFoundException(){}
    public CodeFoundException(String msg){
        super(msg);
    }
}

 

 

在方法上可以添加 @ExceptionHandler 注解,使其用来处理异常

@RequestMapping(value = "/error" , method = RequestMethod.GET)
    public ModelAndView error(@RequestParam("code") String code){
        if("1".equals(code))
            //throw new CodeFoundException("就是测试一下!");
            throw new DuplicateCodeFoundException("就是测试一下!");
        ModelAndView mav = new ModelAndView("error");
        return mav;
    }

    @ExceptionHandler(DuplicateCodeFoundException.class)
    public ModelAndView handleDuplicateCodeFound(){
        ModelAndView mav = new ModelAndView("codefound");

        return mav;
    }

 

如果控制器类的特定切面能够运用到整个应用程序的所有控制器中,那么这将会便利很多。举例来说,如果要在多个控制器中处理异常,
那 @ExceptionHandler 注解所标注的方法是很有用的。不过,如果多个控制器类中都会抛出某个特定的异常,那么你可能会发现要在所有
的控制器方法中重复相同的 @ExceptionHandler 方法。或者,为了避免重复,我们会创建一个基础的控制器类,所有控制器类要扩展这个
类,从而继承通用的 @ExceptionHandler 方法。
Spring 3.2 为这类问题引入了一个新的解决方案:控制器通知。控制器通知( controller advice )是任意带有 @ControllerAdvice 注解的类,
这个类会包含一个或多个如下类型的方法:

  • @ExceptionHandler 注解标注的方法;
  • @InitBinder 注解标注的方法;
  • @ModelAttribute 注解标注的方法。

在带有 @ControllerAdvice 注解的类中,以上所述的这些方法会运用到整个应用程序所有控制器中带有 @RequestMapping 注解的方法
上。
@ControllerAdvice 注解本身已经使用了 @Component ,因此 @ControllerAdvice 注解所标注的类将会自动被组件扫描获取到,就像
带有 @Component 注解的类一样。

@ControllerAdvice 最为实用的一个场景就是将所有的 @ExceptionHandler 方法收集到一个类中,这样所有控制器的异常就能在一个地
方进行一致的处理。例如,我们想将 DuplicateSpittleException 的处理方法用到整个应用程序的所有控制器上。如下的程序清单展现
的 AppWideExceptionHandler 就能完成这一任务,这是一个带有 @ControllerAdvice 注解的类。

技术分享图片

4、重定向和转发

在控制器方法返回的视图名称中,我们借助了 “redirect:” 前缀的力量。当控制器方法返回的 String 值以 “redirect:” 开头的
话,那么这个 String 不是用来查找视图的,而是用来指导浏览器进行重定向的路径

return new ModelAndView("redirect:/")

 

我们知道重定向是会丢失参数的,但是spring有一种保存数据方法使用 flash 属性。 

技术分享图片

 

 技术分享图片

技术分享图片

转发,url不变,参数不丢失,前缀forward:

return new ModelAndView("forward:/dengluPost")

 

第7章 Spring MVC的高级技术

标签:ack   就会   自己   erro   roo   组件   round   config   开头   

原文地址:https://www.cnblogs.com/xzcode/p/9287495.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!