• Spring 实战-第七章-Spring MVC的高级技术


    1.处理multipart形式的数据

    对于文件,Spring可以支持multipart形式的数据,但是DispatcherServlet没有实现任何解析multipart请求数据的功能,需要配置一个解析器用来解析multipart。

    DispatcherServlet将该任务委托给了Spring中的MultipartResolver策略接口的实现,Spring内置了两个实现可以选择:

    • CommonMultipartResolver:使用Jakarta Commons FileUpload解析multipart请求;
    • StandardServletMultipartResolver:依赖于Servlet3.0对multipart请求的支持(始于Spring3.1)

    声明MultipartResolver的Bean

        @Bean
        public MultipartResolver multipartResolver() throws IOException {
            return new StandardServletMultipartResolver();
        }

    使用的时候,必须在web.xml或Servlet初始化类中,将multipart的具体细节(文件路径、大小等)作为DispatcherServlet配置的一部分,否则无法正常使用。

    如果采用Servlet初始化类的方式配置DispatcherServlet的话,这个类已经实现了WebApplicationInitializer,那么可以在Servlet registration上调用setMultipartConfig()方法,传入一个MultipartConfigElement。

    DispatcherServlet ds=new DispatcherServlet();
    Dynamic registration=context.addServlet("appServlet",ds);
    registration.addMapping("/");
    registration.asetMultipartConfig(
        new MultipartCofigElement("/tmp/spittr/upolads"));

    如果配置的Servlet初始化类继承了AbstractAnnotationConfigDispatcherServletInitializer或AbstractDispatcherServletInitializer的话,可以重载customizeRegistration()方法来配置multipart的具体细节。

    //设置multipart上传配置,路径,文件不超过2MB,请求不超过4MB
        @Override
        protected void customizeRegistration(ServletRegistration.Dynamic registration){
            registration.setMultipartConfig(
                    new MultipartConfigElement("C:/test",2097152,4194304,0));
        }

    页面增加input标签

    <input type="file" name="profilePicture" accept="image/jpeg,image/png,image/gif"/>

    处理multipart请求,最常用的是在控制器方法参数上添加@RequestPart注解,接收multipart数据可以使用byte[]、MultipartFile、Part等形式,MultipartFile与Part类似,都包含保存到文件系统的方法。

        @RequestMapping(value="/register",method = POST)
        public String processRegistration(
                @RequestPart("profilePicture") MultipartFile profilePicture,
                @Valid Spitter spitter,
                Errors errors, RedirectAttributes model) throws IOException{
            if(errors.hasErrors()){
                return "registerForm";
            }
            spitterRepository.save(spitter);
            //如果有上传文件,则保存到指定位置
            if(!profilePicture.isEmpty()) {
                profilePicture.transferTo(new File(profilePicture.getOriginalFilename()));
            }
            model.addFlashAttribute("spitter",spitter);
            return "redirect:/spitter/"+ spitterRepository.findByUsername("").getUsername();
        }

    7.3处理异常

    默认情况下,Spring会将吱声的一些异常自动转为为合适的状态,此外,我们可以对应用抛出的异常进行个性化的处理。

    • 将应用异常转为HTTP状态

    通过@ResponseStatus注解,可以将异常类转换为特定的HTTP状态,并且增加相关信息

    @ResponseStatus(value= HttpStatus.NOT_FOUND,reason = "将异常映射为特定的状态码")
    public class ErrorOneException extends Exception {
    
    }

    当代码抛出被包装的异常后,网页会使用异常指定的状态码,并且显示相关信息

    //将异常映射为特定的状态码
        @RequestMapping(value="/errorone",method = GET)
        public  String errorone(Model model) throws ErrorOneException{
           throw new ErrorOneException();
        }

      

    • 编写处理异常的方法

    在某些情况下,主动抛出异常,不仅会增加无关的逻辑,并且通过异常机制处理可能不能满足需求,需要对于特定异常进行更复杂的操作,比如跳转到其他页面,

    这时候在@ExceptionHandler注解,可以处理指定类型的异常

        //编写处理异常的方法
        @RequestMapping(value="/errortwo",method = GET)
        public  String errortwo(Model model){
           int a=1/0;//会抛出ArithmeticException
           return "test";
        }
    
        //编写处理异常的方法
        @ExceptionHandler(ArithmeticException.class)
        public String handleErrorTwo(){
            return "error";//使用error视图进行渲染
        }

    7.4 为控制器添加通知

    Spring3.2引入的控制器通知(controller advice),是任意带有@ControllerAdvice注解的类,这样控制器类的特定切面能够运用到整个应用程序的所有控制器中。

    这个类包含一个或多个如下类型的方法:

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

    在带有@ControllerAdvice注解的类中,以上所述的这些方法会运用到整个应用程序所有控制器中带有@RequestMapping注解的方法上。

    @ControllerAdvice注解本身已经使用了@Component,因此@ControllerAdvice注解锁标注的类将会自动被主键扫描获取到。

    比如7.3中的异常处理,就可以将异常处理统一到一处

    @ControllerAdvice
    public class AppWideExceptionHandler {
    
        @ExceptionHandler(ErrorThreeException.class)
        public String errorThreeExceptionHandler(){
            return "error";
        }
    }

    7.5跨重定向请求传递数据

    当使用“redirect:”前缀进行重定向的时候,由于模型数据已经随着上一个请求的结束而消亡,无法传递到下一个请求中,Spring提供了flash(闪存)属性,用于存储这类模型数据。

    相比Session存储,flash的好处在于,其生命周期只延续到下一个请求,请求结束后就会消失。

    使用flash存储模型数据

        //使用flash存储模型数据
        @RequestMapping(value="/flash",method = POST)
        public String processFlash(Spitter spitter,
               RedirectAttributes model) {
            model.addFlashAttribute("spitter",spitter);
            return "redirect:/spitter/test";
        }

     读取flash中的模型数据,当model中没有spitter属性时,使用查询数据库,否则就使用属性中的,当返回到页面请求结束,flash中的数据就没有了

        //读取flash中的模型数据
        @RequestMapping(value = "/{username}",method = GET)
        public String showSpitterProfile(
                @PathVariable String username,Model model){
            if(!model.containsAttribute("spitter")) {
                Spitter spitter = spitterRepository.findByUsername(username);
                model.addAttribute(spitter);
            }
            return "profile";
        }

    sourceCode:https://github.com/ljw8947/SpringInAction/tree/master/Capter7/Spittr

  • 相关阅读:
    MySQL计算月份间隔的函数
    《认知天性:让学习轻而易举的心理学规律》
    Ubuntu通过iptables配置 ip 代理转发
    Ubuntu开启/var/log/messages
    Ubuntu通过Nginx安装Webdav
    Ubuntu通过iptables防止ssh暴力破解
    frp内网穿透
    Vim配置
    Linux为STDOUT的关键字设置颜色
    Maven项目中在properties 中使用 ${} 来引用pom文件中的属性
  • 原文地址:https://www.cnblogs.com/lvjianwei/p/7922019.html
Copyright © 2020-2023  润新知