- Cache
- 如果問題的答案不會那麼頻繁變更,那麼使用相同方式一遍遍去獲得就是一種浪費
- 可能還會對performance產生負面影響
- Caching可以store經常會用到的information
- Enabling cache support
- 可使用annotation-driven的方式,或是XML
2017年12月27日 星期三
Java Spring - Caching Data
Java Spring - Persisting data with object-relational mapping
- 在persisting data中,JDBC就像自行車,對於份內的工作能夠很好地完成並且在一些特定場合表現出色;但隨著application越來越複雜,需求也變得複雜
- 我們需要將object的property mapping到database上
- 需要自動生成query, statement
- 可以不用再寫問號
- lazy loading: 允許在需要的時候獲得data
- eager fetching: 與lazy loading相對。預先取得,可藉由一個操作將全部從db取出,節省多次查詢的成本
- cascading: 關聯刪除。
- 一些可用的framework提供這樣的服務。這些服務的通用名稱是object-relational mapping, ORM
- 在persistent layer使用ORM,可以節省數千行的code和大量的開發時間
- ORM可以把你的注意力從容易出錯的SQL轉向如何實現應用程序的真正需求
- Spring對不同的ORM的support很類似。一旦掌握其中一種對ORM的support,可以很輕鬆的切換到另一種framework
Java Spring - Spring JDBC
- Spring data-access
- Spring的目標之一就是允許在開發的時候,能夠遵循OO原則中的coding to interface。Spring對data的support也是如此
- 為了避免persistence logic分散到各個component,最好將data access放到一個或多個專注在此任務的component中
- 這樣的component通常稱為data access object, DAO或repository
- 為了避免application和特定的data access strategy,良好多repository應該要用interface的方式顯示功能
- service object ---> repository interface <--- repository implementation
- service object本身並不會處理data access,而是會將data access delegate給repository,repository interface確保和service object decoupling
- 好處:service object好測試,因為不需要和特定的data access implementation綁在一起,也可以為這些interface建立mock implementation,無需連接DB就能夠測試service object
- 只有data access相關的method才透過interface exposed。這可以實現靈活設計,且切換data-persistence framework對應用程式其他部分帶來影響最小。如果將細節滲透到application的其他部分,則整個application將和data access layer couple在一去,導致僵化的設計
- interface&Spring:
- interface是實現low coupling的key,並且應將其應用在application的各個layer
2017年12月26日 星期二
Java Spring - 建立一個pizza flow
- Define basic flow
- State:
- Start
- Identify Customer ->customerReady
- buildOrder -> orderCreated
- takePayment ->paymentTaken
- saveOrder
- thankCustomer
- endState // end-state
Java Spring - Spring Web Flow
- Spring Web Flow:
- 是一個Web的框架,適用於元素按規定流程運行的process
- Struts沒辦法將flow及implementation 分離,flow的定義分散在組成流程的各個元素中。沒有一個地方能透完整描述整個流程
- Spring Web Flow是Spring MVC的extension,support基於流程的application,流程的定義及implement flow behavior的class及view能夠分開
- 使用Spring Web Flow做一個pizza order web application
Java Spring - Carrying data across redirect requests
- redirect
- 處理完POST後,通常都會執redirect。這樣能夠防止點擊refresh或back時,client重新執行危險的POST
- 通常使用redirect: prefix能夠重新定位
- 問: 如何發送data給redirect的目標method?
- 答: 當一個controller method完成之後,這個method所指定的model data將會複製到request中,並作為request的property,request會forward到view上。因為controller method和view處理的是同一個request,所以在forward過程中,request property也能夠保存。但當controller是redirect時,原始的request就消失了,並且會發起一個新的GET request。原始request中所帶有的model data也跟著request消失了,在新的request上,沒有任何的model data,這個request必須要自己計算data
- 有一些方法能夠使用redirect但又能夠將data傳遞給redirect的method中
- 使用URL template 以path variable或或query parameter的形式
- 透過flash attribute發送data
return "redirect:/spitter/" + spitter.getUsername();
Java Spring - Handling exceptions
- Exception
- 如果在request processing的時候出現exception,則outcome依然是Servlet response。
- exception需要以某種方式被轉換成response
- Spring提供多種方式將exception轉換為response
- 特定的Spring exception將會自動mapping成指定的HTTP status code
- Exception上可以加@ResponseStatus annotation,從而將其mapping為某一個HTTP status code
- method上可以加上@ExceptionHandler,使其用來處理exception
- 將exceptions mapping至HTTP status codes
- default情況下,Spring會將自身的一些exception轉換成合適的status code
- BindException 400 Bad Request
- ConversionNotSupportedException 500 Internal Server Error
- HttpMediaTypeNotAcceptableException 406 Not Acceptable
- HttpMediaTypeNotSupportedException 415 Unsupported Media Type
- HttpMessageNotReadableException 400 Bad Request
- HttpMessageNotWritableException 500 Internal Server Error
- HttpRequestMethodNotSupportedException 405 Method Not Allowed
- MethodArgumentNotValidException 400 Bad Request
- MissingServletRequestParameterException 400 Bad Request
- MissingServletRequestPartException 400 Bad Request
- NoSuchRequestHandlingMethodException 404 Not Found
- TypeMismatchException 400 Bad Request
- 例如,如果DispatcherServlet無法找到適合處理request的controller method,則會拋出NoSuchRequestHandlingMethodException,最終結果就是產生404 status code response
- Spring提供一個機制,能夠透過@ResponseStatus annotation將exception mapping為HTTP status code
- 範例:
- 如果findOne返回null,就會throw SpittleNotFoundException exception,且response code為500。實際上,如果出現任何沒有mapping的exception,response都會是500 status code。
- mapping
- SpittleNotFoundException是一種資源沒找到的異常,其實HTTP404是比較精確的response status code。所以,要使用@ResponseStatus將SpittleNotFoundException mapping至HTTP404
- Exception handling method
- 如果想要response不僅包含status code,還要包含產生的錯誤,此時就不能將exception視為HTTP error,而是要按照處理request的方式來處理exception
- 假設使用者新增的Spittle和已存在的Spittle相同,SpittleRepository的save()將會拋出DuplicateSpittleException
- 這表示SpittleController的saveSpittle() method需要處理這個exception
- 如果能夠讓saveSpittle() method只關注在正確的path,而讓其他method處理exception,也許能夠簡單一點
- 先將saveSpittle() method的exception handler移除(易理解及測試,因為只有一個path)
- 為SpittleController添加一新的method,會處理DuplicateSpittleException的情況,這和處理request是一致的
- 對於@ExceptionHandler來說,他能夠處理同一個controller所有method拋出的DuplicateSpittleException exception,而不需要在每一個可能拋出DuplicateSpittleException的method中增加handle code
- Advising controllers
- 如果controller class特定的aspect能夠運用到整個application的所有controller,這會很方便
- 如果多個controller都會拋出某個特定的exception,可能會發現要在所有controller重複相同的@ExceptionHandler
- 為了避免重複,可以create一個base controller,所有controller都extends這個class,從而extends common @ExceptionHandler
- Spring3.2 introduce一個新的解決方案: controller advice,是任意帶有@ControllerAdvice的class,這個class會包含一個或多個下面annotation的method,且會運用到整個application中的所有controller中帶有@RequestMapping的method上
- @ExceptionHandler
- @InitBinder
- @ModelAttribute
- @ControllerAdvice本身已經使用了@Component,因此@ControllerAdvice所標註的class將會自動被ComponentScanner掃描到,就像帶有@Component一樣
- @ControllerAdvice主要用法:
- 將所有的@ExceptionHandler method蒐集到一個class中,如此一來所有的exception就能在同一個地方進行一致的處理
- 如此一來,任意的controller method如果拋出了DuplicateSpittleException,都會使用duplicateSpittleHandler()來處理Exception
@RequestMapping(value="/{spittleId}", method=RequestMethod.GET) public String spittle(@PathVariable("spittleId") long spittleId, Model model) { Spittle spittle = spittleRepository.findOne(spittleId); if (spittle == null) { throw new SpittleNotFoundException(); } model.addAttribute(spittle); return "spittle"; }
package spittr.web; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Spittle Not Found") //將exception mapping至404
public class SpittleNotFoundException extends RuntimeException { }
@RequestMapping(method=RequestMethod.POST) public String saveSpittle(SpittleForm form, Model model) { try { spittleRepository.save( new Spittle(null, form.getMessage(), new Date(), form.getLongitude(), form.getLatitude())); return "redirect:/spittles"; } catch (DuplicateSpittleException e) { return "error/duplicate"; } }
@RequestMapping(method=RequestMethod.POST) public String saveSpittle(SpittleForm form, Model model) { spittleRepository.save( new Spittle(null, form.getMessage(), new Date(), form.getLongitude(), form.getLatitude())); return "redirect:/spittles"; }
@ExceptionHandler(DuplicateSpittleException.class) public String handleDuplicateSpittle() { return "error/duplicate"; }
package spittr.web; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @ControllerAdvice public class AppWideExceptionHandler { @ExceptionHandler(DuplicateSpittleException.class) public String duplicateSpittleHandler() { return "error/duplicate"; } }
Java Spring - 處理圖片Multipart
- 處理multipart format的data
- 上傳文件,對應的部分可以是binary data
- 在處理文件上傳以前,必須要先配置一個multipart resolver,透過此來告知DispatcherServlet該如何讀取multipart request
------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="firstName" Charles ------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="lastName" Xavier ------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="email" charles@xmen.com ------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="username" professorx ------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="password" letmein01 ------WebKitFormBoundaryqgkaBn8IHJCuNmiW Content-Disposition: form-data; name="profilePicture"; filename="me.jpg" Content-Type: image/jpeg [[ Binary image data goes here ]] ------WebKitFormBoundaryqgkaBn8IHJCuNmiW--
Java Spring - 使用其他方式設定DispatcherServlet及ContextLoaderListener
- 透過其他方式set up DispatcherServlet and ContextLoaderListener
- 可能需要額外的Servlet、filter
- 需要對DispatcherServlet做額外config
- 自行定義個DispatcherServlet configuration
- 除了以下三種必須被override的method以外,其實還有更多可以被override的method
- getRootConfigClasses
- getServletConfigClasses
- getServletMappings
Java Spring - Rending Web View
- Spring resolver
- 將controller中請求處理的logic和view中render的implement decouple是Spring MVC的特性
- 如果controller method直接產生HTML,很難在不影響request處理logic的前提下維護更新view
- controller和view會在model的內容達成一致,這是最大關聯。除此之外,兩者應該保持距離
- 而Spring resolver的重點功能就在於透過logic view name知道要使用哪過view render model
2017年12月25日 星期一
Java Spring - 搭建Spring MVC (2)
- Accept request parameter
- Spring MVC允許多種方式將client的data傳到controller method中
- Query parameter
- Form parameter
- Path variable
- 處理Query parameter
- 翻頁功能,讓使用者可以選擇要看哪一頁
- 假設要查看某一頁的Spittle列表,則這個list會按照最新的Spittle在前進行排序,因此下一頁的第一筆ID早於前一頁的最後一筆ID
- 為了顯示下一頁的Spittle,需要將一個Spittle的ID傳入
- 也可以傳入一個parameter確定要展現的Spittle counts
- 需要寫的controller method要處理以下參數
- before parameter
- count parameter
- 將spittles() method替換為使用上述兩個parameter的新spittles() method
Java Spring - 搭建Spring MVC (1)
- Spring MVC lifecycle request
- request進入1,會帶著URL, form submitted by user,.. 等資訊,此時會進入front controller servlet(DispatcherServlet)。DispatcherServlet任務是將request發送給Spring MVC controller,因此DispatcherServlet需要知道要發給誰。
- 所以DispatcherServlet會查詢一個或多個handler mapping來確定request的下一站在哪裡。handler mapping會根據request 所攜帶的URL來決定。
- 一但知道要送到哪一個controller,DispatcherServlet就會將request發送。到了controller,request會卸下其request並交給controller處理訊息。(設計良好的controller本身幾乎不處理工作,而是將業務邏輯delegate給一個或多個service objects處理)
- controller完成logic後會產生一些結果,這些結果需要返回給使用者在browser上顯示。這些資訊稱為model。這些model還會經過friendly方式格式化,通常是HTML。所以information需要給一個view呈現,通常稱為JSP。controller最後要做的一件事情就是將model data打包,並且知道哪個view需要呈現output。接著會將request連同model及view送回DispatcherServlet
- 這樣一來,controller就不會和view coupled,傳給DispatcherServlet的view name也不用特別標示為JSP。這個名字就是用來找產生真正結果的view。DispatcherServlet會使用ViewResolver來將view name mapping為特定一個的view implementation。
- 最後一站是view的implementation。在這它交付model data。request的任務也完成了。view使用model data render output。這個output會被帶回給client
from Spring in action
2017年12月24日 星期日
Java Spring - Spring AOP advice & AspectJ
- 建立annotated aspects
- AspectJ5的特性
- 簡便的通過少量的annotation把任意class轉變為aspect
- 定義aspect
- 一場表演,觀眾很重要,但對演出功能本身而言,觀眾並不是必要。因此,在Performance上,觀眾是aspect,並將其應用到Performance
@Aspect public class Audience { @Before("execution(** concert.Performance.perform(..))") //perform()之前 public void silenceCellPhones() { System.out.println("Silencing cell phones"); } @Before("execution(** concert.Performance.perform(..))") //perform()之前 public void takeSeats() { System.out.println("Taking seats"); } @AfterReturning("execution(** concert.Performance.perform(..))") //perform()成功執行後 public void applause() { System.out.println("CLAP CLAP CLAP!!!"); } @AfterThrowing("execution(** concert.Performance.perform(..))") //表演失敗之後 public void demandRefund() { System.out.println("Demanding a refund"); } }
Java Spring - 透過pointcut選擇join points
- 透過pointcut選擇join points
- advice及pointcut是aspect的最基本元素
- 在Spring AOP中,要使用AspectJ的pointcut expression language定義pointcut
- Spring僅支援AspectJ pointcut designator的子集,如下
- arg()
- @args()
- execution()
- this()
- target
- @target()
- within()
- @within()
- @annotation
2017年12月22日 星期五
Java Spring - AOP基本概念
- 散佈在application多處的功能(如log, security, cache,...)被稱為cross-cutting concern
- 這些cross-cutting concern概念上通常會和業務邏輯分開,但往往又會直接嵌入到業務邏輯中
- 將這些cross-cutting concern和業務邏輯分離,正是AOP要解決的事情
- DI: Application object之間的decoupling
- AOP: cross-cutting concern和他們影響的object之間的decoupling
- AOP是什麼?
- Aspect oriented programming
- 能夠協助將cross-cutting concern模組化,如下圖為橫切服務的功能
- from spring in action 4
- 問題:若要使用相同的功能,通常使用inheritance, delegation
- inheritance: 若整個application都使用同一個base class,會導致脆弱的object
- delegate:需要對delegate對象進行複雜的呼叫
- 解法:
- AOP取代inheritance及delegate,且在很多場景下都簡潔
- 需要定義common functionality
- 可以定義function需要在哪裡被應用,不需要修改受影響的class
- cross-cutting concern可以被模組化成特殊的class,這些class稱為aspect
- 優勢:
- 每個concern都集中在同一個地方,而不是散到程式碼各處
- 主要的service module更簡潔,因為程式碼只包含主要的concern code,次要的concerns被轉移到aspects
- 定義AOP term
- advice (抄電表員紀錄用電量:工作)
- aspects的工作就叫做advice
- advice定義了aspects是什麼,且什麼時候使用
- 什麼時候使用:比如某個method前?後?前後都call?threw exception時用?
- Spring aspects可以使用五種type advices
- Before: target method前
- After: target method後
- After-returning: target method successfully 完成
- After-throwing: target method拋出exception的時候
- Around: advice wraps advice methods,在被通知的method call之前和之後執行自己定義的function
- join point (抄電表員目標就是房屋內那些安裝的電表)
- application執行過程中能夠insert join point的點
- join point可以是call method, throw exception,甚至是修改string
- aspect能夠insert join point到正常流程中,加入新的行為
- pointcut (抄電表員工作的範圍應該是有指定區域的)
- advice定義what&when,pointcut定義where
- 匹配advice所有織入(woven)的join cut
- 有些AOP framework允許創立dynamic pointcut,可以在runtime的時候決定是否apply advice
- aspect (抄電表員知道完成工作所需要的所有東西)
- advice與point cut的結合(what, where, when)
- introduction
- 可以將現有的ass加入新的method或property
- weaving
- aspect應用到target object並且創建新的proxy object的過程
- 在指定的join cut被weaving到target object
- 在target object可以有很多點進行weaving
- compile time: target class compile的時候被weaving,需要特殊的compiler如AspectJ
- class load time: target class被load到JVM的時候被weaving,需要特殊的class loader,AspectJ5的load-time weaving(LTW) support
- runtime: target class在runtime時weaving。一般情況下,weaving時AOP container會為target object dynamic創建一個proxy object。而Spring AOP就是這種方式
- Spring對AOP的support
- AOP framework基本功能:建立pointcuts,定義join points在哪個aspects需要被woven
- Spring提供四種type的AOP support
- classic Spring proxy-based AOP
- Pure-POJO aspects: 需要使用XML,藉由aop namespace轉換POJO為aspects
@AspectsJ: 可以不使用XML Injects AspectJ aspects: APO需求當不只有constructor, property的使用時,可以使用aspects implements AspectJ - Spring advice是Java寫出來的
- 定義advice用的pointcut通常會使用annotation或在Spring config file裡使用XML編寫
- AspectJ是以Java擴展的方式implement
- 優點:可以獲得更強大的控制
- 缺點:需要學期額外的新工作及語法
- Spring通知objects at runtime
- Spring only supports method join points
- 因為Spring是基於dynamic proxy,所以Spring指支援method的join points
- 如AspectJ, JBoss還提供field及constructor join points(因此Spring無法再bean create的時候使用advice)
- method join points可以滿足絕大部分的需求
2017年12月21日 星期四
Java Spring - Scoping beans
- Bean
- 默認情況下,Spring application context所有的bean都是singleton(只有一個instance),也就是不管一個bean被injects多少次,都是同一個instance
- 問題:
- 有些application中,object使用stateless可能不太合理
- 有些時候某些object是mutable(狀態會變),所以會有一些state,因此reuse不安全,這個時候class若是singleton bean就會有問題
- Spring定義了bean的scope:
- Singleton: 整個application只會建立一個instance (default)
- Prototype: 每次injects或是透過Spring application context get時都會建一個新的bean instance
- Session: Web application中,為每個session創建一個bean instance
- Request: Web application中,為每個request創建一個bean instance
Java Spring - Conditional beans
- Conditional beans
- 需求:
- 在某些條件的成立下,此bean才被create,比如某個特定的environment variable被設置以後才create bean
- 解法:
- Spring4以後引入一個新的@Conditional annotation -> 若給定的條件成回傳為true,則會create這個bean,否則會被忽略
Java Spring - Configuring profile beans
- 在開發環境中,遷移是一個挑戰(比如Dev->QA, QA->Prod)
- 假設有個DB config,在Dev上可能使用的是EmbeddedDatabaseBuilder
@Bean(destroyMethod="shutdown") public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .addScript("classpath:schema.sql") //schema會定義在schema.sql中 .addScript("classpath:test-data.sql")//data使用test-data.sql載入 .build(); }
2017年12月20日 星期三
Java Spring - Mixing configurations
- Importing & mixing configurations混搭
- autowired會考慮所有container中的bean,不論是在JavaConfig、XML或是@CompnentScan
Java Spring - 使用Java configuration或XML設置config
- Wiring bean with Java
- 建議使用@Component及@Autowired
- 問題
- 將3rd party library的component做autowired到application,這種時候就無法在3rd-party的class上加上@Component及@Autowired
- 解法
- 採用顯示configuration。可以使用Java或XML
Java Spring - Automatically wiring beans
- 創造application中DI本質的行為稱為wiring
- Spring configuration options
- Spring container負責創建application中的bean。並且通過DI協調之間的關西
- 需要告訴Spring哪些bean如何將其wiring在一起
- wiring mechanisms(選擇方式可以互相搭配)
- 顯式在XML中配置 (最末)
- 顯式在JAVA中配置 (次之)
- 隱式的bean自動wiring及discovery (盡可能使用)
Java Spring - Application context及Bean生命週期
- Spring致力於簡化企業級的Java開發,low coupling,關鍵在於DI及AOP
- Bean
- Spring container負責create對象,wired,configured並管理他們的生命週期(new()~finalize())
- Container是Spring framwork的核心,使用DI管理組件,因此會簡單乾淨,容易理解。更重要的是,容易進行unit test
- Spring container可歸為兩種不同類型:
- bean factory: (org.springframework.beans.factory.BeanFactory interface)提供基本DI support,對大多數應用來說太low-level
- application context: (org.springframework.context.ApplicationContext interface)基於bean factory建置,提供application框架級的服務
2017年12月19日 星期二
Java Spring - DI, AOP, Boilerplate Code核心概念
Spring:
簡單的JavaBean實現EJB才能完成的事情
解決企業級應用開發的複雜性創建,簡化JAVA開發
- 基於POJO的輕量級和最小侵入性coding
- 通過DI AOP
- 基於切面和慣例進行聲明式coding
- 透過切面和模板減少樣板式coding
2017年12月13日 星期三
HTML CSS (9) - 其他設計概念
- CSS權重問題
- 先看權重
- html: 1分
- 自行命名class: 10分
- id: 100分 (在css內為井號在前#id)
- style在內:1000分
- !important: 10000分 css內直接寫!important
- p(1分)
- .header(10分)
- .header p (11分)
- .header .menu li (21分)
- 後面覆蓋前面
- 開發前思考結構
- 先命名class
- head tag
<head> <meta charset="UTF-8"> <title>Document</title> <meta description="keywords" content="新聞、電子信箱和搜尋功能只是起點。每天發掘更多精彩內容。打造專屬自我的 Yahoo奇摩體驗。"> // 網站描述文字 <meta name="keywords" content="yahoo, yahoo奇摩, yahoo奇摩首頁, yahoo首頁, yahoo搜尋, yahoo 信箱, yahoo 即時通訊, 新聞, 股市, 運動, 娛樂, 拍賣, 購物中心, 超級商城">// 關鍵字可以找得到,中間用逗號分隔 <meta property="og:title" content="Yahoo奇摩" /> // FB嵌入使用 <meta property="og:type" content='website' /> <meta property="og:url" content="http://tw.yahoo.com" /> <meta property="og:image" content="https://s.yimg.com/dh/ap/default/130909/y_200_a.png"/> <meta property="og:site_name" content="Yahoo奇摩" /> <meta http-equiv="X-UA-Compatible" content="chrome=1"> //針對 IE 做相容性<link rel="shortcut icon" href="https://mbp.yimg.com/sy/rz/l/favicon.ico"> // 網頁tab上的icon<link rel="stylesheet" href="css/maruko8.css"> // 先css再JS </head>
- 設計注意事項
- 少用position = absolute
- 多用互動性設計(如hover, focus)
- 權重須標示清楚,如ul li h1, ...
- 整個版面都相同的設定,如文字大小,css可在body內設定
- 網頁結構越乾淨越好,不要加入太多標籤
- class名稱儘量有意義
2017年12月12日 星期二
HTML CSS (8) - 表格及表單
- Table
<table> <tr> <th>2017/12/01</th> <th>クリスマス&大みそか原作スペシャル」で 1996年送の人気エピソードをリメイク!</th> </tr> <tr> <td>2017/11/22</td> <td>公式YouTube「ちびまる子ちゃんねる」開設記念!【ちびまる子ちゃん×まる</td> </tr> <tr> <td>2017/11/22</td> <td>相鉄ローゼンの年賀状印刷にて「ちびまる子ちゃん」デザインが注文できます!</td> </tr> </table>
結果如下
2017年12月8日 星期五
HTML CSS (6) - 相對定位及絕對定位
6-1 相對定位及絕對定位
- 相對定位position:absolute;
- 區塊內需寫position:absolute; 再定義位置
- 左上 left:0 top:0
- 左下 left:0 bottom:0
- 右上 right:0 top:0
- 右下 right:0 bottom:0
.content{ background: black; width:200px; height:200px; position:absolute; //絕對定位 left: 0; //左下角 bottom: 0; } .content2{ background: red; width: 500px; height:200px; position:absolute; //絕對定位 right:0; //右上角 top:0; }
- 黑區塊和紅區塊不會理會原本的配置,會被置放在絕對位置
2017年12月7日 星期四
HTML CSS (5) - 網頁排版
5-1 關於如何將兩個元素並排:
https://stackoverflow.com/questions/5759554/displayinline-resets-height-and-width/5759565#5759565根據這篇可知道,inline attribute並沒有長寬,因此如果要使兩個元素有inline的效果,需要使用float或inline-block.
浮動效果float:會根據元素大小並排。若寬度比瀏覽器寬度長,則下一個元素會被推到下一層
float:left;往左靠
float:right; 往右靠
.box{ width: 200px; height: 50px; background: black; float:left; } .box2{ width: 200px; height: 50px; background: pink; float:left; }
2017年12月6日 星期三
HTML CSS (4) - 使用CodePen
2017年12月4日 星期一
HTML CSS (2) - CSS介紹
2-1 CSS介紹及用途
html設計出的網頁文字顏色等能夠改變,設定樣式。- 新增css資料夾
- 新增副檔名為css的檔案,如style.css
- 在html內的header中新增<link> tag
<head> <link rel="stylesheet" type="text/css" href="css/style.css"> </head>
- rel: 定義該檔案和連結檔案的相對關係,css則需要設定為stylesheet
- type:連結檔案的格式
- href: 相對路徑的css檔
CSS可針對html標籤指定樣式 (注意要有中括號,內為屬性+冒號+value+分號)
- 針對h2標籤內的字體顏色做變化: color
- 文字大小: font-size
1 2 3 4 | h2{ color: pink; font-size: 40px; } |
2017年12月3日 星期日
HTML CSS (1) - 環境及常用標籤
1-1 準備工作
下載以下兩個工具
- Sublime Text3
- 自動排版套件
- 安裝sublime package -> 安裝後command+shift+p可搜尋安裝Emmet
測試是否會自動產生html tag
- 將儲存格式選定為.html
- 輸入<html
- 按下tab
- 建立一資料夾,名為project
- 開啟sublime輸入test
- 存檔為html format,命名為index.html
- 至資料夾開啟此html
JSP-Servlet (4) - Container
Container:
- Tomcat就是一個實作Container的範例
- Container開機的時候,載入你寫的Servlet class並初始化
- 當Apache(Web Server)收到針對動態網頁的request時,將會交由負責此servlet的Container處理
- Container會將HttpServletRequest object & HttpServletResponse object交給Servlet thread
- 呼叫執行Servlet的service()內doGet()或是doPost()的method(基於HTTP Request的method)
- Apache Tomcat是用來deploy Java Servlet, JSP。當Java project build成為WAR檔,就可以直接將此檔丟到Tomcat以便deploy。是用來服務Servlet&JSP Server
使用Container的五大項優點(因為以下的事項,更能夠集中精神專注於商業邏輯的開發)
- 與Web Server溝通取得request(因此不需要實作Listener, stream, ServerSocket...)
- 控制Servlet的生命週期,initialization, call method,... 適時的將instance GB。透過Container 則不需要擔心資源管理
- 當多個request進入時,Container會自行建立thread來處理此請求,當此servlet執行為service() method時,thread就會結束。但synchronize的事情還是得自己處理
- 可調整web.xml來設定哪些群組能夠讀取哪些網頁,是否需要login機制,welcome html page等寫在內,可以不透過修改Java程式達到這些目的
- 能夠將JSP轉成真實的Java檔案
Container處理HTTP request steps
- 使用者點擊非靜態網頁的超連結
- container收到後,建立HttpServletRequest object & HttpServletResponse object
- 根據web.xml之URL及真實Servlet位置對應找出此Servlet後,會將上述object交由Servlet thread
- 呼叫Servlet內的service(),且根據request method,service()執行呼叫doGet()或是doPost()
- thread產生的動態頁面,將會放入 HttpServletResponse object
- 因container保有此HttpServletResponse object的reference,所以能夠將此response轉換成HTTP response,接著刪除HttpServletRequest object & HttpServletResponse object
以下Servlet範例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.*; import javax.servlet.http.*; public class Ch1Servlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); Date today = new Date(); writer.println("<html>"+ "<body>" + "<h1 align=center>HF's Chapter Servlet</h1>" + "<br>" + today + "</body>" + "</html>"); } } |
2017年12月2日 星期六
JSP-Servlet (3) - Servlet & Deployment Descriptor產生動態網頁
Web Server(如Apache)的
- 可以做:
- client 請求網頁,找到該靜態網頁,不會做計算
- 原封不動地拿出此靜態網頁,添加header
- 傳送回client(每個client看到的東西都一樣)
- 不能做:(但是可以找到能夠處理此request的application(如Tomcat))
- 產生動態網頁
- 將資料存在server
Servlet Java檔案
import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.*; import javax.servlet.http.*; public class Ch1Servlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); Date today = new Date(); writer.println("<html>"+ "<body>" + "<h1 align=center>HF's Chapter Servlet</h1>" + "<br>" + today + "</body>" + "</html>"); } }
Servlet Deployment Descriptor(web.xml)檔,部署描述檔
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>Ch1 Servlet</servlet-name> <servlet-class>Ch1Servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Ch1 Servlet</servlet-name> <url-pattern>/serv1</url-pattern> </servlet-mapping> </web-app>
- servlet-class: 真實,完整的servlet class名字,但不含.class (file path name)
- servlet-name: alias (deploy name)
- url-pattern: 使用者連線時請求的名稱(public URL name)
以上的命名目的為安全性及可維護性
執行結果:
Ref:
Eclipse 安裝tomcat:
Eclipse下使用tomcat的位置當作deploy位置
Eclipse下tomcat server location無法更改:https://stackoverflow.com/questions/4919846/why-tomcat-server-location-property-is-greyed-in-eclipse
JSP-Servlet (2) - HTML & HTTP
HTML & HTTP差異:
MIME Type:
- HTML: (HyperText Markup Language 超文字標記語言) 瀏覽器必須了解的語言。瀏覽器是一種知道如何和伺服器溝通的軟體(如Safari, Mozilla)。當伺服器回應請求的時候,通常會傳給瀏覽器一組以HTML寫成的指令,由瀏覽器解譯HTML後將內容呈現給使用者。但有時候較舊版的瀏覽器可能會不了解使用新版HTML語法所寫的網頁內容
- HTTP: (HyperText Transport Language 超文字傳輸協定) client及server之間的對話大多是HTTP(以此溝通),此協定支援簡單的request&response。基本上web說的語言就是HTTP。web server透過HTTP將HTML送給client。因此其實HTTP回應內包含HTML
又,HTTP執行在TCP/IP上。
- TCP負責將資料完整地從一個node傳送到另一個node。在運送過程有可能會被分割成幾個部分。但最後能保有完整性。
- IP是將封包從一台主機順利繞道一台主機的底層網路協定。
HTTP是支援web特定功能的網路協定。但依賴TCP/IP取得完整請求與回應
HTTP request關鍵元素:
- HTTP method
- URL
- Form parameters
HTTP response關鍵元素:
- Status Code
- Content-type
- Content
HTTP method:
- GET: 簡單的請求。如,要求server取出資源(HTML, JPEG file, PDF file等)。但也可以傳送(一點)資源
- 傳送字元數量有限,取決於server(tomcat在conf/server.xml內可更改maxHttpHeaderSize="65536"參數),因此如果client在search bar輸入很長的資料,GET可能會無法運作
- 安全性問題,GET會將資量附加在URL後面,出現在瀏覽器的URL欄位中。如帳號密碼等敏感資料
- 如果使用POST代替GET,就不能把Form submission的頁面加入我的最愛當成書籤
- 下例是一個GET的範例,使用?將路徑與參數隔開,參數間以&連結。兩個部分加起來得到的字串就是HTTP request所傳送的完整URL
- POST: 像是Get的加強版,如了可以取出server資源,以能夠傳送使用者的資料。
- 設計為傳送複雜請求
- 使用者在網頁上填的資料(如表單等),就會被加到message body (或稱為payload),資料量可以很大
- HEAD
- TRACE
- PUT
- DELETE
- OPTIONS
- CONNECT
http://ecshweb.pchome.com.tw/search/v3.3/?q=花茶%20&scope=all&sortParm=rnk&sortOrder=dc&cateId=DBAJ11
response header內的content type的值,就是MIME Type,他告知接收瀏覽器即將要接收怎麼樣的資料,好讓瀏覽器知道要怎麼展示
此值對應了request內header的Accept欄位(瀏覽器可以接受哪一種格式)
網頁傳送步驟:
- 使用者在search bar輸入URL
- 瀏覽器建立HTTP GET request
- 瀏覽器將此HTTP GET 請求傳送至server
- server根據某種對應關係找到該頁面
- server產生HTTP response
- 將其頁面傳回至client
- 瀏覽器收到後,根據HTTP內的HTML解譯,並將結果呈現給使用者
URL:(Uniform Resource Locator)
如下範例:
https://www.wangsteak.com.tw:443/advice/wang/menu.html
- https: (告訴server這是哪一種protocal,此例為https)
- www.wangsteak.com.tw: server, 實體server的獨特名字,對應到IP,可以直接使用IP代替server,但通常domain name比較好記
- 443: port。server的很多應用程式會以port區隔。http預設是80
- 一台server可以有0-65535,共65536個 (0~1023 port已經保留給一些知名的服務)
- FTP: 21
- Telnet: 23
- POP3: 110
- SMTP: 25
- TIME server: 37
- advice/wang: path,server被請求的網路位置
- menu.html: resource,請求的檔案。假如被省略大部分會預設加上index.html
JSP-Servlet (1) - Mac下安裝Tomcat
註:須先確認安裝Java且設定完成環境變數$JAVA_HOME
- Tomcat官網下載,拉到最下面可以看到Binary Distributions,選擇合適的版本,若不確定則選擇Core發行的版本
- 解壓縮後會得到一個apache-tomcat-[version] 文件夾
- 將整包資料夾放入想要安裝tomcat的位置,且可將apache-tomcat-[version] 直接改為tomcat
- 這個安裝tomcat的位置,就是CATALINA_HOME
- 開啟Terminal,設定環境變數
- 在檔案內新增一行 (~/Document/tomcat須代換為安裝tomcat的位置)
- 執行source重新讀取bash_profile
- 執行echo確認環境變數存在
- 啟動tomcat,至~/Document/tomcat/bin執行startup.sh(~/Document/tomcat須代換為安裝tomcat的位置)
vim ~/.bash_profile
export CATALINA_HOME=~/Document/tomcat
source ~/.bash_profile
echo $CATALINA_HOME
sh startup.sh
訂閱:
文章 (Atom)