SSM框架之SpringMVC進(jìn)階(二)

一、響應(yīng)數(shù)據(jù)和結(jié)果視圖

1. 返回值分類之:字符串

controller方法返回字符串可以指定邏輯視圖名,通過視圖解析器解析為物理視圖地址。

2. 返回值分類之:void

Servlet原始Api可作為控制器中方法的參數(shù),在Controller方法形參上定義request和response,使用request和response指定響應(yīng)結(jié)果。

3. 返回值分類之:ModelAndView對(duì)象

ModelAndView是spring提供的一個(gè)對(duì)象,可以用來調(diào)整具體的JSP視圖。

二、響應(yīng)之轉(zhuǎn)發(fā)和重定向

  • forward轉(zhuǎn)發(fā):
    Controller方法在提供了String類型的返回值之后,默認(rèn)就是請(qǐng)求轉(zhuǎn)發(fā)。
    需要注意的是:如果用了formward,則路徑必須寫成實(shí)際視圖url,不能寫邏輯視圖。
    //相當(dāng)于
    request.getRequestDispatcher("url").forward(request,response)
    
    使用請(qǐng)求轉(zhuǎn)發(fā),既可以轉(zhuǎn)發(fā)到j(luò)sp,也可以轉(zhuǎn)發(fā)到其他的控制器方法。
  • redirect重定向


三、ResponseBody響應(yīng)json數(shù)據(jù)

DispatcherServlet會(huì)攔截到所有的資源,導(dǎo)致一個(gè)問題就是靜態(tài)資源(img,css,js)也會(huì)被攔截到,從而不能被使用。解決問題就是需要配置靜態(tài)資源不進(jìn)行攔截。
在SpringMvc.xml配置文件中添加如下配置:

     <!--前端控制器,配置那些資源不用攔截    -->
    <mvc:resources mapping="/js/**" location="/js/"/>
    <mvc:resources mapping="/images/**" location="/images/"/>
    <mvc:resources mapping="/css/**" location="/css/"/>
  • 使用@ResponseBody注解實(shí)現(xiàn)將controller方法返回對(duì)象轉(zhuǎn)換為json響應(yīng)給客戶端。


  
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.10.0</version>
    </dependency>

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

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

二、SpringMVC實(shí)現(xiàn)文件上傳

1. 文件上傳的必要前提

  • form表單的enctype取值必須是:multipart/form-data(默認(rèn)值是:application/x-www-from-urlencoded)
    enctype:是表單請(qǐng)求正文的類型。
  • method屬性取值必須是post
  • 提供一個(gè)文件選擇域
    <input  type = "file" />
    

2.文件上傳的原理屬性:

  • 當(dāng)form表單的enctype取值不是默認(rèn)后,request.getParameter()將失效。enctype="application/x-www-form-urlencoded"時(shí),form表單的正文內(nèi)容是:key=value&key=value&key=value
  • 當(dāng)form表單的enctype取值為Mutilpart/form-data時(shí),請(qǐng)求正文內(nèi)容就會(huì)變成:
    每一部分都是MIME類型描述的正文。
  • 借助第三方組件實(shí)現(xiàn)文件上傳:
    使用Commons-fileUpload組件實(shí)現(xiàn)文件上傳,需要導(dǎo)入該組件相應(yīng)的jar包:Commons-fileupload和Commons-io。commons-io不屬于文件上傳組件開發(fā)的jar文件,但Commons-fileUpload組件從1.1版本開始,它工作時(shí)需要commons-io包的支持。


3. jsp文件上傳表單的實(shí)現(xiàn)

 <h3>文件上傳</h3>

    <form action="file/upload" method="post" enctype="multipart/form-data">
        選擇上傳文件:<input type="file" name="upload"/><br/>
        <input type="submit" value="上傳"/>

    </form>

4. SpringMVC中文件解析器的配置

<!--配置文件解析器
       文件上傳的id是固定的,不能起別的名稱,否則無法實(shí)現(xiàn)請(qǐng)求參數(shù)的綁定。
       -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>
    </bean>

5. 文件上傳代碼實(shí)現(xiàn)

package com.seapp.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.RequestPartServletServerHttpRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * @author seapp
 * @date 2020/8/3 23:14
 */
@Controller
@RequestMapping("/file")
public class FileUploadController {

    /**
     * 實(shí)現(xiàn)文件上傳
     *
     * @return
     */
    @RequestMapping("/upload")
    public String fileUpload(HttpServletRequest request, MultipartFile upload) throws IOException {
        System.out.println("SpringMVC文件上傳開始");

        //獲取文件上傳路徑
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        //判斷該文件是否存在,不存在則創(chuàng)建該文件
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }

        //獲取上傳文件信息
        String filename = upload.getOriginalFilename();
        //把文件的名稱設(shè)置唯一值,uuid
        filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;
        //完成文件上傳
        upload.transferTo(new File(path,filename));
        return "success";
    }
}

6.SpirngMVC跨服務(wù)器方式實(shí)現(xiàn)文件上傳

  • 三方訪問依賴的引入:
  <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-core</artifactId>
      <version>1.18.1</version>
    </dependency>

    <dependency>
      <groupId>com.sun.jersey</groupId>
      <artifactId>jersey-client</artifactId>
      <version>1.18.1</version>
    </dependency>
  • 文件跨服務(wù)傳輸?shù)木唧w實(shí)現(xiàn):

    /**
     * 實(shí)現(xiàn)文件上傳
     *
     * @return
     */
    @RequestMapping("/upload")
    public String fileUpload(HttpServletRequest request, MultipartFile upload) throws IOException {
        System.out.println("SpringMVC文件上傳開始");

        String path = "http://localhost:8090/uplods/";
        //獲取上傳文件信息
        String filename = upload.getOriginalFilename();
        //把文件的名稱設(shè)置唯一值,uuid
        filename = UUID.randomUUID().toString().replace("-", "") + "_" + filename;

        //創(chuàng)建客戶端對(duì)象
        Client client = Client.create();
        WebResource webResource = client.resource(path + filename);
        //完成文件上傳
        webResource.put(upload.getBytes());

        return "success";
    }

三、SpringMVC中的異常處理

1. 自定義異常類(做提示信息的)

package com.seapp.exception;

/**

  • 自定義異常處理類
  • @author seapp
  • @date 2020/8/4 15:53
    */
    public class SysException extends Exception {
private String message;

public SysException(String message) {
    this.message = message;
}

public String getMessage() {
    return message;
}

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

}

2. 編寫異常處理器

package com.seapp.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 異常處理器
 * @author seapp
 * @date 2020/8/4 15:57
 */
public class SysExceptionResolver implements HandlerExceptionResolver {
    /**
     * 異常處理邏輯
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
                                         Object handler, Exception ex) {

        //獲取異常對(duì)象
        SysException e = null;
        if(ex instanceof SysException){
            e = (SysException) ex;
        }else {
            e  = new SysException("系統(tǒng)正在維護(hù)...");
        }

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("errorMsg",e.getMessage());
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

3. 配置異常處理器(跳轉(zhuǎn)到友好處理界面 )


    <!--配置異常處理器    -->
    <bean id="sysExceptionResolver" class="com.seapp.exception.SysExceptionResolver"/>

四、SpringMVC中的攔截器

1. 攔截器

  • Spring MVC的處理器攔截器類似于Servlet開發(fā)中的過濾器Filter,用于對(duì)處理器進(jìn)行預(yù)處理和后處理。
  • 用戶可以自己定義一些攔截器來實(shí)現(xiàn)特定功能。
  • 談到攔截器,還要向大家提一個(gè)詞——攔截器鏈(Interceptor Chain)。攔截器鏈就是將攔截器聯(lián)結(jié)成一條鏈。在訪問被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。
  • 過濾器與攔截器的區(qū)別:
    ①:過濾器是Servlet規(guī)范中的一部分,任何Java web工程都可以使用。
    ②:攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能用。
    ③:過濾器在url-pattern中配置了/*之后,可以對(duì)所有要訪問的資源進(jìn)行攔截。
    ④:攔截器它是只會(huì)攔截訪問的控制器方法,如果訪問的是jsp、html、css、image或者js是不會(huì)進(jìn)行攔截的。
  • 它也是AOP思想的具體應(yīng)用。
  • 我們要想自定義攔截器,要求必須實(shí)現(xiàn)"HandlerInterceptor"接口。

2.攔截器實(shí)現(xiàn)

  • 編寫攔截器,實(shí)現(xiàn)HandlerInterceptor接口
package com.seapp.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定義攔截器
 * @author seapp
 * @date 2020/8/4 16:47
 */
public class MyInterceptor  implements HandlerInterceptor {

    /**
     * 攔截器預(yù)處理
     * @param request
     * @param response
     * @param handler
     * @return
     *      true:放行,若攔截鏈中還有攔截器,則執(zhí)行下個(gè)攔截器。若沒有,則執(zhí)行Controller中的方法
     *      false:攔截。使用request/response參數(shù),直接跳轉(zhuǎn)至指定界面。
     *
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        return true;
    }

    /**
     * 后處理的方法
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 最后執(zhí)行的方法
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {

    }
}

  • 配置攔截器(springmvc.xml)
 <!--配置攔截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--要攔截的方法-->
            <mvc:mapping path="/user/**"/>
            <!--不要攔截的方法-->
<!--        <mvc:exclude-mapping path="/**"/>-->
            <!--配置攔截器對(duì)象-->
            <bean class="com.seapp.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容