八邑商、Servlet 3.0注解

Servlet 3.0注解

在Servlet 3.0之后摄咆,為了簡(jiǎn)化Servlet開(kāi)發(fā),Servlet的API人断,提供了注解吭从,用于簡(jiǎn)化Servlet的配置。

常用注解如下:

注解 說(shuō)明
@WebServlet 用于取代Servlet的xml配置
@WebFilter 用于取代Filter的xml配置
@WebListener 用于取代Lsitener的xml配置
@WebInitParam 用于取代xml中初始化參數(shù)的配置
@MultipartConfig 用于標(biāo)識(shí)該Servlet支持文件上傳

@WebServlet

? name : 表示 servlet的名稱(chēng) 默認(rèn)空字符串

? value/urlPatterns : 表示servlet的映射地址 格式是數(shù)組 表示servlet支持多個(gè)映射地址恶迈,直接可以在注解不聲明任何屬性涩金,進(jìn)行賦值,值是默認(rèn)給value屬性暇仲。

loadOnStartup : servlet 初始化的時(shí)機(jī)

initParams : servlet初始化參數(shù) 值類(lèi)型是:WebInitParam

@WebServlet(value = "test.do", loadOnStartup = 1, 
initParams = { @WebInitParam(name = "name1", value = "value1"),
        @WebInitParam(name = "name2", value = "value2") })
public class TestServlet extends HttpServlet {

    private static final long serialVersionUID = -4744875954442714537L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello  servlet  3.0");
    }
    
}

注意:

不推薦使用 initParams注解鸭廷,雖然initParams能夠取代xml配置,但是實(shí)際上沒(méi)有任何意義熔吗。因?yàn)?strong>initParams可以通過(guò)@WebInitParam配置初始化參數(shù)辆床,但是這種配置方式是寫(xiě)在類(lèi)中,然后在方法里面,獲取配置對(duì)象ServletConfig進(jìn)行獲取值桅狠,再進(jìn)行相關(guān)操作讼载。那么,為什么不直接在程序中使用這個(gè)值中跌,而是獲取類(lèi)上面的數(shù)據(jù)值?

@WebFilter

? filterName : filter的別名可以缺省

? value/urlPatterns : 過(guò)濾器過(guò)濾的地址規(guī)則

? servletNames : 過(guò)濾過(guò)濾的servlet的名稱(chēng) 標(biāo)識(shí)這個(gè)filter 只過(guò)濾指定的servlet咨堤,其它請(qǐng)求不過(guò)濾

initParams :與servlet中的initParams參數(shù)一樣,標(biāo)識(shí)初始化參數(shù)

package com.sxt.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;


@WebFilter(value = {"/*"})
public class TestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("攔截器");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        
    }

}

@WebListener

package com.sxt.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class ApplicationListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("銷(xiāo)毀");
    }

}

@MultipartConfig

如果Servlet需要接收文件上傳的流數(shù)據(jù)漩符,需要在Servlet的類(lèi)上面一喘,使用@MultipartConfig注解進(jìn)行標(biāo)識(shí),

因?yàn)镾ervlet底層嗜暴,會(huì)對(duì)請(qǐng)求的參數(shù)凸克,根據(jù)這個(gè)標(biāo)識(shí)進(jìn)行特殊封裝。

4.Servlet版文件上傳

在web中闷沥,實(shí)現(xiàn)文件上傳萎战,有以下要求

  1. 提交數(shù)據(jù)的form表單,必須含有:enctype="multipart/form-data"

  2. form表單的提交請(qǐng)求的方式舆逃,必須是post請(qǐng)求

  3. 處理文件上傳的Servlet蚂维,必須使用@MultipartConfig注解修飾

文件上傳對(duì)相關(guān)API

package com.sxt.controller;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * @ClassName: UploadController 
 * @Description: 因?yàn)檫@個(gè)Servlet 要處理文件上傳的 文件數(shù)據(jù)  必須使用 @MultipartConfig 修飾
 * @author: Mr.T
 * @date: 2020年2月17日 下午4:14:23
 */
@WebServlet("/upload.do")
@MultipartConfig
public class UploadController extends HttpServlet {

    private static final long serialVersionUID = -5139866113909465871L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 注意 輸入框的數(shù)據(jù)   輸入框是普通的文本數(shù)據(jù)
        String fileName = req.getParameter("fileName");
        System.out.println("輸入框的數(shù)據(jù):"+fileName);
        //獲取文件流數(shù)據(jù)  使用getPart("name")
        //此時(shí) 返回  part 對(duì)象  這個(gè)part 里面封裝了所有跟文件數(shù)據(jù)相關(guān)數(shù)據(jù)
        Part part = req.getPart("file");
        //文件的大小
        System.out.println(part.getSize());
        //文件類(lèi)型的請(qǐng)求頭的中的值  : 例如 : map3 具體格式   --媒體類(lèi)型 :audio/mpeg
        System.out.println(part.getContentType());
        //此時(shí)getName  是獲取表單中 input的name屬性值 沒(méi)有意義  不是文件的名稱(chēng)
        String name = part.getName();
        System.out.println("input中的name值:"+name);
        //獲取 上傳的文件數(shù)據(jù)流
        //既然part 已經(jīng)提供了持久化的方法  為了還提供一個(gè)獲取輸入流數(shù)據(jù)的方法?
        //因?yàn)?此時(shí)當(dāng)前輸入流中的數(shù)據(jù)就是整個(gè)文件的流數(shù)據(jù),可以輸出到任何地方路狮。
        //更加靈活,注意  inputStream 也支持保存到本地
        InputStream in = part.getInputStream();
        /*
        byte[] b = new byte[1024];
        int len = -1;
        FileOutputStream  fos = new FileOutputStream("F:\\2.jpg");
        while((len = in.read(b)) != -1) {
            fos.write(b, 0, len);
            fos.flush();
        }
        fos.close();
        in.close();
        */
        //如何獲取文件的真實(shí)名稱(chēng) 和文件后綴 
        // 獲取上傳數(shù)據(jù)的對(duì)應(yīng)的請(qǐng)求頭信息  
        // 根據(jù) Content-Disposition 整個(gè)請(qǐng)求頭  獲取上傳文件的名稱(chēng)相關(guān)信息
        String header = part.getHeader("Content-Disposition");
        //form-data; name="file"; filename="2.jpeg"
        //現(xiàn)在需要獲取字符串中 : filename = 后面的值
        System.out.println("文件的真實(shí)名稱(chēng):"+getFileName(part));
        System.out.println("文件真實(shí)名稱(chēng)相關(guān)信息:"+header);
        //將上傳的文件數(shù)據(jù)進(jìn)行持久化
        part.write("F:\\1.jpg");
    }
    
    
    /**
     * @Title: getFileName
     * @author: Mr.T   
     * @date: 2020年2月17日 下午4:48:49 
     * @Description: 獲取文件的原名稱(chēng)
     * @param part
     * @return
     * @return: String
     */
    private String  getFileName(Part part) {
        // 由于文件的原名稱(chēng) 在請(qǐng)求頭中
        String header = part.getHeader("Content-Disposition");
        //form-data; name="file"; filename="2.jpeg"
        String[] info = header.split(" ");
        //從數(shù)組中獲取原名稱(chēng)相關(guān)信息 :filename="2.jpeg"
        String name = info[2].trim();
        name = name.substring(10 , name.length() - 1);
        return name;
    }
}

文件上傳的路徑問(wèn)題

package com.sxt.controller;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

/**
 * @ClassName: UploadController 
 * @Description: 因?yàn)檫@個(gè)Servlet 要處理文件上傳的 文件數(shù)據(jù)  必須使用 @MultipartConfig 修飾
 * @author: Mr.T
 * @date: 2020年2月17日 下午4:14:23
 */
@WebServlet("/upload2.do")
@MultipartConfig
public class UploadController2 extends HttpServlet {

    private static final long serialVersionUID = -5139866113909465871L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 注意 輸入框的數(shù)據(jù)   輸入框是普通的文本數(shù)據(jù)
        String fileName = req.getParameter("fileName");
        System.out.println("輸入框的數(shù)據(jù):"+fileName);
        //獲取文件流數(shù)據(jù)  使用getPart("name")
        //此時(shí) 返回  part 對(duì)象  這個(gè)part 里面封裝了所有跟文件數(shù)據(jù)相關(guān)數(shù)據(jù)
        Part part = req.getPart("file");
     
        //將圖片保存在F盤(pán),沒(méi)有問(wèn)題,但是此時(shí)圖片不能查看虫啥。因?yàn)镕盤(pán)不在tomcat 服務(wù)器中,
        //瀏覽器只能訪問(wèn)到項(xiàng)目的目錄中的文件
        //而目前F 盤(pán) 不屬于項(xiàng)目的中文件夾,所以瀏覽器是訪問(wèn)不到的。
        //所以一般圖片需要保存在服務(wù)器中: 保存在服務(wù)器中,就會(huì)有2個(gè)路徑奄妨。
        //1. 文件的物理路徑    是具體保存文件的路徑  用于文件下載
        //2. 文件的網(wǎng)絡(luò)訪問(wèn)路徑   是用于在瀏覽器中訪問(wèn)這個(gè)文件的路徑
        // 要將文件保存到物理磁盤(pán)上,所以要有文件的物理路徑
        //獲取img的物理路徑 
        String realPath = req.getServletContext().getRealPath("img");
        //生成文件的物理路徑
        // File.separator 路徑分割符    因?yàn)椴煌牟僮飨到y(tǒng)  分割符存在差異    win \  linux /
        String filePath = realPath + File.separator + getFileName(part);
        System.out.println("文件具體保存路徑:"+filePath);
        //保存文件
        part.write(filePath);
        //要有圖片的URL地址  網(wǎng)絡(luò)訪問(wèn)路徑
        String url = "/img/"+getFileName(part);
        System.out.println(url);
        //注意: 保存的文件名稱(chēng)  不建議使用 文件的原名稱(chēng)涂籽,因?yàn)榭赡艹霈F(xiàn)覆蓋,
        //所以一般保存的文件名稱(chēng)有一套生成文件名稱(chēng)的策略
        // 如: 使用UUID作為文件名稱(chēng)
        // 如:時(shí)間戳+隨機(jī)數(shù)  作為文件名稱(chēng)  等等 
    }
    
    
    /**
     * @Title: getFileName
     * @author: Mr.T   
     * @date: 2020年2月17日 下午4:48:49 
     * @Description: 獲取文件的原名稱(chēng)
     * @param part
     * @return
     * @return: String
     */
    private String  getFileName(Part part) {
        // 由于文件的原名稱(chēng) 在請(qǐng)求頭中
        String header = part.getHeader("Content-Disposition");
        //form-data; name="file"; filename="2.jpeg"
        String[] info = header.split(" ");
        //從數(shù)組中獲取原名稱(chēng)相關(guān)信息 :filename="2.jpeg"
        String name = info[2].trim();
        name = name.substring(10 , name.length() - 1);
        return name;
    }
    

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市展蒂,隨后出現(xiàn)的幾起案子又活,更是在濱河造成了極大的恐慌苔咪,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柳骄,死亡現(xiàn)場(chǎng)離奇詭異团赏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)耐薯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)舔清,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人曲初,你說(shuō)我怎么就攤上這事体谒。” “怎么了臼婆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵抒痒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我颁褂,道長(zhǎng)故响,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任颁独,我火速辦了婚禮彩届,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘誓酒。我一直安慰自己樟蠕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布靠柑。 她就那樣靜靜地躺著寨辩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪病往。 梳的紋絲不亂的頭發(fā)上捣染,一...
    開(kāi)封第一講書(shū)人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音停巷,去河邊找鬼。 笑死榕栏,一個(gè)胖子當(dāng)著我的面吹牛畔勤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扒磁,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼庆揪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了妨托?” 一聲冷哼從身側(cè)響起缸榛,我...
    開(kāi)封第一講書(shū)人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吝羞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后内颗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體钧排,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年均澳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恨溜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡找前,死狀恐怖糟袁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情躺盛,我是刑警寧澤项戴,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站槽惫,受9級(jí)特大地震影響肯尺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜躯枢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一则吟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锄蹂,春花似錦氓仲、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至朝抖,卻和暖如春啥箭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背治宣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工急侥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侮邀。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓坏怪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親绊茧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铝宵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容