SpringMVC使用-续

转发和重定向

除了视图解析器配合返回字符串的方法:

使用request和response

@RequestMapping("/test")
public void testRedir(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //使用request转向页面
    request.getRequestDispatcher("/WEB-INF/pages/success.jsp")
    .forward(request,response);
    //使用response重定向
    response.sendRedirect("testRetrunString");
    //使用response指定响应结果
    response.setCharacterEncoding("utf-8");
    response.setContentType("application/json;charset=utf-8");
    response.getWriter().write("json 串");
}

使用返回字符串关键字

@RequestMapping("/testForward")
public String testForward() {
    System.out.println("AccountController 的 testForward 方法执行了。。。。");
    return "forward:/WEB-INF/pages/success.jsp";
}

@RequestMapping("/testRedirect")
public String testRedirect() {
    System.out.println("AccountController 的 testRedirect 方法执行了。。。。");
    return "redirect:testReturnModelAndView";
}

ResponseBody 响应 json 数据

该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如:json,xml 等,通过 Response 响应给客户端

Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要加入
jackson 的包。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

示例:

@RequestMapping("/testResponseJson")
public @ResponseBody Account testResponseJson(@RequestBody Account account) {
    System.out.println("异步请求:"+account);
    return account;
}

前一个@ResponseBody返回的时候转换为json,后一个@ResponseBody接收请求时转换为对象。

文件上传和下载

文件上传

这里的文件上传用的是multipart/form-data

当 form 表单的 enctype 取值为 Mutilpart/form-data 时,请求正文内容就变成:
每一部分都是 MIME 类型描述的正文

-----------------------------7de1a433602ac 分界符
Content-Disposition: form-data; name="userName" 协议头
aaa 协议的正文
-----------------------------7de1a433602ac
Content-Disposition: form-data; name="file";
filename="C:\Users\admin\Desktop\fileupload_demofile\b.txt"
Content-Type: text/plain 协议的类型(MIME 类型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-----------------------------7de1a433602ac--

Apache Commoms里的两个工具类

  • commons-fileupload-xxx.jar
  • commons-io-xxx.jar

(如果是maven项目只需要添加commons-fileupload依赖)

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

配置文件上传处理Bean

spring-mvc.xml配置

<!-- 配置文件上传解析器 -->
<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置上传文件的最大尺寸为 5MB -->
    <property name="maxUploadSize">
    <   value>5242880</value>
    </property>
</bean>

文件上传处理Controller

@Controller
@RequestMapping("/file")
public class FileController {
    @RequestMapping("/initFileUpload")
    public String initFileUpload(){
        return "FileUpload";
    }
    @RequestMapping()
    public String fileUpLoad(String name, @RequestParam("file")CommonsMultipartFile file, HttpSession session){
        if(!file.isEmpty()){
            String path = session.getServletContext().getRealPath("/upload");
            String fileName = file.getOriginalFilename();
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            File targetFile = new File(path,new Date().getTime()+fileType);
            try {
                file.getFileItem().write(targetFile);
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "FileUpload";
    }
}

文件下载

可先获取下载文件的输入流,并将输入流读入缓冲流BufferedInputStream,最后将缓冲流通过循环的方式写入到response的输出流实现文件下载功能。

public void fileDownLoad(HttpSession session, HttpServletResponse response,String fileName,boolean isOnline) throws Exception{
    String path = session.getServletContext().getRealPath("/upload")+"\\"+fileName;
    File file = new File(path);
    System.out.println(path);
    if(!file.exists()){
        response.sendError(404,"您要下载的文件没找到");
        return;
    }
    BufferedInputStream bufIn = new BufferedInputStream(new FileInputStream(file));
    byte[] buff = new byte[1024];
    int len = -1;
    response.reset();
    if(isOnline){
        URL u = new URL("file:///"+path);
        response.setContentType(u.openConnection().getContentType());
        response.setHeader("Content-Disposition","inline;filename="+fileName);
    }else{
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition","attachment;filename="+fileName);
    }
    OutputStream out = response.getOutputStream();
    while ((len=bufIn.read(buff))!=-1){
        out.write(buff,0,len);
        out.flush();
    }
    bufIn.close();
    out.close();
}

异常处理

系统的 dao、service、controller 出现都通过 throws Exception 向上抛出,最后由 SpringMVC 前端控制器交由异常处理器进行异常处理。

SpringMVC使用-续
  1. 编写自定义异常类
public class SysException extends Exception{

    //存储提示信息
    private String message;

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SysException(String message) {
        this.message = message;
    }
}
  1. 编写异常处理器
public class SysExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //获取异常对象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException) ex;
        }else {
            e = new SysException("系统正在维护");
        }
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",e.getMessage());
        mv.setViewName("error");
        return mv;
    }
}
  1. 配置异常处理器(跳转到提示页面)
<!-- 配置异常处理器 -->
<bean id="sysExceptionResolver" class="com.rhett.exception.SysExceptionResolver"></bean>

SpringMVC中的拦截器

  • 过滤器是 servlet 规范中的一部分,任何 java web 工程都可以使用。
  • 拦截器是 SpringMVC 框架自己的,只有使用了 SpringMVC 框架的工程才能用。
  • 过滤器在 url-pattern 中配置了/*之后,可以对所有要访问的资源拦截。
  • 拦截器它是只会拦截访问的控制器方法,如果访问的是 jsp,html,css,image 或者 js 是不会进行拦截的。

它也是 AOP 思想的具体应用。

我们要想自定义拦截器, 要求必须实现 HandlerInterceptor 接口。

public class HandlerInterceptorDemo1 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler) throws Exception {
        System.out.println("preHandle 拦截器拦截了");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, 
    HttpServletResponse response,
    Object handler,ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle 方法执行了");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion 方法执行了");
    }
}

HandlerInterceptor接口中的方法:

  1. preHandle方法是controller方法执行前拦截的方法
    1. 可以使用request或者response跳转到指定的页面
    2. return true放行,执行下一个拦截器,如果没有拦截器,执行controller中的方法。
    3. return false不放行,不会执行controller中的方法。
  2. postHandle是controller方法执行后执行的方法,在JSP视图执行前。
    1. 可以使用request或者response跳转到指定的页面
    2. 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示。
  3. postHandle方法是在JSP执行后执行
    1. request或者response不能再跳转页面了

配置拦截器:

<!-- 配置拦截器 -->
<mvc:interceptors>
    <mvc:interceptor>
        <!-- 要拦截的方法 -->
        <mvc:mapping path="/**"/>
        <!-- 不要拦截的方法 -->
        <!-- <mvc:exclude-mapping path=""/> -->
        <!-- 配置拦截器对象-->
        <bean id="handlerInterceptorDemo1"
                class="com.rhett.interceptor.MyInterceptor1"></bean>
    </mvc:interceptor>
</mvc:interceptors>

若配置多个拦截器形成拦截器链,按配置顺序执行。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/springmvc%e4%bd%bf%e7%94%a8-%e7%bb%ad/