[java]47、springMVC-Multipart

2022-07-17  本文已影响0人  史记_d5da

1、Multipart参数

1.1、图片格式

1、需要在pom.xml中添加依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

2、添加CommonsMultipartResolverIoC容器,id值固定为multipartResolver

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxInMemorySize" value="20480"/>
</bean>

3、java代码的实现部分

@RequestMapping("/test3")
@ResponseBody
public String test3(String username,
                        MultipartFile photo1,
                        MultipartFile photo2,
                        HttpServletRequest request) throws Exception{
    System.out.println(username);
    // 将文件数据写入到具体的位置
    String filename = photo1.getOriginalFilename();
    String path = request.getServletContext().getRealPath("upload/img" + filename);
    File file = new File(path);
    // 在实际操作过程中,需使用方法 FileUtils.copyInputStreamToFile(photo1.getInputStream(), file);
    photo1.transferTo(file);
    filename = photo2.getOriginalFilename();
    path = request.getServletContext().getRealPath("upload/img/" + filename);
    file = new File(path);
    photo2.transferTo(file);
    return "test3 success";
}

4、CommonsMultipartResolver的常用属性
defaultEncoding:设置request的请求编码
uploadTempDir:设置上传文件时的临时目录,默认是Servlet容器的临时目录
maxUploadSize:限制总的上传文件大小,以字节为单位。当设为-1时表示无限制,默认是-1
maxUploadSizePerFile:限制每个上传文件的大小
maxInMemorySize:设置每个文件上传时允许写到内存中的最大值,以字节为单位,默认是10240
若一个文件超过这个数值,就会生成临时文件;否则不会生成临时文件

1.2、日期格式

Spring(MVC)默认支持yyyy/MM/dd的日期格式转换,其他日期格式需要特殊处理。
1、使用@DateTimeFormat

@RequestMapping("/test5")
@ResponseBody
public String test5(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) throws Exception{
    System.out.println(birthday);
    return "test5 success";
}

2、使用Converter

<mvc:annotation-driven conversion-service="conversionService">
...
<!--类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.sj.converter.DateConverter" />
        </set>
    </property>
</bean>

DateConverter

public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        try {
            return new SimpleDateFormat("yyy-MM-dd").parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }
}

2、异常处理

2.1、SpringMVC的异常处理

@Controller
public class ExceptionController {
    @RequestMapping("/test1")
    public void test1() {
        throw new RuntimeException("666");
    }

    @RequestMapping("/test2")
    public void test2() throws Exception{
        throw new ClassNotFoundException("777");
    }

    @RequestMapping("/test3")
    public void test3() throws Exception{
        throw new IOException("777");
    }
}
2.2、SpringMVC可以对异常信息做统一处理,主要有4种方式

1、使用SpringMVC自带的异常处理类:SimpleMappingExceptionResolver

<!--    异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.RuntimeException">/WEB-INF/page/rumtime.jsp</prop>
            <prop key="java.io.IOException">/WEB-INF/page/io.jsp</prop>
            <prop key="java.lang.ClassNotFoundException">/WEB-INF/page/not.jsp</prop>
        </props>
    </property>
<!--        异常对象的属性名(可以通过EL表达式访问)-->
    <property name="exceptionAttribute" value="ex" />
<!--        其他错误页面异常-->
    <property name="defaultErrorView" value="/WEB-INF/page/error.jsp" />
</bean>

2、自定义异常处理类:实现HandlerExceptionResolver接口

@Component
public class MyExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response,
                                         Object handler,
                                         Exception ex) {
        HandlerMethod method = (HandlerMethod)handler;
        method.getMethod();
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex", ex);
        mv.setViewName("/WEB-INF/page/error.jsp");
        return mv;
    }
}

3、使用注解:@ExceptionHandler
@ExceptionHandler方法、出现异常的方法,必须处在同一个controller

@ExceptionHandler({ArithmeticException.class, IOException.class})
public ModelAndView resolveException1(Exception ex) {
    ModelAndView mv = new ModelAndView();
    mv.addObject("ex", ex);
    mv.setViewName("/WEB-INF/page/rumtime.jsp");
    return mv;
}
// 处理其他异常
@ExceptionHandler()
public ModelAndView resolveException2(Exception ex) {
    ModelAndView mv = new ModelAndView();
    mv.addObject("ex", ex);
    mv.setViewName("/WEB-INF/page/error.jsp");
    return mv;
}

4、使用@ExceptionHandler + @ControllerAdvice

@ControllerAdvice
public class MyExceptionResolver2 {
    @ExceptionHandler({ArithmeticException.class, IOException.class})
    public ModelAndView resolveException1(Exception ex) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex", ex);
        mv.setViewName("/WEB-INF/page/rumtime.jsp");
        return mv;
    }

    @ExceptionHandler()
    public ModelAndView resolveException2(Exception ex) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("ex", ex);
        mv.setViewName("/WEB-INF/page/error.jsp");
        return mv;
    }
}

controllerAdvice可以通过属性设置它的处理范围
basePackagesbasePackageClassesassignableTypesannotations

3、拦截器(Interceptor

拦截器(Interceptor)的功能,跟过滤器(Filter)有点类似,但是有本质区别的
1、过滤器
Servlet规范的一部分
能拦截任意请求,在请求抵达Servlet之前、响应抵达客户端之前拦截
常用于:编码设置、登录校验等
2、拦截器
SpringMVC的一部分
只能拦截DispatchServlet拦截到的内容,一般用来拦截controller
常用于:抽取controller的公共代码
配置

<mvc:interceptors>
    <mvc:interceptor>
<!--            需要拦截的路径可以写多个-->
<!--            **代表当前目录下的所有内容(包括子目录)-->
        <mvc:mapping path="/**"/>
<!--            排除asset目录的所有内容-->
        <mvc:exclude-mapping path="/asset/**"/>
<!--            排除所有html-->
        <mvc:exclude-mapping path="/**/*.html"/>
        <bean class="com.sj.interceptor.MyInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>
3.1、HandlerInterceptor方法解析

1、preHandle:在controller的处理方法之前调用
一般在这里进行初始化、请求预处理操作
如果返回false,那么后序将不会在调用controller的处理方法、postHandle\afterCompletion方法
当多个拦截器时,这个方法按照逆序执行
2、postHandle:在controller的处理反复之后、在DispatcherServlet进行视图渲染之前调用
一般在这里进行请求后续加工处理操作
当有多个拦截器时,这个方法按照逆序执行
3、afterCompletion:在DispatcherServlet进行视图渲染之后调用
一般在这里进行资源回收操作
当有多个拦截器时,这个方法按照逆序执行

public class MyInterceptor implements HandlerInterceptor, BeanPostProcessor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle -" + request.getRequestURI());
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle - " + request.getRequestURI());
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

4、SpringMVC的执行流程

4.1、源码解读

继承关系 DispatcherServlet继承FrameworkServlet继承HttpServletBean继承HttpServlet
1、首先调用FrameworkServlet - service方法,在调用父类super.service方法
2、父类HttpServlet - service方法,在调用doGet方法,HttpServlet为抽象类,会调用子类的实现方法
3、子类FrameworkServlet - doGet方法调用,在调用processRequest方法,在调用doService方法,doService为抽象方法,会调用子类的实现方法。
4、子类DispatcherServlet - doService方法,然后再调用doDispatch方法

4.2、springMVC的执行流程图
执行流程图
上一篇 下一篇

猜你喜欢

热点阅读