笔记SpringMVC-2

2018-11-13  本文已影响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";
    }
上一篇下一篇

猜你喜欢

热点阅读