不怕千萬人阻擋,就怕本身投降。html
概念:運行在服務器端的小程序
servlet就是一個接口,定義了Java類被瀏覽器訪問到(tomcat識別)的規則。未來咱們自定義一個類,實現servlet接口,複寫方法。因此servlet就是實現了Servlet接口的類。前端
1.建立javaEE項目java
2.定義一個類,實現servlet接口public class servletDemo1 implements servlet
mysql
3.實現接口中的抽象方法web
4.配置Servlet,在xml中配置。sql
<servlet><servlet-name>demo1</ servlet-name><servlet-class>cn.itcast.web. servlet.ServletDemo1</servlet-class>< / servlet><servlet-mapping><servlet-name>demo1</ servlet-name><url-pattern>/demo1</url-pattern>< / servlet-mapping>
執行原理:
1,當服務器接受到客戶端瀏覽器的請求後,會解析請求uRL路徑,獲取訪問的servlet的資源路徑2.查找web.xml文件,足否有對應的<url-pattern>
標籤體內容。
3.若是有,則在找到對應的<servlet-class>
全類名
4. tomcat會將字節碼文件加載進內存,而且建立其對象
5,調用其方法。數據庫
servlet中的生命週期方法∶
1.被建立:執行init方法,只執行一次
對象被建立後再執行Servlet方法。apache
servlet何時被建立?小程序
默認狀況下,第一次被訪問時,servlet被建立。能夠配置其執行servlet的建立時機。後端
在<servlet>
標籤下配置
1,第一次被訪問時,建立<load-on-startup>
的值爲負數。
2.在服務器啓動時,建立<load-on-startup>
的值爲0或正整數。
Servlet的init方法,只執行一次,說明一個servlet在內存中只存在一個對象,Servlet是單例的。
多個用戶同時訪問時,可能存在線程安全問題。
解決∶儘可能不要在servlet中定義成員變量。即便定義了成員變量,也不要對修改值。
2.提供服務:執行service方法,執行屢次。
每次訪問Servlet時,Service方法都會被調用一次。
3.被銷燬:執行destroy方法,只執行一次。
servlet被銷燬時執行,服務器關閉時,Servlet被銷燬。
只有服務器正常關閉時,纔會執行destroy方法。
destroy方法在servlet被銷燬以前執行,通常用於釋放資源。
java6支持Serlet3.0.
java8支持Serlet4.0.
好處:支持註解配置。
能夠不須要web.xml。
步驟:
1.建立JavaEE項目,選擇Servelt3.0以上的,能夠不建立web.xml。
2.定義一個類,實現Servlet接口。
3.複寫方法。
4.在類上使用@WebServlet註解,進行配置。
由於註解是加在類上的,因此不須要關心類名,只須要關心資源路徑。
@WebServlet(urlPatterns="/demo")//能夠配置多個路徑public class ServletDemo implement Servlet{}
或者
@WebServlet("/demo")//能夠配置多個路徑public class ServletDemo implement Servlet{}
IDEA與tomcat的相關配置
1.IDEA會爲每個tomcat部署的項目單獨創建一份配置文件.
查看控制檯的log : Using CATALINA_BASE:「c: \users\fay.Intelli]Idea2018.1\system\tomcatl_itcast"
2.工做空間項目和 tomcat部署的web項目。
tomcat真正訪問的是"「tomcat部署的web項目」",「tomcat部署的web項目"對應着」"工做空間項目」的web目錄下的全部資源。
WEB-INF目錄下的資源不能被瀏覽器直接訪問。
GenericServlet是Servlet的子類(子);
HttpServlet是GenericServlet的子類(孫);
問題提出:有時候咱們只須要重寫Servlet的service方法。然而咱們繼承Servlet類必須實現Servlet的全部抽象方法。這樣就與咱們意願相左。有什麼解決辦法呢?
【解決辦法】:GenericServlet爲Servlet的子類,而且已經(空)實現了Servlet的4個方法,只有service方法沒有實現。
所以咱們能夠寫一個類,繼承GenericServlet抽象類。實現service方法便可。
未來咱們在定義本身的serlvet類時,能夠繼承抽象類GenericServlet便可,若是須要使用到其餘方法,重些該方法便可。
能夠看出,此時代碼書寫已經很方便,可是咱們之後開發並不使用這種方式。
那咱們使用哪一種方式呢?
【HttpServlet】:爲何要使用這個類呢?
那咱們得問本身,咱們實現service方法幹嗎呢?
咱們在寫service方法體時,須要判斷前端給後臺的請求方式,並根據其獲取數據。每次都須要判斷,有沒有一種方式,能夠簡潔的達到效果呢?
HttpServlet抽象類,幫咱們把這些事情都作好了,咱們只須要重寫HttpServlet對應得方法便可。
如:
doGet(){//重寫部分};doPost(){//重些部分};
所以咱們未來須要屏蔽請求方式的處理邏輯,繼承HttpServlet就顯得格外好用。
HttpSerlvet:對http協議的一種封裝,簡化操做。
所以咱們之後開發:就再也不定義類繼承GenericServlet實現service方法。而是定義類繼承HttpServlet重寫doGet(),或doPost()方法。
Servlet的urlpartten配置
由於urlpattten是一個數組,因此能夠爲其配置多個資源路徑
@WebServlet({"/d4","dd4","ff"})public class ServletDemo extends HttpServlet{}
一個servlet能夠設置多個訪問路徑。
路徑的定義規則
1./xxx2./xxx/xxx(多層路徑)(/xxx/*) 3.*.do
概念:Hyper Text Transfer Protocol超文本協議。
傳輸協議:定義了,客戶端和服務器端通訊超時,發送數據的格式。
請求和響應一一對應。
無狀態:每次請求之間相互獨立,不能交互數據。
歷史版本:
1.0:每一次請求響應都會創建新的鏈接(http1.0)
1.1:複用鏈接(http1.1)。
請求消息數據格式:
1.請求行
請求方式 請求url 請求協議/版本
GET /index.html HTTP/1.1
HTTP協議有7種請求方式。
GET:
(1.請求參數在請求行中,在url後。
(2.請求的url的長度有限制。
(3.不安全
POST:
(1.請求參數在請求體中。
(2.請求的url的長度沒有限制。
(3.相對安全
2.請求頭
請求頭名稱:請求頭值
常見的請求頭:
主機
User-Agent:瀏覽器告訴服務器,我訪問你使用的瀏覽器版本信息,能夠獲取其信息解決瀏覽器兼容性問題。
Accept:告訴服務器,我能夠解析的格式。
Referer:告訴服務器,當前請求從哪裏來。
做用:方式其餘人盜鏈。統計工做。
Connection:表示鏈接能夠複用。
3.請求空行
空行(分割POST的請求頭和請求體)
4.請求體
POST纔有請求體,封裝了POST的請求參數。
響應消息數據格式:
1.響應行
協議及版本 響應狀態碼 狀態碼描述
狀態碼:
1xx:服務器接收客戶端消息,但沒有接收完成,等待一段時間後,發送1xx狀態碼。
2xx:成功
3xx:302(重定向),304訪問緩存
4xx:客戶端錯誤,405沒有對應的方法。(doGet,doPost)
5xx:服務器端錯誤,500代碼錯誤,505服務器不支持客戶端使用的HTTP版本。
2.響應頭
頭名稱:值
常見的響應頭:
Content-Type:服務器告訴客戶端本次響應體數據格式以及編碼格式。
Content-disposition:服務器告訴客戶端以什麼格式打開響應體數據。
值:in-line默認值,在當前頁面內打開。
attachment:以附件形式打開響應體,文件下載。
3.響應空行
4.響應體
傳輸的數據。
1.request對象繼承體系結構:
ServletRequest —接口
繼承
HttpServletRequest —接口
實現
org.apache.catalina.connector.RequestFacade 類(tomcat實現了HttpServletRequest接口)
2.request和response的原理
1.request和response對象是由服務器建立的。咱們只是使用他們。
2.request對象是來獲取請求消息,response對象是來設置響應消息。
3.request的功能:
3.1獲取請求消息數據
獲取請求行數據
**1.1獲取請求方式**
String getMethod();//瞭解便可
**1.2獲取虛擬目錄**
String getContextPath();//重要
**1.3獲取Servlet路徑:**
String getServletPath();
**1.4獲取get方式請求參數:**
String getQueryString();//瞭解
**1.5獲取請求URI**
String getRequestURI(); 如:/day1/demo2
**1.6獲取請求URL**
StringBuffer getRequestURL(); 如: http://localhost/day1/demo2
**1.7獲取協議及版本**
String getProtocol();
**1.8獲取客戶機的IP地址**
String getRemoteAddr();
URI:統一資源標識符。(範圍更大)
URL:統一資源定位符。
獲取請求頭數據
String getHeader(String name);//經過請求頭的名稱獲取請求頭的值 Enumeration<String> getHeaderNames();//獲取全部的請求頭名稱
@WebServlet("/ServletTest2")public class ServletTest2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取全部請求頭名稱 Enumeration<String> headNames = request.getHeaderNames(); //遍歷 while (headNames.hasMoreElements()){ String name = headNames.nextElement(); //根據名稱獲取請求頭的值 String value = request.getHeader(name); System.out.println(name+"---"+value); } }}
獲取請求體數據
步驟:
1.獲取流對象
BufferedReader getReader() ;//獲取字符輸入流,只能操做字符數據 ServletInputStream getInputStream();//獲取字節輸入流,能夠操做全部 類型的數據(文件上傳)
2.再從流對象中拿數據
@WebServlet("/ServletTest3")public class ServletTest3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //獲取請求參數 //1.獲取字符流 BufferedReader br = request.getReader(); //讀取數據 String line = null; while ((line=br.readLine())!=null){ System.out.println(line); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { }}
3.2.其餘功能
1.獲取請求參數的通用方式(get和post均可以)
String getParameter(String name):根據參數名獲取參數值 String[] getParameterValues(String name):根據參數名獲取參數值的數組 (經常使用於複選框) Enumeration<String> getParameterNames():獲取全部請求參數名稱。 Map<String,String[]> getParameterMap():獲取全部參數的map集合。
優點:屏蔽了get和post方法的不一樣,代碼只須要寫一份,再另外一方法中調用另外一個已經實現的方法便可,知足get和post請求。
獲取請求參數中文亂碼的問題處理:
get方式:tomcat8已經將get方式亂碼問題解決了。
post方式:會亂碼。
解決方案:在獲取參數前,設置流的編碼。
request.setCharacterEncoding(「utf-8」);
//設置編碼request.setCharacterEncoding("utf-8");//獲取請求參數String username = request.getParameter("username");
2.請求轉發
一種在服務器內資源跳轉的方式。
步驟:
1.經過request對象獲取請求轉發器對象: RequestDispatcher getRequestDispatcher(String path)2.使用RequestDispatcher對象來進行轉發:forward(ServletRequest request,ServletResponse response)
特色:
瀏覽器地址欄路徑沒有發生變化。
只能訪問當前服務器內部資源中。
轉發是一次請求,多個資源使用同一個請求。
3.共享數據
域對象:一個有做用範圍的對象,能夠在範圍內共享數據。
request域:表明一次請求的範圍,通常用於請求轉發的多個資源中共享數據。
方法:
setAttribute(String name,Object obj);存儲數據 Object getAttitude(String name);經過鍵獲取值removeAttribute(String name)經過鍵移除值
例子:
@WebServlet("/ServletTest4")public class ServletTest4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("ServletTest4被訪問了"); //存儲數據到request域中 request.setAttribute("name","MengYangchen"); RequestDispatcher getquestDispatcher = request.getRequestDispatcher("/ServletTest5");//沒有虛擬路徑(項目) getquestDispatcher.forward(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
@WebServlet("/ServletTest5")public class ServletTest5 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("ServletTest5被訪問了"); //獲取數據 Object name = request.getAttribute("name"); System.out.println(name); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
結果:
4.獲取ServletContext(對象)
返回ServletContext對象
ServletContext getServletContext()
用戶登陸案例需求:
1.編寫login.html登陸頁面
username &password兩個輸入框
2.使用Druid數據庫鏈接池技術,操做mysql,day14數據庫中user表
3.使用JdbcTemplate技術封裝JDBC
4.登陸成功跳轉到SuccessServlet展現:登陸成功!用戶名,歡迎您
5.登陸失敗跳轉到FailServlet展現:登陸失敗,用戶名或密碼錯誤。
1.請求消息:客戶端發送給服務器的數據。
2.服務器端發送給客戶端的數據。
功能:設置響應消息。
1.設置響應行。
void setStatus(int sc) 設置狀態碼
2.設置響應頭。
void setHeader(String name, String value)
3.設置響應體。
獲取輸出流
PrintWriter getWriter() 字符輸出流 ServletOutputStream getOutputStream() 字節輸出流
使用輸出流,將數據輸出到客戶端瀏覽器。
1.完成重定向
@WebServlet("/ServletResponseTest1")public class ServletResponseTest1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("response1被訪問了"); //重定向,訪問ServletResponseTest1,會自動跳轉到ServletResponseTest2 //1.設置狀態碼302/* response.setStatus(302); //2.設置響應頭location response.setHeader("location","/First/ServletResponseTest2"); */ //簡單重定向方法 response.sendRedirect("/First/ServletResponseTest2");//有虛擬路徑 } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
@WebServlet("/ServletResponseTest2")public class ServletResponseTest2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("response2被訪問了"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
轉發的特色:
1.轉發地址欄路徑不變。
2.轉發只能訪問當前服務器下的資源。
3.轉發是一次請求。
4.路徑不須要帶虛擬路徑。
重定向的特色:
1.地址欄發生改變。
2.重定向能夠訪問其餘站點(服務器)的資源。
3.重定向是兩次請求。
4.路徑須要虛擬路徑。
2.服務器輸出字符數據到瀏覽器
亂碼緣由:編碼解碼用的編碼不一樣。
2.1.獲取字符輸出流。
//設置輸出流編碼response.setCharacterEncoding("utf-8");//告訴瀏覽器,服務器發送消息體數據的編碼,建議瀏覽器使用該編碼解碼response.setHeader("content-type","text/html;charset=utf-8");//簡單形式,設置編碼response.setContentType("text/html;charset=utf-8");PrintWrite out = response.getWriter();//tomcat返回的對象[ISO-8859-1]。
2.2輸出數據(不須要刷新)
out.write();
3.服務器輸出字節數據到瀏覽器
3.1獲取字節輸出流
3.2輸出數據
response.setContentType("text/html;charset=utf-8");ServletOutputStream out = response.getOutputStream();out.writer("你好".getBytes("utf-8"));
4.驗證碼
1.本質:圖片
2.目的:防止惡意表單註冊。
隨機生成。
後端:servlet:
@WebServlet("/IdentifyingCodeServlet")public class IdentifyingCodeServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 100; int height = 50; //1.建立一對象,在內存中的圖片(驗證碼圖片對象) BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //2.美化圖片 //2.1填充背景色 Graphics g = image.getGraphics(); g.setColor(Color.pink); g.fillRect(0,0,100,50);//填充矩形 //2.2畫邊框 g.setColor(Color.yellow); g.drawRect(0,0,width-1,height-1); String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; //生成隨機角標 Random ran = new Random(); for(int i=1;i<=4;i++){ int index = ran.nextInt(str.length()); char ch = str.charAt(index);//隨機字符 //2.3寫驗證碼 g.setColor(Color.blue); g.drawString(""+ch,width/5*i,height/2); } //2.4畫干擾線,防識別 //隨機生成座標點 for(int i=0;i<8;i++){ int x1 =ran.nextInt(width); int x2 =ran.nextInt(width); int y1 =ran.nextInt(height); int y2 =ran.nextInt(height); g.setColor(Color.green); g.drawLine(x1,y1,x2,y2); } //3.將圖片輸出到頁面展現 ImageIO.write(image,"jpg",response.getOutputStream()); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
前端頁面:
<body><h1>帳號註冊</h1><form action="/First/ServletTest3" method="post"> <input type="text" placeholder="請輸入用戶名" name="username"><br> <input type="password" placeholder="請輸入密碼" name="password"><br> <input type="submit" value="註冊"><br> <img id="checkCode" src="/First/IdentifyingCodeServlet"/> <a id="change" href="">看不清換一張</a></form> <script> //1.給超連接或圖片綁定單擊事件 //2.從新設置圖片的src屬性 window.onload = function () { var a =document.getElementById("change"); //1.獲取圖片對象 var img = document.getElementById("checkCode"); //2.綁定單擊事件 img.onclick = function () { //加時間戳 var date = new Date().getTime(); img.src = "/First/IdentifyingCodeServlet?"+date;//欺騙緩存,由於路徑不變,瀏覽器會自動去找緩存,而不是服務器 } a.onclick = function () { var date = new Date().getTime(); img.src = "/First/IdentifyingCodeServlet?"+date;//欺騙緩存,由於路徑不變,瀏覽器會自動去找緩存,而不是服務器 } } </script></body>
1.相對路徑
如:./index.html
不以/開頭,以./開頭的路徑(能夠省略不寫)。
規則:找到當前資源和目標資源之間的相對位置關係。
./表示當前目錄;…/上一級目錄。
2.絕對路徑
如:http://localhost/First/ServletResponseTest2
簡略寫法:/First/ServletResponseTest2
以/開頭。
規則:判判定義的路徑是給誰用的。
1.給客戶端瀏覽器使用:須要加虛擬目錄(超連接…項目的訪問路徑)
2.給服務器端使用(轉發…不須要加虛擬目錄)
【問題提出】在重定向寫路徑是咱們採用的是直接書寫路徑,之後一旦更改了虛擬目錄。全部代碼將須要該過來。
【解決方案】動態獲取虛擬目錄。
//動態獲取虛擬目String contextPath = request.getContextPath();//簡單的重定向方法response.sendRedirect(contextPath+"ServletResponseTest2");
前端代碼採起jsp獲取虛擬目錄。
1.概念:表明整個web應用,能夠和程序的容器(服務器)來通訊。
2.如何獲取ServletContext對象。
1.經過request獲取 request.getServletContext();2.經過HttpServlet獲取this.getServletContext();//由於咱們繼承了HttpServlet
二者獲取的ServletContext是相等的。
2.功能:
獲取MIME類型。
MIME類型:在互聯網通訊過程當中定義的一種文件數據類型。
格式:大類型/小類型 text/html
//經過HttpServlet獲取SevletContext context = this.getServletContext();//定義文件名稱String filename = "a.jpg";//獲取MIME類型String mimeType = context.getMimeType(filename);System.out.println(mimeType);
域對象:共享數據。
1.setAttribute(String name,Object value)2.getAttribute(String name)3.removeAttribute(String name);
ServletContext對象範圍:全部用戶全部請求的數據。
@WebServlet("/ServletContextTest")public class ServletContextTest extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //經過httpServlet獲取 ServletContext context = this.getServletContext(); //設置共享數據 context.setAttribute("name","Is me!"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
@WebServlet("/ServletContextTest2")public class ServletContextTest2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //經過httpServlet獲取 ServletContext context = this.getServletContext(); //獲取共享數據 Object a = context.getAttribute("name"); response.setContentType("utf-8"); PrintWriter out = response.getWriter(); out.print(a); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
訪問http://localhost/First/ServletContextTest2獲得結果:
獲取文件的真實路徑
在web服務器的真實路徑。
1.方法:String getRealPath(String path)
配置文件所在地方不一樣,參數書寫不一樣。
String realPath = context.getRealPath("/a.txt");//web目錄下資源訪問String realPath = context.getRealPath("/WEB-INF/a.txt");//WEB-IN目錄下資源訪問String realPath = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下資源訪問
@WebServlet("/ServletContextTest3")public class ServletContextTest3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); String realPath = context.getRealPath("/WEB-INF/classes/a.txt"); System.out.println(realPath); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
文件下載需求
1.頁面顯示超連接
2.點擊超連接後彈出下載提示框
3.完成圖片文件下載。
分析:
1.超連接指向的資源若是能過被瀏覽器解析,則在瀏覽器中顯示,若是不能解析,則彈出下載提示框。不知足需求。
2.任何資源都必須彈出下載提示框。
3.使用響應頭設置資源的打開方式。
步驟:
1.定義頁面,編輯超連接href屬性,指向servlet,傳遞資源名稱filename
2.定義servlet
2.1獲取文件名稱
2.2使用字節輸入流加載文件進內存.
2.3指定response的響應頭:content-disposition:attachment;filename=xxx.2.4將數據寫出到response輸出流。
前端:
<body><p align="center">優質資源網站</p><a href="/First/res/img/1.jpg">表情包(未處理)</a><br><a href="/First/ServletDownLoad?filename=1.jpg">表情包</a><br><a href="/First/ServletDownLoad?filename=2.jpg">表情包2</a></body></html>
後端:
@WebServlet("/ServletDownLoad")public class ServletDownLoad extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.獲取請求參數,文件名稱 String filename = request.getParameter("filename"); //2.使用字節輸入流加載文件進入內存 //2.1找到文件服務器路徑 ServletContext context = this.getServletContext(); String realPath = context.getRealPath("/res/img/"+filename); //2.2用字節流關聯 FileInputStream fis = new FileInputStream(realPath); //3.設置reponse響應頭 //設置響應數據類型:context-type String mimeType = context.getMimeType(filename); response.setHeader("content-type",mimeType); //設置打開方式:content-disposition response.setHeader("content-disposition","attachment;filename="+filename); //4.將輸入流的數據寫出到輸出流中 ServletOutputStream sos = response.getOutputStream(); byte[] buff = new byte[1024*4]; int len =0; while ((len=fis.read(buff))!=-1){ sos.write(buff,0,len); } fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); }}
中文文件名的問題
【解決思路】
1.獲取客戶端使用的瀏覽器版本信息
2.根據不一樣的版本信息,設置filename不一樣的編碼方式。
//1.獲取user-agent請求頭String agent = request.getHeader("user-agenet");//2.使用工具類方法編碼文件名(本身從網上下載工具欄導入在本身建立的工具包)filename = DownLoadUtils.getFileName(agent,filename);
別懼怕顧慮,想到就去作,這世界就是這樣,當你把不敢去實現夢想的時候夢想就會離你愈來愈遠,當你勇敢地去追夢的時候,全世界都會來幫你。