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)系作者
  • 序言:七十年代末渐溶,一起剝皮案震驚了整個(gè)濱河市辉浦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茎辐,老刑警劉巖宪郊,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拖陆,居然都是意外死亡弛槐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門依啰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乎串,“玉大人,你說我怎么就攤上這事速警√居” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵闷旧,是天一觀的道長长豁。 經(jīng)常有香客問我,道長忙灼,這世上最難降的妖魔是什么匠襟? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任钝侠,我火速辦了婚禮,結(jié)果婚禮上酸舍,老公的妹妹穿的比我還像新娘帅韧。我一直安慰自己,他們只是感情好啃勉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布忽舟。 她就那樣靜靜地躺著,像睡著了一般璧亮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斥难,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天枝嘶,我揣著相機(jī)與錄音,去河邊找鬼哑诊。 笑死群扶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的镀裤。 我是一名探鬼主播竞阐,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼暑劝!你這毒婦竟也來了骆莹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤担猛,失蹤者是張志新(化名)和其女友劉穎幕垦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體傅联,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡先改,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒸走。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仇奶。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖比驻,靈堂內(nèi)的尸體忽然破棺而出该溯,到底是詐尸還是另有隱情,我是刑警寧澤别惦,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布朗伶,位于F島的核電站,受9級(jí)特大地震影響步咪,放射性物質(zhì)發(fā)生泄漏论皆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望点晴。 院中可真熱鬧感凤,春花似錦、人聲如沸粒督。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屠橄。三九已至族跛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锐墙,已是汗流浹背礁哄。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溪北,地道東北人桐绒。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像之拨,于是被迫代替她去往敵國和親茉继。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355