有一天你會(huì)長大
什么話該說,什么話不該說,該說的話該怎么說。誰能告訴我。
posted @ 2010-01-19 13:21 追求無止境 閱讀(204) | 評(píng)論 (0) | 編輯 收藏
追求無止境我的程序人生
隨筆 - 31, 文章 - 2, 評(píng)論 - 20, 引用 - 0
|
有一天你會(huì)長大什么話該說,什么話不該說,該說的話該怎么說。誰能告訴我。 posted @ 2010-01-19 13:21 追求無止境 閱讀(204) | 評(píng)論 (0) | 編輯 收藏 2009年度盛事 - 總結(jié)20092009年12月31日,站在2009年的尾巴上,不禁感到時(shí)間飛逝。2009年,匆匆而過。在過去的2009年,收獲何多,失去何多。2009年,對(duì)我來說,是一個(gè)重要的轉(zhuǎn)折點(diǎn)。漸漸的發(fā)現(xiàn)自己應(yīng)該長大了,也發(fā)現(xiàn)自己確實(shí)長大了,更發(fā)現(xiàn)自己實(shí)際上還是需要繼續(xù)長大。 每年的這個(gè)時(shí)候,各個(gè)新聞媒體都會(huì)評(píng)出什么十大之類的,我也落一會(huì)俗(當(dāng)然自己本身就很俗),來看看今年發(fā)生在我身上的幾大事件: 先大體羅列一下吧:
從時(shí)間跨度上來說, 1月到2月在家過年,2月和3月在青島某公司實(shí)習(xí),4月和5月在北京某公司實(shí)習(xí),6月在中國石油大學(xué)享受畢業(yè)之前的時(shí)光,7月到8月繼續(xù)在北京某公司實(shí)習(xí),9月到12月在上學(xué)+實(shí)習(xí)。2009年最幸福的事情發(fā)生在1到2月,盡快也有不快;最平常的日子在2月和3月,到了4月和5月或許是我最糾結(jié)的日子吧;6月或許是最快樂的日子的吧;7月和8月讓我體會(huì)到了工作的滋味;而9月到12月,整天在公司與學(xué)校之間奔跑,知道了工作+上課兩者要做到兼顧的滋味,雖然并沒有做到兼顧。 2009年大體經(jīng)歷如此。2009年對(duì)我最大的關(guān)鍵字或許就是“改變”,這一年我訂婚了,在這一點(diǎn)上,改變了我的準(zhǔn)非單身狀態(tài);在這一年,我實(shí)習(xí)了,而且大量的時(shí)間都在于此,改變了我僅僅是學(xué)生的狀態(tài);在這一年,我畢業(yè)了,我離開了生活學(xué)習(xí)四年的中國石油大學(xué),離開了讓我畢生難忘的日子;在這一年,我來北京了,從對(duì)北京的一無所知,到開始的彷徨,然后漸漸熟悉和適應(yīng);在這一年,我的經(jīng)濟(jì)漸漸獨(dú)立,盡管每個(gè)月只有不到1000的收入,但能滿足的我的基本需求;在這一年,我買了筆記本,雖然對(duì)其他人來說,這不是一件特別的事,對(duì)我來說,因采用了分期付款,而用接下來一年中近半個(gè)月的工資來還,但我不覺得后悔,在這個(gè)過程中,我的經(jīng)濟(jì)觀念和理財(cái)觀念開始漸漸改變;在這一年,工作成了我的核心,工作教會(huì)我很多東西,在與人交流、在工作態(tài)度、在技術(shù)上,都有一定的提高。 回憶2009年,收獲頗多,也失去不少。但日子總是向前的,有得必有失。希望在以后的2009年,自己能夠漸漸提高自己的能力。無論是在生活上,在工作上,還是在心理上。
2009年10大大事: 與老婆訂婚: 2009年, posted @ 2009-12-31 12:55 追求無止境 閱讀(209) | 評(píng)論 (0) | 編輯 收藏 Spring web MVC 框架學(xué)習(xí)筆記 之 ViewResolver技術(shù)上次的文章中介紹了ModelAndView對(duì)象中的view對(duì)象,可以使用字符串來讓Spring框架進(jìn)行解析獲得適合的視圖。而解析View的就是ViewResolver技術(shù)。 ViewResolver的定義如下: public interface ViewResolver { 在[spring-dispatcher-name]-servlet.xml中,可以定義viewResolver: <bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 來讓DispacherServlet進(jìn)行加載默認(rèn)的viewResolver,如果沒有設(shè)置viewResolver,spring使用InternalResourceViewResolver進(jìn)行解析。 Spring實(shí)現(xiàn)ViewResolver的非抽象類且我們經(jīng)常使用的viewResolver有以下四種:
使用多視圖解析器: 我們不想只使用一種視圖解析器的話,可以在[spring-dispatcher-name]-servlet.xml定義多個(gè)viewResolver: <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> DispatcherServlet會(huì)加載所有的viewResolver到一個(gè)list中,并按照優(yōu)先級(jí)進(jìn)行解析。注意order中的值越小,優(yōu)先級(jí)越高。而id為viewResolver 的viewResolver的優(yōu)先級(jí)是最低的。 posted @ 2009-11-27 12:11 追求無止境 閱讀(6881) | 評(píng)論 (1) | 編輯 收藏 Spring MVC框架學(xué)習(xí)筆記 之 View技術(shù)以前,我們詳細(xì)介紹了Spring的Controller技術(shù)。Spring的面向接口編程,使Controller的實(shí)現(xiàn)多種多樣。View技術(shù)也一樣。今天的分析先從在Controller中的ModelAndView開始。 public class ModelAndView { private Object view; //View實(shí)例或者view的字符串 /** Model Map */ private ModelMap model; //model /* * Convenient constructor when there is no model data to expose. * Can also be used in conjunction with <code>addObject</code>. * @param view View object to render * @see #addObject */ public ModelAndView(View view) { this.view = view; } public ModelAndView(String viewName){ this.view = viewName; } 可以看到view實(shí)例可以指向一個(gè)View對(duì)象或者字符串。現(xiàn)在先看看View接口: public interface View { /** * Return the content type of the view, if predetermined. * <p>Can be used to check the content type upfront, * before the actual rendering process. * @return the content type String (optionally including a character set), * or <code>null</code> if not predetermined. */ String getContentType(); /** * 繪制視圖 * 繪制視圖的第一步是準(zhǔn)備請(qǐng)求: 如果是JSP的視圖技術(shù) * 首先會(huì)把model設(shè)為request的屬性。 * 第二步則是真正的繪制視圖 * @param model Map with name Strings as keys and corresponding model * objects as values (Map can also be <code>null</code> in case of empty model) * @param request current HTTP request * @param response HTTP response we are building * @throws Exception if rendering failed */ void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; } 在這之后,我們再來看看View的實(shí)現(xiàn)繼承類圖,可以看到Spring支持多種類型視圖: org.springframework.web.servlet.view.AbstractView (implements org.springframework.beans.factory.BeanNameAware, org.springframework.web.servlet.View)
和Controller一樣,View的第一個(gè)實(shí)現(xiàn)也是AbstractView。所以先讓我們看看AbstractView對(duì)render函數(shù)的實(shí)現(xiàn):
public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { 第一步,將靜態(tài)屬性和model的屬性都添加到mergedModel里面。如果需要請(qǐng)求上下文,則將請(qǐng)求上下文添加到model中。 靜態(tài)屬性是繼承AbstractView進(jìn)行設(shè)置的屬性。而請(qǐng)求上下文如果設(shè)置的名字就會(huì)創(chuàng)建一個(gè)request上下文。在requestContext中定義了一些包括本地化和主題的處理工具。 第二步,對(duì)響應(yīng)進(jìn)行預(yù)處理。最后調(diào)用子類需要實(shí)現(xiàn)的函數(shù)renderMergedOutputModel。 對(duì)PDF和EXCEL格式我們暫且不管,且Spring支持多種視圖技術(shù),這里我們主要關(guān)注JSTL技術(shù), 接著我們來看AbstractUrlBasedView 類。在AbstractUrlBasedView 只定義了一個(gè)url屬性。別的沒有什么特殊處理。 接著繼承AbstractUrlBasedView 的是InternalResourceView。他對(duì)renderMergedOutputModel進(jìn)行實(shí)現(xiàn),實(shí)現(xiàn)如下: /** exposeModelAsRequestAttributes(model, requestToExpose); 可以看到InternalResourceView對(duì)請(qǐng)求進(jìn)行了轉(zhuǎn)發(fā)。轉(zhuǎn)發(fā)到url上。最后我們看看JSTLView的實(shí)現(xiàn):
public class JstlView extends InternalResourceView { private MessageSource messageSource; public JstlView() { } public JstlView(String url) { super(url); } public JstlView(String url, MessageSource messageSource) { this(url); this.messageSource = messageSource; } protected void initServletContext(ServletContext servletContext) { if (this.messageSource != null) { this.messageSource = JstlUtils.getJstlAwareMessageSource(servletContext, this.messageSource); } super.initServletContext(servletContext); } protected void exposeHelpers(HttpServletRequest request) throws Exception { if (this.messageSource != null) { JstlUtils.exposeLocalizationContext(request, this.messageSource); } else { JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext())); } } }
在InternalResourceView 中,基本上所有的處理都差不多了。在JSTLView對(duì)兩個(gè)方法進(jìn)行了覆蓋。第一個(gè)initServletContext,主要初始化了MessageResource 第二個(gè)exposeHelpers將messageSource放在了request里面。 這樣view的解析就結(jié)束了。接下來容器對(duì)jsp進(jìn)行解析,并進(jìn)行tag等的處理。然后將生成的頁面返回給客戶端。 posted @ 2009-11-26 13:25 追求無止境 閱讀(8209) | 評(píng)論 (2) | 編輯 收藏 SpringMVC web框架學(xué)習(xí) Controller 分析org.springframework.web.servlet.mvc.AbstractController (implements org.springframework.web.servlet.mvc.Controller)
Spring MVC框架中的Controller對(duì)請(qǐng)求進(jìn)行處理:所有的Controller都實(shí)現(xiàn)接口Controller: public interface Controller { /** * Process the request and return a ModelAndView object which the DispatcherServlet * will render. A <code>null</code> return value is not an error: It indicates that * this object completed request processing itself, thus there is no ModelAndView * to render. * @param request current HTTP request * @param response current HTTP response * @return a ModelAndView to render, or <code>null</code> if handled directly * @throws Exception in case of errors */ ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception; } 上面的doc表明Controller返回的modelandview可以使空,表明請(qǐng)求都是該函數(shù)中處理完成了,不需要modeland來進(jìn)行渲染。 在繼續(xù)之前先介紹一個(gè)有用的工具類:WebUtils。用這個(gè)可以簡化session,request的處理。具體的內(nèi)容可以參考文檔。 Controller的第一個(gè)實(shí)現(xiàn)是:AbstractController。他是一個(gè)Abstract類,除了實(shí)現(xiàn)了Controller接口,它還繼承了WebContentGenerator。 WebContentGenerator的作用是什么?參考文檔可以發(fā)現(xiàn),該類主要對(duì)Cache和Session進(jìn)行管理。
用戶可以對(duì)這些參數(shù)進(jìn)行測試,cache和expire信息涉及到了http協(xié)議信息,更多信息可以參考http協(xié)議文檔。這里不再說明。 再看AbstractController的代碼: public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) 他會(huì)檢查支持的方法,和會(huì)話,然后應(yīng)用cache設(shè)置。 如果需要session同步,就進(jìn)行同步處理。session同步應(yīng)用于有session的情況下。如果沒有session,session同步是沒有用的。 AbstractController會(huì)調(diào)用handleRequestInternal方法進(jìn)行處理,繼承AbstractController的類需要實(shí)現(xiàn)該方法。 下面我們再看看AbstractUrlViewController 的代碼實(shí)現(xiàn)和文檔,先看handleRequestInternal的實(shí)現(xiàn):
/** 可以看到,它使用了getViewNameForRequest獲取需要的viewName。而getViewNameForRequest是一個(gè)抽象函數(shù),需要子類實(shí)現(xiàn)。lookupPath就是我們請(qǐng)求的URL中的一部分。如我們使用UrlFilenameViewController來進(jìn)行如下的配置:
<bean name="/index.do" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>、
09-11-25 11:56:06 - DEBUG [http-8200-1] - Returning view name 'index' for lookup path [/index.do]
該Controller對(duì)/index.do解析成index,然后再通過viewResolver對(duì)index進(jìn)行擴(kuò)展為/jsp/index.jsp。從而找到該頁面。
可以看到這個(gè)類的主要是用于對(duì)url進(jìn)行解析,然后轉(zhuǎn)到合適的頁面上,而在轉(zhuǎn)到這個(gè)頁面之前不需要進(jìn)行特別的處理。
明白了該類的作用自然也就知道了UrlFilenameViewController的作用。這里不再進(jìn)行詳細(xì)分析。
posted @ 2009-11-26 09:35 追求無止境 閱讀(4166) | 評(píng)論 (0) | 編輯 收藏 Spring MVC 框架學(xué)習(xí)之AbstractFormController以及AbstractFormControll在看完BaseCommandController和AbstractCommandController之后,我們再看BaseCommandController的另一個(gè)實(shí)現(xiàn)AbstractFormController,以及AbstractFormController的具體實(shí)現(xiàn)SimpleFormController。 先看看AbstractFormController對(duì)handleRequestInternal的實(shí)現(xiàn): protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { // Form submission or new form to show? if (isFormSubmission(request)) { // Fetch form object from HTTP session, bind, validate, process submission. try { Object command = getCommand(request); ServletRequestDataBinder binder = bindAndValidate(request, command); BindException errors = new BindException(binder.getBindingResult()); return processFormSubmission(request, response, command, errors); } catch (HttpSessionRequiredException ex) { // Cannot submit a session form if no form object is in the session. if (logger.isDebugEnabled()) { logger.debug("Invalid submit detected: " + ex.getMessage()); } return handleInvalidSubmit(request, response); } } else { // New form to show: render form view. return showNewForm(request, response); } } 這個(gè)方法,首先判斷是不是Form提交,判斷方法是: protected boolean isFormSubmission(HttpServletRequest request) { 如果是form提交的話,系統(tǒng)首先創(chuàng)建一個(gè)Command,然后對(duì)數(shù)據(jù)進(jìn)行綁定和驗(yàn)證,之后調(diào)用processFormSubmission方法。showNewForm則調(diào)用showForm。
在AbstractFormController中里面有兩個(gè)抽象方法:
好了,看完AbstractFormController之后,再看看SimpleFormController是如何實(shí)現(xiàn): protected ModelAndView processFormSubmission( 在上面的方法中,如果有錯(cuò)誤,調(diào)用showForm,來顯示form。沒有錯(cuò)誤的話,則調(diào)用onSubmit方法。 protected final ModelAndView showForm( 在showForm中,設(shè)置屬性,放在model中,然后在viewName進(jìn)行設(shè)置。
FormController就是上面的過程。具體的執(zhí)行過程和詳細(xì)信息會(huì)在以后的博客中具體介紹。
posted @ 2009-11-25 17:31 追求無止境 閱讀(2450) | 評(píng)論 (0) | 編輯 收藏 Spring MVC 框架學(xué)習(xí)筆記之BaseCommandController和AbstractCommandController
Spring的BaseCommandController繼承自AbstractController。在看BaseCommandController之前先看他的繼承類AbstractCommandController是如何實(shí)現(xiàn) AbstractController的handleInternalRequest方法的: protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { Object command = getCommand(request); ServletRequestDataBinder binder = bindAndValidate(request, command); BindException errors = new BindException(binder.getBindingResult()); return handle(request, response, command, errors); } getCommand就是BaseCommandController中的方法。 protected Object getCommand(HttpServletRequest request) throws Exception { return createCommand(); } protected final Object createCommand() throws Exception { if (this.commandClass == null) { throw new IllegalStateException("Cannot create command without commandClass being set - " + "either set commandClass or (in a form controller) override formBackingObject"); } if (logger.isDebugEnabled()) { logger.debug("Creating new command of class [" + this.commandClass.getName() + "]"); } return BeanUtils.instantiateClass(this.commandClass); } createCommand創(chuàng)建了一個(gè)CommandClass的對(duì)象。 然后再看bindAndValidate方法: protected final ServletRequestDataBinder bindAndValidate(HttpServletRequest request, Object command) throws Exception { ServletRequestDataBinder binder = createBinder(request, command); BindException errors = new BindException(binder.getBindingResult()); if (!suppressBinding(request)) { binder.bind(request); onBind(request, command, errors); if (this.validators != null && isValidateOnBinding() && !suppressValidation(request, command, errors)) { for (int i = 0; i < this.validators.length; i++) { ValidationUtils.invokeValidator(this.validators[i], command, errors); } } onBindAndValidate(request, command, errors); } return binder; } 這個(gè)方法首先創(chuàng)建了 DataBinder對(duì)象,然后,獲取創(chuàng)建綁定對(duì)象時(shí)發(fā)生的錯(cuò)誤。報(bào)錯(cuò)在errors。接下來綁定對(duì)象,調(diào)用onBind處理綁定事件;接下來應(yīng)用Validator。然后調(diào)用onBindAndValidate來處理綁定和驗(yàn)證事件。最后返回binder。 處理完之后調(diào)用handle方法進(jìn)行處理。 綜上所述,AbstractCommandController具有兩個(gè)功能: 1、將請(qǐng)求參數(shù)轉(zhuǎn)換為Command對(duì)象。在該Controller中,我們設(shè)置一個(gè)object對(duì)象。然后BaseCommandController將請(qǐng)求的參數(shù)進(jìn)行轉(zhuǎn)換。如果請(qǐng)求參數(shù)有value值,就會(huì)調(diào)用object的的setValue對(duì)象來設(shè)置對(duì)象里的值。如果請(qǐng)求參數(shù)中有address.city.就會(huì)調(diào)用object中g(shù)etAddress().setCity()方法來賦值。這個(gè)object可以是任意的object,唯一的要求就是這個(gè)object類沒有參數(shù)。 2、對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證。在轉(zhuǎn)換和驗(yàn)證時(shí)發(fā)生錯(cuò)誤時(shí),需要在handle(request, response, command, errors)中進(jìn)行處理。 posted @ 2009-11-25 16:25 追求無止境 閱讀(5384) | 評(píng)論 (0) | 編輯 收藏 Spring的MVC web框架學(xué)習(xí)筆記1、Spring web 框架的核心:DispatcherServlet DispatcherServlet 用于接收請(qǐng)求。是使用Spring框架的入口。在web.xml中,需要配置該servlet。在配置該Servlet的時(shí)候url-pattern你可以使用你自己想使用的形式,如*.aspx,*.do,*.htm,*.action,用以混淆客戶端對(duì)服務(wù)器架構(gòu)的認(rèn)識(shí)。 另外,該Servlet在容器中還會(huì)加載一個(gè)APPlicationContext的xml文件。默認(rèn)加載的是[servlet-name]-servlet.xml。例如,你在web.xml中配置的servlet如下: <web-app> <servlet> <servlet-name>example</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>*.form</url-pattern> </servlet-mapping> </web-app> 該Servlet就會(huì)在服務(wù)器啟動(dòng)時(shí),加載example-servlet.xml。當(dāng)然,你也可以自己來指定加載文件。 要看看DispatcherServlet真面目,打開源文件,發(fā)現(xiàn)定義了很多BeanName的常量,如本地化解析器beanname,主題解析器beanname,視圖解析器beanname,上傳文件解析的multipart解析器beanname。 等: public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver"; public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver"; public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping"; public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter"; public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver"; public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator"; public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver"; 這個(gè)類怎么使用這些bean呢?以上面的exexample-servlet.xml為例,我們定義的名字為example的DispatcherServlet使用example-servlet.xml的配置。在example-servlet.xml里,我們可以配置名字上面的beanName的bean,來讓servlet加載這些bean。 這下明白了,servlet.xml該怎么配置,該配置什么了。 好了,看完了最重要的servlet的配置問題,我們再看下一個(gè)重要的接口:Controller。至于上面servlet要使用的什么什么解析器啦,我們稍后在分析。 2、Controller 我們的請(qǐng)求提交到DispacherServlet后,會(huì)轉(zhuǎn)給Controller。怎么找Controller?通過使用handlerMapping。如果沒有設(shè)置handlerMapping,spring使用默認(rèn)的BeanNameUrlHandlerMapping來找Controller。 BeanNameUrlHandlerMapping?顧名思義,就是通過bean的name屬性來映射controller。bean的name請(qǐng)求是一個(gè)url,如果請(qǐng)求的是logout.do,在example-servlet.xml中定義一個(gè)名字(name)為login.do的Controller. <bean name="/logout.do" class="com.jy.bookshop.web.spring.LogoutController"> 再插一句話,在handlerMapping中,我們可以使用請(qǐng)求攔截器來對(duì)請(qǐng)求進(jìn)行攔截處理。該攔截器怎么使用這里暫且不表,有機(jī)會(huì)再討論。 ok,現(xiàn)在我們創(chuàng)建一個(gè)LogoutController來讓他處理請(qǐng)求,讓他實(shí)現(xiàn)Controller吧: public class LogOutController implements Controller { public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception { … return new ModelAndView(new RedirectView("login.do")); } } 看看這個(gè)Controller接口的定義,發(fā)現(xiàn)這個(gè)接口只定義了一個(gè)handleRequest方法。在這個(gè)方法中,返回一個(gè)ModelAndView。 先說ModelAndView。我們知道MVC,那么ModelAndView就是 MV了。Controller就是C。這樣MVC全了。呵呵。 繼續(xù)說ModelAndView,要了解他的結(jié)構(gòu),那自然要看看他的源代碼了: /** View instance or view name String */ private Object view; /** Model Map */ private ModelMap model;
只關(guān)注我們關(guān)注的,里面包含了一個(gè)View對(duì)象和model對(duì)象。model對(duì)象是一個(gè)Map,這里不再說了。關(guān)鍵看看view,奇怪,怎么是一個(gè)Object,太抽象了。再繼續(xù)看源代碼的話,會(huì)更加明白:
public ModelAndView(String viewName, String modelName, Object modelObject) { this.view = viewName; addObject(modelName, modelObject); } public void setViewName(String viewName) { this.view = viewName; } 原來這個(gè)view可以指向一個(gè)View對(duì)象,也可以指向String對(duì)象啊。View一個(gè)接口,如果看doc的話,他的實(shí)現(xiàn)類有AbstractExcelView, AbstractJasperReportsSingleFormatView, AbstractJasperReportsView, AbstractJExcelView, AbstractPdfStamperView, AbstractPdfView,AbstractTemplateView, AbstractUrlBasedView, AbstractView, AbstractXsltView, ConfigurableJasperReportsView, FreeMarkerView, InternalResourceView,JasperReportsCsvView, JasperReportsHtmlView, JasperReportsMultiFormatView, JasperReportsPdfView, JasperReportsXlsView, JstlView, RedirectView,TilesJstlView, TilesView, TilesView, VelocityLayoutView, VelocityToolboxView, VelocityView, XsltView(誠實(shí)的說,這些View是拷doc的)。 現(xiàn)在可以知道,我們的Controller返回一個(gè)View和Model,來讓Spring框架來創(chuàng)建一個(gè)回應(yīng)。 現(xiàn)在奇怪的還有一點(diǎn),我吧view設(shè)置為字符串,Spring框架怎么處理?在ModelAndView中,如果view是一個(gè)字符串,則會(huì)將這個(gè)值交給DispatcherServlet的viewResovler來處理。記得上面提到的viewResovler了嗎?呵呵,派上用場了。 view的問題解決了,然后再說model吧。在ModelAndView添加了一些對(duì)象,Spring是怎么處理的呢?總應(yīng)該把這些對(duì)象給弄到request對(duì)象里,讓jsp頁面來使用吧。讓View使用?那么看看View接口吧: public interface View { String getContentType(); void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception; } render函數(shù)需要帶一個(gè)model變量。再找找view的實(shí)現(xiàn)類,看看是怎么工作的。不過view有那么多,對(duì)于一些像什么pdf啦,excel了他們都不需要在request中添加這個(gè)model。 最終呢,我們在jstlView的父類InternalResourceView中的renderMergedOutputModel函數(shù)發(fā)現(xiàn)他把model放在了request里面了。 OK,現(xiàn)在我們明白了,controller返回的modelandview交給Servlet進(jìn)行處理,來生成一個(gè)頁面。 最簡單的Controller介紹完畢。現(xiàn)在看看Spring提供的一些controller的實(shí)現(xiàn),Spring提供了很多controller的實(shí)現(xiàn),繼承的結(jié)構(gòu)如下:
org.springframework.web.servlet.mvc.AbstractController (implements org.springframework.web.servlet.mvc.Controller)
AbstractController是Controller的第一個(gè)實(shí)現(xiàn)。其他的Controller都是繼承這個(gè)Controller的。我們先看比較重要的Controller。 先說UrlFilenameViewController。不如我們自己來部署一個(gè)吧。 在example-servlet.xml中增加如下的配置: <bean name="/error.do" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"> OK,當(dāng)/error.do的請(qǐng)求上來后,urlFileNameViewController將他變成/error。然后返回個(gè)View,這個(gè)view的name就是/error,然后使用viewresolver來進(jìn)行解析,可以解析成/jsp/error.jsp。 另外還有比較重要的controller是baseCommandController,將請(qǐng)求參數(shù)轉(zhuǎn)換為一個(gè)對(duì)象,并對(duì)對(duì)象參數(shù)合法性進(jìn)行驗(yàn)證。另外,SimpleFormController可以對(duì)表單進(jìn)行處理。 關(guān)于各個(gè)controller的分析。未完待續(xù)。。
posted @ 2009-11-25 11:09 追求無止境 閱讀(3716) | 評(píng)論 (2) | 編輯 收藏 [轉(zhuǎn)] java.beans.PropertyEditor(屬性編輯器)簡單應(yīng)用原文:http://www.aygfsteel.com/orangewhy/archive/2007/06/26/126371.html
java.beans.PropertyEditor的從字義來看是一個(gè)屬性編輯器,但總覺得它的作用更像一個(gè)轉(zhuǎn)換器--從字符串轉(zhuǎn)換為類對(duì)象的屬性。 java.beans.PropertyEditor接口定義的方法有好幾個(gè),但是最重要為下面兩個(gè): void setValue(Object value) void setAsText(String text) throws java.lang.IllegalArgumentException; 一般地,我們要使用PropertyEditor時(shí),并不直接實(shí)現(xiàn)此接口,而是通過繼承實(shí)現(xiàn)此接口的java.beans.PropertyEditorSupport來簡化我們的工作,在子類覆蓋setAsText方法就可以了,setValue方法一般不直接使用,在setAsText方法中將字符串進(jìn)行轉(zhuǎn)換并產(chǎn)生目標(biāo)對(duì)象以后,由調(diào)setAsText調(diào)用setValue來把目標(biāo)對(duì)象注入到編輯器中。當(dāng)然,你可用覆蓋更多的方法來滿足你的特殊要求。JavaBean的類和接口,被大部分spring包使用,可以從spring中學(xué)習(xí)更成熟的JavaBean使用方法。 簡單的例子: 實(shí)體類Person: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
Person的屬性編輯器: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
測試代碼: ![]() ![]() ![]() ![]() ![]() ![]()
結(jié)果輸出: ![]() posted @ 2009-11-20 22:07 追求無止境 閱讀(296) | 評(píng)論 (0) | 編輯 收藏 提高開發(fā)技術(shù)的Tip以下Tip和學(xué)習(xí)路線從自己身上出發(fā)進(jìn)行總結(jié),僅代表個(gè)人觀點(diǎn)。你可以留言進(jìn)行討論。 1.有計(jì)劃的學(xué)習(xí)學(xué)習(xí)是一個(gè)循序漸進(jìn)的過程。如果沒有一個(gè)計(jì)劃,學(xué)習(xí)將變得沒有規(guī)律,我們也無法提高自己的能力。想起上學(xué)的時(shí)候,學(xué)校每個(gè)學(xué)期都會(huì)制定一個(gè)教學(xué)大綱來指導(dǎo)老師的教學(xué)和我們的學(xué)習(xí)。是的,如果沒有計(jì)劃,今天突然想學(xué)這個(gè),明天突然想學(xué)那個(gè),朝三暮四,我們永遠(yuǎn)也無法學(xué)到自己想學(xué)的東西。所以我們需要制定一個(gè)學(xué)習(xí)計(jì)劃。有計(jì)劃的學(xué)習(xí)才能提高自己的能力。Java web項(xiàng)目的開發(fā)是需要很多知識(shí)的積累的,包括Java SE,數(shù)據(jù)庫,JDBC,Linux,Log4j,Html/CSS/Javascript,持久層框架,JUNIT及其他測試框架,IOC框架,web MVC框架等等,如果我們沒有一個(gè)良好的計(jì)劃,今天學(xué)習(xí)Log4j,明天學(xué)習(xí)Junit,這些東西都不會(huì)掌握好并學(xué)習(xí)好。 如果給自己做計(jì)劃。計(jì)劃可以按照時(shí)間段來進(jìn)行。例如本年度的工作,本季度要達(dá)到的水平,本月要學(xué)習(xí)的東西,本周學(xué)習(xí)的計(jì)劃安排,以及每一天的安排。每天晚上睡覺前,想想今天的計(jì)劃安排是否完成,明天該學(xué)習(xí)什么;每周到結(jié)束的時(shí)候,總結(jié)一下本周完成了什么,下周要學(xué)習(xí)什么。根據(jù)自己對(duì)計(jì)劃的實(shí)行情況可以改變自己的計(jì)劃。總之要有計(jì)劃的學(xué)習(xí)。可以使用google 日歷和 qq mail 郵箱等來管理自己的計(jì)劃。 2. 同一段時(shí)間只學(xué)習(xí)一種技術(shù)我是一個(gè)什么都想學(xué)的人。我不想把自己的時(shí)間都用在學(xué)習(xí)Java上,我還想學(xué)習(xí)C++,還想學(xué)習(xí) web 設(shè)計(jì),還想學(xué)好windows編程,想學(xué)Linux編程,想學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)編程,想學(xué)習(xí)路由器、網(wǎng)絡(luò)的配置……。于是,今天看了VC++深入詳解,明天學(xué)習(xí)Linux shell編程。計(jì)算機(jī)技術(shù)包含了太多技術(shù)。我們無法一一將他們都掌握。所以不要想什么都學(xué)會(huì)。至少在一段時(shí)間內(nèi)學(xué)習(xí)一種技術(shù)。我給自己制定了這樣的計(jì)劃,今年要把所有的精力都致力為 java EE 開發(fā)技術(shù)上。一年后,努力學(xué)習(xí)C/C++編程。 是的。我們學(xué)習(xí)的東西可以廣一點(diǎn),但一定要有自己專的方面。學(xué)專了一個(gè)方面,你就可以接著學(xué)習(xí)其他的技術(shù)。一個(gè)什么都會(huì)的人,很可能什么都不會(huì);所以,精于一,而博于廣。 3.學(xué)會(huì)休息我們都很忙,上學(xué)的時(shí)候?qū)W好各科,至少不能掛科,然后在課外學(xué)習(xí)自己喜歡的java 編程;工作的時(shí)候,需要做好工作,然后在工作之余多學(xué)一些東西;時(shí)間長了,我們就可能倦了,累了。所以我們需要學(xué)會(huì)休息來改變自己的精神狀態(tài)。 整天在電腦前進(jìn)行軟件開發(fā)的我們,要學(xué)會(huì)放松自己和休息。作為程序員整天在電腦前,極容易養(yǎng)成工作和休息都離不開電腦的習(xí)慣。休息的時(shí)候,也是在電腦前看電影,玩游戲。我想,在我們工作累了之后,應(yīng)該離開電腦,走向戶外來放松和休息。或到大街上轉(zhuǎn)轉(zhuǎn),或到商場里購物,或去游泳館游泳,或去健身房健身,或和朋友一起打臺(tái)球。等等等等。總之要學(xué)會(huì)放松自己,走出戶外,不要整天在電腦前。 以上3點(diǎn)是自己對(duì)自己工作學(xué)習(xí)的總結(jié)和提醒,特別寫出來和大家一起分享。
感謝HiMagic!分享自己的觀點(diǎn)。值得學(xué)習(xí)。
posted @ 2009-11-16 15:11 追求無止境 閱讀(1780) | 評(píng)論 (6) | 編輯 收藏 Java DOC學(xué)習(xí)筆記1、Interface Comparable<T> 只有實(shí)現(xiàn)該接口的對(duì)象的列表或數(shù)組才能調(diào)用Collections.sort()方法。 在實(shí)現(xiàn) int
2、Interface Iterable<T>
3、Interface Readable java.lang.Interface Readable一個(gè)Readable 是一個(gè)字符串的來源。實(shí)現(xiàn)這個(gè)接口需要實(shí)現(xiàn)的方法是:
5、java.lang Interface Thread.UncaughtExceptionHandler 從名字就可以判斷出來,當(dāng)線程拋出未捕獲的異常時(shí),實(shí)現(xiàn)這個(gè)接口的類的對(duì)象可以對(duì)一場進(jìn)行處理。 官方文檔:當(dāng)線程被一個(gè)未捕獲的異常打斷時(shí),這個(gè)接口被調(diào)用。 當(dāng)線程要被為捕獲異常打斷是,JVM使用
6、包裝型對(duì)象:Boolean Byte Character Double Float Long Short Integer 這些類就不用了說了,主要會(huì)使用里面的靜態(tài)方法和一些常量就可以了。 7、Class Character.Subset 這個(gè)類的實(shí)例代表了Unicode字符集的特殊的子集。定義在Character中的唯一子集族類是UnicodeBlock.其他的Java API或許因?yàn)樽约旱挠脩舳x了其他的子集。
………… 具體參見java.lang 8 、java.langClass Class<T>這個(gè)類的實(shí)力代表了Java運(yùn)行程序中的類和接口。Enum是類,而Annotation是一個(gè)接口。Every array also belongs to a class that is reflected as a Class的對(duì)象在程序中可以獲取類的詳細(xì)信息。 9、Java.lang.Class ClassLoader ClassLoader是個(gè)不錯(cuò)的東西,下面是官方文檔的簡單翻譯和注解: 1、ClassLoader用于加載類對(duì)象。ClassLoader是一個(gè)抽象類。給出類的二進(jìn)制名字(如“ "java.lang.String" "javax.swing.JSpinner$DefaultEditor" "java.security.KeyStore$Builder$FileBuilder$1" "java.net.URLClassLoader$3$1" ”),ClassLoader會(huì)使用定位和生成類。一個(gè)典型的策略就是將二進(jìn)制名字轉(zhuǎn)化為文件名,然后從文件系統(tǒng)中讀取這個(gè)類文件。 每一個(gè)Class對(duì)象都包含了一個(gè)創(chuàng)建它的引用。 數(shù)組的Class對(duì)象不能由ClassLoader創(chuàng)建,但是可以由Java運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建。一個(gè)數(shù)組類的ClassLoader,和他的元素的ClassLoader是一樣的;如果元素是基本類型,則數(shù)組類沒有ClassLoader。 應(yīng)用程序可以實(shí)現(xiàn)ClassLoader的子類,來擴(kuò)展行為。這樣可以在JVM動(dòng)態(tài)的創(chuàng)建類。 ClassLoader主要由安全管理器來使用,用于保證安全區(qū)域。 ClassLoader 使用一個(gè)delegation(委托)模型來搜索類和資源。每一個(gè)ClassLoader有一個(gè)相關(guān)的父類ClassLoader。當(dāng)請(qǐng)求來查找一個(gè)資源或者類的時(shí)候,ClassLoader 實(shí)例會(huì)委托搜索類和資源。 內(nèi)建的ClassLoader,叫做bootstrap class loader,沒有父類。 正常的,ClassLoader從本地文件系統(tǒng)中加載數(shù)據(jù)。通過CLassPath。 當(dāng)然,也可以通過NetWork從服務(wù)器上下載字節(jié)碼。來加載類: ClassLoader loader = new NetworkClassLoader(host, port); Object main = loader.loadClass("Main", true).newInstance(); Network ClassLoader 子類必須定義方法FindClass 和loadClassData來加載來自互聯(lián)網(wǎng)上的類。一旦或得到字節(jié)碼,它使用defineClass方法來創(chuàng)建類實(shí)例。 class NetworkClassLoader extends ClassLoader { String host; int port; public Class findClass(String name) { byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); } private byte[] loadClassData(String name) { // load the class data from the connection . . . } } 個(gè)人理解: ClassLoader是一個(gè)類加載器,除了可以從ClassPath加載類之外,還可以從ClassPath中加載資源:
10、Compiler類3 編譯類是提供給支持Java到本地代碼編譯器和相關(guān)服務(wù)。根據(jù)設(shè)計(jì),編譯器類什么都不做;它作為一個(gè)占位符來為運(yùn)行時(shí)編譯執(zhí)行的技術(shù)。 當(dāng)JVM第一次啟動(dòng)時(shí),他判斷java.compiler是否存在。如果存在,他3 posted @ 2009-11-16 13:11 追求無止境 閱讀(145) | 評(píng)論 (0) | 編輯 收藏 CSS學(xué)習(xí)筆記1、background相關(guān): 屬性 background background-attachment background-color background-image background-position background-repeat (1)background
2、文本相關(guān) text-indent :縮進(jìn)元素中的首行文本。 值 length % text-align: 文本對(duì)應(yīng)方式 您可能會(huì)認(rèn)為 text-align:center 與 <CENTER> 元素的作用一樣,但實(shí)際上二者大不相同。 <CENTER> 不僅影響文本,還會(huì)把整個(gè)元素居中。text-align 不會(huì)控制元素的對(duì)齊,而只影響內(nèi)部內(nèi)容。元素本身不會(huì)從一段移到另一端,只是其中的文本受影響。 值 left right center justify word-spacing :以改變字(單詞)之間的標(biāo)準(zhǔn)間隔 值 normal length letter-spacing:改變字母之間的距離 值 normal length text-transform:處理文本的大小寫 值 none capitalize uppercase lowercase 值 none underline overline line-through blink 值 normal pre nowrap pre-wrap pre-line
direction :文本的方向?qū)傩?/p> ltr rtl 屬性 color direction line-height letter-spacing text-align text-decoration text-indent text-shadow text-transform unicode-bidi white-space word-spacing 3、CSS字體相關(guān) font font-family font-size font-size-adjust font-stretch font-style font-variant font-weight CSS 列表屬性(list)屬性 list-style list-style-image
list-style-position
list-style-type
marker-offset CSS Table 屬性CSS 表格屬性允許你設(shè)置表格的布局。(請(qǐng)注意,本節(jié)介紹的不是如何使用表來建立布局,而是要介紹 CSS 中表本身如何布局。) 屬性 border-collapse caption-side table-layout CSS 邊框?qū)傩?/h4>"CSS" 列中的數(shù)字指示哪個(gè) CSS 版本定義了該屬性。 輪廓(outline)是繪制于元素周圍的一條線,位于邊框邊緣的外圍,可起到突出元素的作用。 CSS outline 屬性規(guī)定元素輪廓的樣式、顏色和寬度。 outline outline-color outline-style outline-width CSS 框模型概述
CSS 框模型 (Box Model) 規(guī)定了元素框處理元素內(nèi)容、內(nèi)邊距、邊框 和 外邊距 的方式。
CSS 內(nèi)邊距屬性屬性 padding padding-bottom padding-left padding-right padding-top CSS 邊框?qū)傩?/h4>屬性 border border-style
border-width
border-color
border-bottom border-bottom-color border-bottom-style border-bottom-width border-left border-left-color border-left-style border-left-width border-right border-right-color border-right-style border-right-width border-top border-top-color border-top-style border-top-width CSS 外邊距屬性屬性 margin margin-bottom margin-left margin-right margin-top CSS 定位屬性CSS 定位屬性允許你對(duì)元素進(jìn)行定位。 詳細(xì)參見http://www.w3school.com.cn/css/css_positioning.asp CSS 定位和浮動(dòng)CSS 為定位和浮動(dòng)提供了一些屬性,利用這些屬性,可以建立列式布局,將布局的一部分與另一部分重疊,還可以完成多年來通常需要使用多個(gè)表格才能完成的任務(wù)。 定位的基本思想很簡單,它允許你定義元素框相對(duì)于其正常位置應(yīng)該出現(xiàn)的位置,或者相對(duì)于父元素、另一個(gè)元素甚至瀏覽器窗口本身的位置。顯然,這個(gè)功能非常強(qiáng)大,也很讓人吃驚。要知道,用戶代理對(duì) CSS2 中定位的支持遠(yuǎn)勝于對(duì)其它方面的支持,對(duì)此不應(yīng)感到奇怪。 另一方面,CSS1 中首次提出了浮動(dòng),它以 Netscape 在 Web 發(fā)展初期增加的一個(gè)功能為基礎(chǔ)。浮動(dòng)不完全是定位,不過,它當(dāng)然也不是正常流布局。我們會(huì)在后面的章節(jié)中明確浮動(dòng)的含義。 一切皆為框div、h1 或 p 元素常常被稱為塊級(jí)元素。這意味著這些元素顯示為一塊內(nèi)容,即“塊框”。與之相反,span 和 strong 等元素稱為“行內(nèi)元素”,這是因?yàn)樗鼈兊膬?nèi)容顯示在行中,即“行內(nèi)框”。 您可以使用 display 屬性改變生成的框的類型。這意味著,通過將 display 屬性設(shè)置為 block,可以讓行內(nèi)元素(比如 <a> 元素)表現(xiàn)得像塊級(jí)元素一樣。還可以通過把 display 設(shè)置為 none,讓生成的元素根本沒有框。這樣的話,該框及其所有內(nèi)容就不再顯示,不占用文檔中的空間。 但是在一種情況下,即使沒有進(jìn)行顯式定義,也會(huì)創(chuàng)建塊級(jí)元素。這種情況發(fā)生在把一些文本添加到一個(gè)塊級(jí)元素(比如 div)的開頭。即使沒有把這些文本定義為段落,它也會(huì)被當(dāng)作段落對(duì)待: <div> some text <p>Some more text.</p> </div> 在這種情況下,這個(gè)框稱為無名塊框,因?yàn)樗慌c專門定義的元素相關(guān)聯(lián)。 塊級(jí)元素的文本行也會(huì)發(fā)生類似的情況。假設(shè)有一個(gè)包含三行文本的段落。每行文本形成一個(gè)無名框。無法直接對(duì)無名塊或行框應(yīng)用樣式,因?yàn)闆]有可以應(yīng)用樣式的地方(注意,行框和行內(nèi)框是兩個(gè)概念)。但是,這有助于理解在屏幕上看到的所有東西都形成某種框。 CSS 定位機(jī)制CSS 有三種基本的定位機(jī)制:普通流、浮動(dòng)和絕對(duì)定位。 除非專門指定,否則所有框都在普通流中定位。也就是說,普通流中的元素的位置由元素在 X(HTML) 中的位置決定。 塊級(jí)框從上到下一個(gè)接一個(gè)地排列,框之間的垂直距離是由框的垂直外邊距計(jì)算出來。 行內(nèi)框在一行中水平布置。可以使用水平內(nèi)邊距、邊框和外邊距調(diào)整它們的間距。但是,垂直內(nèi)邊距、邊框和外邊距不影響行內(nèi)框的高度。由一行形成的水平框稱為行框(Line Box),行框的高度總是足以容納它包含的所有行內(nèi)框。不過,設(shè)置行高可以增加這個(gè)框的高度。 在下面的章節(jié),我們會(huì)為您詳細(xì)講解相對(duì)定位、絕對(duì)定位和浮動(dòng)。 CSS position 屬性通過使用 position 屬性,我們可以選擇 4 中不同類型的定位,這會(huì)影響元素框生成的方式。 position 屬性值的含義:
提示:相對(duì)定位實(shí)際上被看作普通流定位模型的一部分,因?yàn)樵氐奈恢孟鄬?duì)于它在普通流中的位置。 屬性 position
top
right bottom left overflow
clip
vertical-align
z-index
CSS 尺寸屬性CSS 尺寸屬性允許你控制元素的高度和寬度。同樣,還允許你增加行間距。 屬性 height line-height max-height max-width min-height min-width width CSS 分類屬性 (Classification)CSS 分類屬性允許你控制如何顯示元素,設(shè)置圖像顯示于另一元素中的何處,相對(duì)于其正常位置來定位元素,使用絕對(duì)值來定位元素,以及元素的可見度。 屬性 clear cursor display float position visibility
偽類瀏覽器支持:IE Internet Explorer, F: Firefox, N: Netscape。 W3C:“W3C” 列的數(shù)字顯示出偽類屬性由哪個(gè) CSS 標(biāo)準(zhǔn)定義(CSS1 還是 CSS2)。 偽類 :active :focus :hover :link :visited :first-child :lang 偽元素 :first-letter :first-line :before :after
不同的媒介類型注釋:媒介類型名稱對(duì)大小寫不敏感。 瀏覽器支持:IE: Internet Explorer, F: Firefox, N: Netscape。 W3C:“W3C” 列的數(shù)字顯示出屬性背景由哪個(gè) CSS 標(biāo)準(zhǔn)定義(CSS1 還是 CSS2)。 媒介類型 all aural braille embossed handheld print projection screen tty tv posted @ 2009-11-16 13:08 追求無止境 閱讀(288) | 評(píng)論 (0) | 編輯 收藏 JDBC高級(jí)特性1、可滾動(dòng)的結(jié)果集(Scrollable Result Sets) (1)創(chuàng)建可滾動(dòng)的結(jié)果集: Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet.
ResultSet.CONCUR_READ_ONLY:結(jié)果集是只讀的。 ResultSet.
盡管我們可以在這里設(shè)置創(chuàng)建的是可滾動(dòng)結(jié)果集,但是如果廠商的JDBC實(shí)現(xiàn)不支持,我們獲取到的結(jié)果將不具有可滾動(dòng)屬性。 可以使用ResultSet.getType()方法來獲取是否支持滾動(dòng): int type = rs.getType(); The variable
rs.isAfterLast(); rs.isBeforeFirst(); rs.isLast(); rs.isFirst(); rs.hasNext(); 等等方法。 2、更新結(jié)果集 (1)創(chuàng)建可以更新的結(jié)果集 Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet uprs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES"); 在JDBC 2.0中,我們可以向可以更新的結(jié)果集中插入行或刪除行,或者修改其中的行。 下面的方法用于判斷結(jié)果集是否可以更新: int concurrency = uprs.getConcurrency(); The variable
(2)更新結(jié)果集 JDBC 1.0中可以這樣更新: stmt.executeUpdate( "UPDATE COFFEES SET PRICE = 10.99 " + "WHERE COF_NAME = 'French_Roast_Decaf'"); 在JDBC2.0中。則可以: uprs.last(); uprs.updateFloat("PRICE", 10.99f); uprs.updateRow(); 在移動(dòng)游標(biāo)前,必須先調(diào)用updateRow方法。否則更新信息會(huì)丟失。調(diào)用cancelRowUpdates可以取消對(duì)行的更新。 (3)向結(jié)果集中插入或者刪除行 Connection con = DriverManager.getConnection( "jdbc:mySubprotocol:mySubName"); Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet uprs = stmt.executeQuery( "SELECT * FROM COFFEES"); uprs.moveToInsertRow(); uprs.updateString("COF_NAME", "Kona"); uprs.updateInt("SUP_ID", 150); uprs.updateFloat("PRICE", 10.99f); uprs.updateInt("SALES", 0); uprs.updateInt("TOTAL", 0); uprs.insertRow(); 在移動(dòng)游標(biāo)前,必須要先調(diào)用insertRow否則插入的信息將丟失。 uprs.absolute(4); uprs.deleteRow(); 刪除行。 (4)查看結(jié)果集中的變化(其實(shí)就是說了一個(gè)意思,用
Result sets vary greatly in their ability to reflect changes made in their underlying data. If you modify data in a So when can you see visible changes you or others made while the With a You can, to some extent, regulate what changes are visible by raising or lowering the transaction isolation level for your connection with the database. For example, the following line of code, where con.setTransactionIsolation( Connection.TRANSACTION_READ_COMMITTED); With this isolation level, a int level = con.getTransactionIsolation(); The explanation of If you want more information about the visibility of changes and transaction isolation levels, see "What Is Visible to Transactions" on page 597. In a posted @ 2009-11-16 13:05 追求無止境 閱讀(280) | 評(píng)論 (0) | 編輯 收藏 視頻感想昨天晚上看了關(guān)于“都市信息網(wǎng)”項(xiàng)目開發(fā)視頻,給人總體感覺差強(qiáng)人意,學(xué)到了一些知識(shí),記錄如下: 1、頁面結(jié)構(gòu):
2、關(guān)于controller:
3、關(guān)于DAO層的設(shè)計(jì)
4、關(guān)于TreeMap
有了這幾條規(guī)則,就可以保證整棵樹的平衡,也就等于保證了搜索的時(shí)間為O(log N)。 但是在插入、刪除節(jié)點(diǎn)后,就有可能破壞了紅黑樹的性質(zhì)。所以我們要做一些操作來把整棵樹修補(bǔ)好。下面我就來介紹一下。 posted @ 2009-11-16 13:03 追求無止境 閱讀(98) | 評(píng)論 (0) | 編輯 收藏 一個(gè)簡單的小測驗(yàn),考查一下對(duì)Java基礎(chǔ)的掌握情況
今天看Java Language Specification的時(shí)候看到了下面的一段代碼:
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 輸出的結(jié)果出人預(yù)料。不運(yùn)行它,大家自己想想答案吧,然后把答案和你的想法貼出來分享給大家吧。 正確答案的話,運(yùn)行一下運(yùn)行一下就知道了。。 posted @ 2009-08-11 09:39 追求無止境 閱讀(1536) | 評(píng)論 (8) | 編輯 收藏 JSP優(yōu)化(轉(zhuǎn))
你時(shí)常被客戶抱怨JSP頁面響應(yīng)速度很慢嗎?你想過當(dāng)客戶訪問次數(shù)劇增時(shí),你的WEB應(yīng)用能承受日益增加的訪問量嗎?本文講述了調(diào)整JSP和servlet的一些非常實(shí)用的方法,它可使你的servlet和JSP頁面響應(yīng)更快,擴(kuò)展性更強(qiáng)。而且在用戶數(shù)增加的情況下,系統(tǒng)負(fù)載會(huì)呈現(xiàn)出平滑上長的趨勢。在本文中,我將通過一些實(shí)際例子和配置方法使得你的應(yīng)用程序的性能有出人意料的提升。其中,某些調(diào)優(yōu)技術(shù)是在你的編程工作中實(shí)現(xiàn)的。而另一些技術(shù)是與應(yīng)用服務(wù)器的配置相關(guān)的。在本文中,我們將詳細(xì)地描述怎樣通過調(diào)整servlet和JSP頁面,來提高你的應(yīng)用程序的總體性能。在閱讀本文之前,假設(shè)你有基本的servlet和JSP的知識(shí)。
方法一:在servlet的init()方法中緩存數(shù)據(jù)
當(dāng)應(yīng)用服務(wù)器初始化servlet實(shí)例之后,為客戶端請(qǐng)求提供服務(wù)之前,它會(huì)調(diào)用這個(gè)servlet的init()方法。在一個(gè)servlet的生命周期中,init()方法只會(huì)被調(diào)用一次。通過在init()方法中緩存一些靜態(tài)的數(shù)據(jù)或完成一些只需要執(zhí)行一次的、耗時(shí)的操作,就可大大地提高系統(tǒng)性能。
例如,通過在init()方法中建立一個(gè)JDBC連接池是一個(gè)最佳例子,假設(shè)我們是用jdbc2.0的DataSource接口來取得數(shù)據(jù)庫連接,在通常的情況下,我們需要通過JNDI來取得具體的數(shù)據(jù)源。我們可以想象在一個(gè)具體的應(yīng)用中,如果每次SQL請(qǐng)求都要執(zhí)行一次JNDI查詢的話,那系統(tǒng)性能將會(huì)急劇下降。解決方法是如下代碼,它通過緩存DataSource,使得下一次SQL調(diào)用時(shí)仍然可以繼續(xù)利用它:
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
<tr>
<td>public class ControllerServlet extends HttpServlet
{
private javax.sql.DataSource testDS = null;
public void init(ServletConfig config) throws ServletException
{
super.init(config);
Context ctx = null;
try
{
ctx = new InitialContext();
testDS = (javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingException ne)
{
ne.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public javax.sql.DataSource getTestDS()
{
return testDS;
}
...
...
}</td></tr></table>
方法 2:禁止servlet和JSP 自動(dòng)重載(auto-reloading)
Servlet/JSP提供了一個(gè)實(shí)用的技術(shù),即自動(dòng)重載技術(shù),它為開發(fā)人員提供了一個(gè)好的開發(fā)環(huán)境,當(dāng)你改變servlet和JSP頁面后而不必重啟應(yīng)用服務(wù)器。然而,這種技術(shù)在產(chǎn)品運(yùn)行階段對(duì)系統(tǒng)的資源是一個(gè)極大的損耗,因?yàn)樗鼤?huì)給JSP引擎的類裝載器(classloader)帶來極大的負(fù)擔(dān)。因此關(guān)閉自動(dòng)重載功能對(duì)系統(tǒng)性能的提升是一個(gè)極大的幫助。
方法 3: 不要濫用HttpSession
在很多應(yīng)用中,我們的程序需要保持客戶端的狀態(tài),以便頁面之間可以相互聯(lián)系。但不幸的是由于HTTP具有天生無狀態(tài)性,從而無法保存客戶端的狀態(tài)。因此一般的應(yīng)用服務(wù)器都提供了session來保存客戶的狀態(tài)。在JSP應(yīng)用服務(wù)器中,是通過HttpSession對(duì)像來實(shí)現(xiàn)session的功能的,但在方便的同時(shí),它也給系統(tǒng)帶來了不小的負(fù)擔(dān)。因?yàn)槊慨?dāng)你獲得或更新session時(shí),系統(tǒng)者要對(duì)它進(jìn)行費(fèi)時(shí)的序列化操作。你可以通過對(duì)HttpSession的以下幾種處理方式來提升系統(tǒng)的性能:
· 如果沒有必要,就應(yīng)該關(guān)閉JSP頁面中對(duì)HttpSession的缺省設(shè)置: 如果你沒有明確指定的話,每個(gè)JSP頁面都會(huì)缺省地創(chuàng)建一個(gè)HttpSession。如果你的JSP中不需要使用session的話,那可以通過如下的JSP頁面指示符來禁止它:
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
<tr>
<td><%@ page session="false"%> </td></tr></table>
· 不要在HttpSession中存放大的數(shù)據(jù)對(duì)像:如果你在HttpSession中存放大的數(shù)據(jù)對(duì)像的話,每當(dāng)對(duì)它進(jìn)行讀寫時(shí),應(yīng)用服務(wù)器都將對(duì)其進(jìn)行序列化,從而增加了系統(tǒng)的額外負(fù)擔(dān)。你在HttpSession中存放的數(shù)據(jù)對(duì)像越大,那系統(tǒng)的性能就下降得越快。
· 當(dāng)你不需要HttpSession時(shí),盡快地釋放它:當(dāng)你不再需要session時(shí),你可以通過調(diào)用HttpSession.invalidate()方法來釋放它。
· 盡量將session的超時(shí)時(shí)間設(shè)得短一點(diǎn):在JSP應(yīng)用服務(wù)器中,有一個(gè)缺省的session的超時(shí)時(shí)間。當(dāng)客戶在這個(gè)時(shí)間之后沒有進(jìn)行任何操作的話,系統(tǒng)會(huì)將相關(guān)的session自動(dòng)從內(nèi)存中釋放。超時(shí)時(shí)間設(shè)得越大,系統(tǒng)的性能就會(huì)越低,因此最好的方法就是盡量使得它的值保持在一個(gè)較低的水平。
方法 4: 將頁面輸出進(jìn)行壓縮
壓縮是解決數(shù)據(jù)冗余的一個(gè)好的方法,特別是在網(wǎng)絡(luò)帶寬不夠發(fā)達(dá)的今天。有的瀏覽器支持gzip(GNU zip)進(jìn)行來對(duì)HTML文件進(jìn)行壓縮,這種方法可以戲劇性地減少HTML文件的下載時(shí)間。因此,如果你將servlet或JSP頁面生成的HTML頁面進(jìn)行壓縮的話,那用戶就會(huì)覺得頁面瀏覽速度會(huì)非常快。但不幸的是,不是所有的瀏覽器都支持gzip壓縮,但你可以通過在你的程序中檢查客戶的瀏覽器是否支持它。下面就是關(guān)于這種方法實(shí)現(xiàn)的一個(gè)代碼片段:
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
<tr>
<td>public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
OutputStream out = null
String encoding = request.getHeader("Accept-Encoding");
if (encoding != null && encoding.indexOf("gzip") != -1)
{
request.setHeader("Content-Encoding" , "gzip");
out = new GZIPOutputStream(request.getOutputStream());
}
else if (encoding != null && encoding.indexOf("compress") != -1)
{
request.setHeader("Content-Encoding" , "compress");
out = new ZIPOutputStream(request.getOutputStream());
}
else
{
out = request.getOutputStream();
}
...
...
} </td></tr></table>
方法 5: 使用線程池
應(yīng)用服務(wù)器缺省地為每個(gè)不同的客戶端請(qǐng)求創(chuàng)建一個(gè)線程進(jìn)行處理,并為它們分派service()方法,當(dāng)service()方法調(diào)用完成后,與之相應(yīng)的線程也隨之撤消。由于創(chuàng)建和撤消線程會(huì)耗費(fèi)一定的系統(tǒng)資源,這種缺省模式降低了系統(tǒng)的性能。但所幸的是我們可以通過創(chuàng)建一個(gè)線程池來改變這種狀況。另外,我們還要為這個(gè)線程池設(shè)置一個(gè)最小線程數(shù)和一個(gè)最大線程數(shù)。在應(yīng)用服務(wù)器啟動(dòng)時(shí),它會(huì)創(chuàng)建數(shù)量等于最小線程數(shù)的一個(gè)線程池,當(dāng)客戶有請(qǐng)求時(shí),相應(yīng)地從池從取出一個(gè)線程來進(jìn)行處理,當(dāng)處理完成后,再將線程重新放入到池中。如果池中的線程不夠地話,系統(tǒng)會(huì)自動(dòng)地增加池中線程的數(shù)量,但總量不能超過最大線程數(shù)。通過使用線程池,當(dāng)客戶端請(qǐng)求急劇增加時(shí),系統(tǒng)的負(fù)載就會(huì)呈現(xiàn)的平滑的上升曲線,從而提高的系統(tǒng)的可伸縮性。
方法 6: 選擇正確的頁面包含機(jī)制
在JSP中有兩種方法可以用來包含另一個(gè)頁面:1、使用include指示符(<%@ includee file=”test.jsp” %>)。2、使用jsp指示符(<jsp:includee page=”test.jsp” flush=”true”/>)。在實(shí)際中我發(fā)現(xiàn),如果使用第一種方法的話,可以使得系統(tǒng)性能更高。
方法 7:正確地確定javabean的生命周期
JSP的一個(gè)強(qiáng)大的地方就是對(duì)javabean的支持。通過在JSP頁面中使用<jsp:useBean>標(biāo)簽,可以將javabean直接插入到一個(gè)JSP頁面中。它的使用方法如下:
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
<tr>
<td><jsp:useBean id="name" scope="page|request|session|application" class=
"package.className" type="typeName">
</jsp:useBean></td></tr></table>
其中scope屬性指出了這個(gè)bean的生命周期。缺省的生命周期為page。如果你沒有正確地選擇bean的生命周期的話,它將影響系統(tǒng)的性能。
舉例來說,如果你只想在一次請(qǐng)求中使用某個(gè)bean,但你卻將這個(gè)bean的生命周期設(shè)置成了session,那當(dāng)這次請(qǐng)求結(jié)束后,這個(gè)bean將仍然保留在內(nèi)存中,除非session超時(shí)或用戶關(guān)閉瀏覽器。這樣會(huì)耗費(fèi)一定的內(nèi)存,并無謂的增加了JVM垃圾收集器的工作量。因此為bean設(shè)置正確的生命周期,并在bean的使命結(jié)束后盡快地清理它們,會(huì)使用系統(tǒng)性能有一個(gè)提高。
其它一些有用的方法
· 在字符串連接操作中盡量不使用“+”操作符:在java編程中,我們常常使用“+”操作符來將幾個(gè)字符串連接起來,但你或許從來沒有想到過它居然會(huì)對(duì)系統(tǒng)性能造成影響吧?由于字符串是常量,因此JVM會(huì)產(chǎn)生一些臨時(shí)的對(duì)像。你使用的“+”越多,生成的臨時(shí)對(duì)像就越多,這樣也會(huì)給系統(tǒng)性能帶來一些影響。解決的方法是用StringBuffer對(duì)像來代替“+”操作符。
· 避免使用System.out.println()方法:由于System.out.println()是一種同步調(diào)用,即在調(diào)用它時(shí),磁盤I/O操作必須等待它的完成,因此我們要盡量避免對(duì)它的調(diào)用。但我們在調(diào)試程序時(shí)它又是一個(gè)必不可少的方便工具,為了解決這個(gè)矛盾,我建議你最好使用Log4j工具(http://jakarta.apache.org ),它既可以方便調(diào)試,而不會(huì)產(chǎn)生System.out.println()這樣的方法。
· ServletOutputStream 與 PrintWriter的權(quán)衡:使用PrintWriter可能會(huì)帶來一些小的開銷,因?yàn)樗鼘⑺械脑驾敵龆嫁D(zhuǎn)換為字符流來輸出,因此如果使用它來作為頁面輸出的話,系統(tǒng)要負(fù)擔(dān)一個(gè)轉(zhuǎn)換過程。而使用ServletOutputStream作為頁面輸出的話就不存在一個(gè)問題,但它是以二進(jìn)制進(jìn)行輸出的。因此在實(shí)際應(yīng)用中要權(quán)衡兩者的利弊。
總結(jié)
本文的目的是通過對(duì)servlet和JSP的一些調(diào)優(yōu)技術(shù)來極大地提高你的應(yīng)用程序的性能,并因此提升整個(gè)J2EE應(yīng)用的性能。通過這些調(diào)優(yōu)技術(shù),你可以發(fā)現(xiàn)其實(shí)并不是某種技術(shù)平臺(tái)(比如J2EE和.NET之爭)決定了你的應(yīng)用程序的性能,重要是你要對(duì)這種平臺(tái)有一個(gè)較為深入的了解,這樣你才能從根本上對(duì)自己的應(yīng)用程序做一個(gè)優(yōu)化!
posted @ 2009-07-23 09:55 追求無止境 閱讀(179) | 評(píng)論 (0) | 編輯 收藏 轉(zhuǎn)帖--每個(gè)人都該學(xué)會(huì)的50件事情
要過得健康充實(shí),還得靠自立。要學(xué)會(huì)自立,必須得掌握一些技巧。可能和你在學(xué)校里學(xué)到的不同,但全才遠(yuǎn)遠(yuǎn)要比專門只會(huì)一樣的人更能夠適應(yīng)生活。
這里是每個(gè)人都該學(xué)會(huì)的50件事情。(不完全統(tǒng)計(jì)) 1. 生火——火能產(chǎn)生光和熱。這兩件是生存的必需品。也許在某個(gè)時(shí)候,這項(xiàng)技能可以救你的命。 2. 操作電腦——基本的電腦常識(shí)是現(xiàn)代生活之必需。必要的時(shí)候,請(qǐng)幫助他人。 3。有效使用Google——Google無所不知。如果你用Google找不到你想找的東西,那就是你的問題了。 4。人工呼吸和處理喉嚨被塞住的急救措施——有一天你的妻子、丈夫、兒子或女兒,可能正是需要你幫助的那個(gè)人。 5。開手排檔的車——也許有時(shí)候你會(huì)需要這項(xiàng)技能,要是不會(huì)就糟了。 6。簡單地做飯——如果你連雞蛋或牛排都不會(huì)煎,那就麻煩了。 7。講一個(gè)能吸引人們注意力的故事——如果你不能吸引別人的注意力,那還是別廢話了。 8。不與人打架,除非你能贏——兩種情況下,你都贏了。 9。告訴別人壞消息——總得有人去做這件事。不幸的是,有一天這個(gè)重任也會(huì)落到你肩上。 10。換輪胎——輪胎里面有氣體,只要有氣體的東西總有一天會(huì)爆掉。 11。從容應(yīng)對(duì)面試——要是緊張得渾身是汗,你肯定得不到那份工作。 12。管理好自己的時(shí)間——否則你就是在浪費(fèi)時(shí)間。偶爾浪費(fèi)時(shí)間也沒關(guān)系,但不能一直這樣。 13。快速閱讀——很多時(shí)候你只要讀要點(diǎn)就可以了。(看到這里就覺得沒早點(diǎn)學(xué)會(huì)這條了吧) 14。記住名字——你會(huì)喜歡別人管你叫“喂,那個(gè)誰。。。”嗎? 15。整理房間——真正做起來總比想象的要難一點(diǎn)。 16。輕裝上陣——旅行時(shí)只帶最必需的東西。這樣更便宜、更簡單、更靈活。 17。和警察打交道——蹲監(jiān)獄可不是好玩的,監(jiān)獄里面的大漢就更不用說了。 18。給別人指路——沒人喜歡迷路,所以最好第一次就指對(duì)。 19。進(jìn)行基本的急救——會(huì)正確處理傷口,不是只有醫(yī)生或天才才能做到的。 20。游泳——地球表面71%的地方都是水,所以學(xué)會(huì)游泳絕對(duì)是個(gè)好主意。 21。路邊停車——大多數(shù)標(biāo)準(zhǔn)駕照考試都要求考路邊停車,然而大多數(shù)人還是不知道該怎么做。很奇怪啊。 22。了解自己的酒量——不然你一不小心就會(huì)很難看。 23。選擇好的產(chǎn)品——腐壞的水果和蔬菜只能成為惡作劇的道具用來嚇人。 24。會(huì)用錘子、斧子和手鋸——不是只有木匠才用得著這些工具的。每個(gè)人都得有點(diǎn)使用這些工具的基本常識(shí)。 25。進(jìn)行簡單的財(cái)務(wù)規(guī)劃——負(fù)債累累可不好,一個(gè)簡單地預(yù)算計(jì)劃可以幫你解決這些問題。 26.至少會(huì)說兩種通用的語言——世界上只有25%的人說英語。如果能跟剩下75%的人溝通也挺好的。 27.正確地做俯臥撐和仰臥起坐——姿勢不正確的話只會(huì)傷害身體,也是浪費(fèi)時(shí)間。 28.多贊美別人——贊美是世上最好的禮物之一,更何況是免費(fèi)的。 29.談判——再多問一兩個(gè)問題就會(huì)得到更好的價(jià)錢。 30.仔細(xì)聽別人說話——多聽少講,學(xué)到的多,失去的少。 31.復(fù)習(xí)基本的地理知識(shí)——如果你不知道你生活圈以外的環(huán)境,大部分的人只會(huì)認(rèn)為你什么都不知道(而且通常他們是對(duì)的)。 32.粉刷房間——粉刷房間的價(jià)格百分之九十是人工費(fèi)用,簡單的油漆活自己做比付給別人9倍的工資要來得劃算。 33.簡單明了又內(nèi)容豐富的演說——如果下次公司開會(huì)時(shí)你的上司要你解釋你上個(gè)月做了什么活,這樣的演講能讓你過關(guān)。“嗯。。。不知道”的話就慘了。 34.照相的時(shí)候微笑——硬是不笑的人最糟了! 35.不出丑的搭訕——搭訕成功跟失敗只是一念之間。如果太刻意的話會(huì)失敗,不夠用心的話也會(huì)失敗。 36.做有用的筆記——因?yàn)闆]用的筆記和不做筆記一樣都是沒用的。 37.禮待住在自己家里的客人——要不然的話哪天你需要借住他們家的時(shí)候就只能睡旅館了。 38.給人好的第一次印象——亞里士多德曾經(jīng)說過,“好的開始是成功的一半。” 39.會(huì)看地圖和使用指南針——如果你的衛(wèi)星導(dǎo)航器在一個(gè)鳥不生蛋的地方壞了,你要怎么辦? 40.縫鈕扣——比買新衣便宜。 41.自己裝家里的視聽系統(tǒng)——又不是多難,付錢給別人裝只是因?yàn)橥祽小? 42.打字——打字打得好的話會(huì)節(jié)省很多時(shí)間,一生受用。 43.保護(hù)私人資料——除非你是那個(gè)小偷,不然個(gè)人資料被偷可不是好玩的。 44.設(shè)定基本的電腦系統(tǒng)防護(hù)措施——設(shè)定密碼跟防火墻并不需要計(jì)算機(jī)本科畢業(yè),但可以預(yù)防將來倒大霉。 45。識(shí)別謊言——人們會(huì)對(duì)你說謊,此乃人生之一大不幸。 46。有禮貌地結(jié)束約會(huì),而不承諾下一次——千萬別給別人一個(gè)你不愿給的承諾。你也不用急著決定和一個(gè)剛認(rèn)識(shí)沒多久的人有什么未來。 47。除去污漬——總比再買一件便宜。 48。保持房間整潔——整潔的房間是健康、規(guī)律生活的開始。 49。正確地抱嬰兒——你可不想無意弄傷一個(gè)小寶寶。 50。啟動(dòng)汽車電瓶——這總比走路或叫拖車好得多。 風(fēng)雨雷電---MP3MP4專賣; posted @ 2008-10-04 14:16 追求無止境 閱讀(104) | 評(píng)論 (0) | 編輯 收藏 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||