美文网首页
笔记SpringMVC-2

笔记SpringMVC-2

作者: 飞奔吧牛牛 | 来源:发表于2018-11-13 16:31 被阅读0次

    1.类型转换器
    需求:将String类型字符串转换为Employee对象,如:a-b-1-1转换为Employee对象

    其中Employee类中的字段:
        private Integer id;
        private String lastName;
        private String email;
        private int gender;
        private Department department;
    Department类中的字段:
        private Integer id;
        private String departmentName;
    

    步骤如下:
    1).定义类型转换器EmployeeConverter

    @Component
    public class EmployeeConverter implements Converter<String, Employee>{
    
        @Override
        public Employee convert(String source) {
            if (source != null) {
                String[] vals = source.split("-");
                if (vals != null && vals.length ==4) {
                    try {
                        
                        String lastName = vals[0];
                        String email = vals[1];
                        int gender = Integer.parseInt(vals[2]);
                        int departmentId = Integer.parseInt(vals[3]);
                        Department department = new Department();
                        department.setId(departmentId);
                        Employee employee = new Employee(null, lastName, email, gender, department);
                        return employee;
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            }
            return null;
        }
    }
    

    2).spring配置文件springmvc.xml中加入如下配置

    <mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
        
        <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <ref bean="employeeConverter"/>
                </set>
            </property>
        </bean>
    

    3).请求页面

    <form action="testConversionServiceConverer" method="post">
            <input type="text" name="employee" value="a-b-1-1"/>
            <input type="submit" value="submit">
        </form>
    

    4).目标方法

    @RequestMapping("/testConversionServiceConverer")
        public String testConverter(@RequestParam("employee") Employee employee) {
            System.out.println(employee);
            return "success";
        }
    

    2.mvc:annotation-driven

    <mvc:annotation-driven />会自动注册
    RequestMappingHandlerMapping,
    RequestMappingHandlerAdapter和
    ExceptionHandlerExceptionResolver三个bean
    还提供以下支持:
    -支持使用ConversionService实例对表单参数进行类型转换
    -支持使用@numberFormat annotation,
    @DateTimeFormat注解完成数据类型的格式化
    -支持使用@Valid注解对JavaBean实例进行JSR 303 验证
    -支持使用@RequestBody和ResponseBody注解
    

    3.@InitBinder
    由@InitBinder 标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类,用于完成有表单字段到JavaBean
    属性的绑定
    @InitBinder方法不能有返回值,她必须声明为void。
    @InitBinder方法的参数通常是WebDataBinder

    //不对哪个字段赋值
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setDisallowedFields("lastName");
    }
    

    4.数据格式化

        <!-- 
        org.springframework.context.support.ConversionServiceFactoryBean这个类用于配置类型转换
        org.springframework.format.support.FormattingConversionServiceFactoryBean这个类既可以格式化数据又可以类型转换
         -->
        <bean id="conversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <set>
                    <ref bean="employeeConverter"/>
                </set>
            </property>
        </bean>
    
        在属性上添加注解
        @DateTimeFormat(pattern="yyyy-MM-dd")
        private Date birth;
        @NumberFormat(pattern="#,###,###.#")
        private Float salary;
    

    5.返回json
    由于乱码问题,加上了produces="text/plain;charset=UTF-8",网上也有配置AnnotationMethodHandlerAdapter的(放在mvc:annotation-driven之前)

      <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
         <property name="messageConverters">     
             <list>     
                <bean class = "org.springframework.http.converter.StringHttpMessageConverter">     
                    <property name = "supportedMediaTypes">  
                          <list>  
                              <value>text/html;charset=UTF-8</value>     
                         </list>     
                    </property>     
                 </bean>     
             </list>     
         </property>    
       </bean>  
    

    但是,不管用!

    @ResponseBody
        @RequestMapping(value="/getJson", produces="text/plain;charset=UTF-8")
        public String getJson(HttpServletResponse respone) {
            Employee e = new Employee(101, "张三", "123@qq.com", 1, new Department(1, "开发部"));
            String s = JSON.toJSONString(e);
            return s;
        }
    

    6.文件上传

    1).添加文件上传所需的jar包
    commons-fileupload-1.3.3.jar
    commons-io-2.6.jar

    2).springmvc.xml中加入如下配置:

    <!-- 配置MultipartResolver -->
        <bean id="multipartResolver" 
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="UTF-8"></property>
            <property name="maxUploadSize" value="1024000"></property>
        </bean>
    

    3).请求页面

    <form action="testFileUpload" method="post" enctype="multipart/form-data">
            File:<input type="file" name="file"/>
            File2:<input type="file" name="file2"/>
            Desc:<input type="text" name="desc"/>
            <input type="submit" value="Submit"/>
        </form>
    

    4).目标方法

    @RequestMapping("/testFileUpload")
        public String testFileUpload(@RequestParam("desc") String desc,
                @RequestParam("file") MultipartFile file,
                @RequestParam("file2") MultipartFile file2) throws IOException {
            System.out.println(desc);
            System.out.println(file.getOriginalFilename()+" "+file2.getOriginalFilename());
            return "success";
        }
    

    7.拦截器
    1).创建拦截器,

    /**
     * 拦截器方法执行顺序:pre-目标方法-post-渲染视图-after
     *preHandle>handle>postHandle>render>afterCompletion
     */
    public class FirstInterceptor implements HandlerInterceptor {
        
        /**
         * 该方法在目标方法之前被调用。
         * 若返回值是true,则继续调用后续的兰机器和方法
         * 若返回false,则不会再调用后续的拦截器和方法
         * 
         * 可以考虑做权限
         */
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
            System.out.println(getClass().getName()+":preHandle");
            return true;
        }
    
        /**
         * 调用目标方法之后,但再渲染视图之前
         * 可以对请求域中的是属性或视图做出修改
         */
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
                throws Exception {
            System.out.println(getClass().getName()+":postHandle");
        }
        
        /**
         * 渲染视图之后被调用,释放资源
         */
        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            System.out.println(getClass().getName()+":afterCompletion");
        }
    
    }
    

    2).配置拦截器

    <mvc:interceptors>
            <!-- 配置自定义拦截器 -->
            <bean class="com.springmvc.interceptor.FirstInterceptor"></bean>
            <bean class="com.springmvc.interceptor.SecondInterceptor"></bean>
            <!-- 拦截器(不)作用的路径 -->
            <mvc:interceptor>
                <mvc:mapping path="/emp"/>
                <bean class="com.springmvc.interceptor.EmpInterceptor"></bean>
            </mvc:interceptor>
        </mvc:interceptors>
    

    3).多个拦截器

    当多个(两个)拦截器配置时,方法执行顺序为
    FirstInterceptor:preHandle
    SecondInterceptor:preHandle
    执行目标方法。。。
    SecondInterceptor:postHandle
    FirstInterceptor:postHandle
    SecondInterceptor:afterCompletion
    FirstInterceptor:afterCompletion

    有两个拦截器,第一个拦截器返回false时,
    FirstInterceptor:preHandle
    有两个拦截器,第一个拦截器返回true,第二个拦截器返回false时。
    FirstInterceptor:preHandle
    SecondInterceptor:preHandle
    FirstInterceptor:afterCompletion

    总结:如果一个拦截器的preHandle方法返回false,那么这个拦截器的后续方法,以及整个拦截器组的postHandle方法,以及目标方法将不执行

    8.异常处理@ExceptionHandler

    /**
         * 1.在@ExceptionHandler方法参数中可以加入Exception类型的参数,改参数即对应发生的异常对象
         * 2.@ExceptionHandler方法的参数不能传入Map,若希望把异常信息传到页面上,需要使用ModelAndView作为返回值
         * 3.@ExceptionHandler方法标记的异常有优先级的问题,
         * 4.@ControllerAdvice:如果在当前handler中找不到@ExceptionHandler标记的方法来处理当前方法出现的异常,
         * 则将去 @ControllerAdvice标记的类中查找@ExceptionHandler标记的方法来处理异常
         */
        @ExceptionHandler
        public ModelAndView handleArithmeticException(Exception ex) {
            System.out.println(ex);
            ModelAndView mv = new ModelAndView("error");
            return mv;
        }
    
        @RequestMapping("/testExceptionHandlerExceptionResolver")
        public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i) {
            System.out.println("" + (10 / i));
            return "success";
        }
    

    相关文章

      网友评论

          本文标题:笔记SpringMVC-2

          本文链接:https://www.haomeiwen.com/subject/utelfqtx.html