歡迎光臨
每天分享高質量文章

Java Web技術經驗總結(九)

1. ParameterizableViewController類

有時我們需要定義ParameterizableViewController一個類,由這個類負責快速將請求匯入到另一個檢視。,這個標簽是對應的簡稱。如下是一個Java配置,會將”/”的請求引導到名叫”home”的檢視:

  1. @Configuration

  2. @EnableWebMvc

  3. public class WebConfig extends WebMvcConfigurerAdapter {

  4.      @Override

  5.     public void addViewControllers(ViewControllerRegistry registry) {

  6.         registry.addViewController("/").setViewName("home");

  7.     }

  8.  }

跟這個程式碼對應的XML配置程式碼如下:

  1. path="/" view-name="home"/>

2. mvc:default-servlet-handler

通常我們使用DispatchServlet處理”/”開頭的URL(改寫了Tomcat容器的預設Servlet),透過定義這預設的servlet-handler,可以在使用DispatchServlet的同時,允許容器的預設Servlet處理靜態資源請求。這個標簽配置了一個DefaultServletHttpRequestHandler,用於處理”/*”之類的URL,不過相對於其他的URL匹配樣式來說具有較低的優先順序。
這個handler將會把所有請求引導到預設的Servlet,因此,我們配置時,要讓預設handler在所有的URL處理器對映中位於最低優先順序;尤其是當你在使用或者你設定了自定義的處理器對映時,最低優先順序的值是
Integer.MAX_VALUE*。透過Java Config程式碼啟用default-servlet-handler:

  1. @Configuration

  2. @EnableWebMvc

  3. public class WebConfig extends WebMvcConfigurerAdapter {

  4.      @Override

  5.      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

  6.         configurer.enable();

  7.     }

  8.  }

同樣的功能可使用如下XML程式碼實現:

3. mvc:interceptors

在請求由DispatchServlet傳遞到具體的業務邏輯控制器之前,Spring MVC還提供了攔截器、過濾器等機制用於對請求進行預處理和post處理。可以針對所有的請求或者指定URL匹配樣式的請求進行攔截,如下是一個Java Config程式碼:

  1. @Configuration

  2. @EnableWebMvc

  3. public class WebConfig extends WebMvcConfigurerAdapter {

  4.     @Override

  5.    public void addInterceptors(InterceptorRegistry registry) {

  6.         registry.addInterceptor(new LocaleInterceptor());

  7.         registry.addInterceptor(new ThemeInterceptor()).addPathPatterns("/**").excludePathPatterns("/admin/**");

  8.         registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/secure/*");

  9.     }

  10.  }

對應的XML配置程式碼如下:

  1.     class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>

  2.    

  3.         path="/**"/>

  4.         path="/admin/**"/>

  5.         class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>

  6.    

  •    

  •         path="/secure/*"/>

  •         class="org.example.SecurityInterceptor"/>

  •    

  • 這個配置的含義有二:(1)對於所有符合”/“樣式的請求(除”/admin/“之外)要應用ThemeChangeInterceptor攔截器;(2)對於所有符合”/secure/*”樣式的請求,都要應用SecurityInterceptor攔截器。

    4. 根據使用者填寫的生日,自動計算出星座。

    1. public class ConstellationBuilder {

    2.    public static String getAstro(int month, int day) {

    3.        String[] starArr = {"魔羯座", "水瓶座", "雙魚座", "牡羊座", "金牛座", "雙子座", "巨蟹座", "獅子座",

    4.                "處女座", "天秤座", "天蠍座", "射手座"};

    5.        int[] DayArr = {22, 20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22};  //兩個星座分割日

    6.        int index = month;        // 所查詢日期在分割日之前,索引-1,否則不變

    7.        if (day < DayArr[month - 1]) {

    8.            index = index - 1;

    9.        }

    10.        return starArr[index];

    11.    }

    12. }

    對應的測試程式碼如下,註意Joda Time包的使用,不過如果你使用Java 8的話,可以直接使用Java 8提供的日期介面。

    1. public class ConstellationBuilderTest {

    2.    @Test

    3.    public void getAstro() throws Exception {

    4.        Calendar calendar = Calendar.getInstance();

    5.        calendar.set(1988, Calendar.OCTOBER, 16);

    6.        LocalDateTime localDateTime = LocalDateTime.fromDateFields(calendar.getTime());

    7.        String res = ConstellationBuilder.getAstro(localDateTime.getMonthOfYear(), localDateTime.getDayOfMonth());

    8.        Assert.assertEquals("天秤座", res);

    9.    }

    10. }

    5. 在Mybatis中,使用陳述句INSERT … ON DUPLICATE KEY UPDATE的語法。

    1. id="insertOrUpdate" parameterType="userBean">

    2.    

    3.    INSERT INTO

    4.      user

    5.      (id, name, sex, birthday, constellation, work, province, city, district, mobile, integral, ctime, mtime)

    6.    VALUES     (#{id}, #{name}, #{sex}, #{birthday}, #{constellation}, #{work}, #{province}, #{city}, #{district},

    7.      #{mobile}, #{integral}, now(), now())

    8.    ON DUPLICATE KEY

    9.     UPDATE

    10.          name=VALUES(name),

    11.          sex=VALUES(sex),

    12.          birthday=VALUES(birthday),

    13.          constellation=VALUES(constellation),

    14.          work=VALUES(work),

    15.          province=VALUES(province),

    16.          city=VALUES(city),

    17.          district=VALUES(district),

    18.          mobile=VALUES(mobile),

    19.          integral=VALUES(integral),

    20.          mtime=now()

    21.    ]]>

    MySQL的官方檔案,要找個時間認真閱讀,有問題的時候,也可以直接翻閱官方檔案,而不是漫無目的得Google。根據官方檔案-insert-on-duplicate中提到:

    You can use the VALUES(colname) function in the UPDATE clause to refer to column values from the INSERT portion of the INSERT … ON DUPLICATE KEY UPDATE statement. In other words, VALUES(colname) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts. The VALUES() function is meaningful only in INSERT … UPDATE statements and returns NULL otherwise.
    重點:VALUES函式用於提取對應的列值,如果沒有則傳回NULL;

    6. Spring Boot + Thymeleaf + BootStrap結合使用的一個例子

    Spring MVC with Bootstrap and Thymeleaf

    7. 對於JVM中垃圾回收演演算法的分類

    我目前為止看到的最清晰的一篇文章:JVM調優總結(三):(1)按照基本策略——取用計數、標記清除、複製、標記整理;(2)按照分割槽對待的方式區分——增量升級、分代蒐集;(3)按照系統執行緒劃分——序列蒐集、並行蒐集、併發蒐集。

    8. JVM調優文章

    閱讀文章JVM調優(四),JVM中垃圾回收,面臨的問題可以總結為如下三類:

    • 如何識別垃圾物件?(1)取用計數;(2)Root Objects物件樹

    • 如何處理記憶體碎片問題?(1)複製;(2)標記-整理

    • 如何處理“物件建立”和“物件回收”這兩個相反的動作?(1)序列;(2)並行;(3)併發

    9. JDK中單例樣式的經典應用是?

    答:Runtime類,如下是我在JDK 1.8中查到的Runtime類的主要程式碼,可以看出,它是透過建構式私有化實現的單例樣式。參考JDK設計樣式應用——單例樣式(Singleton)。

    1. public class Runtime {

    2.    private static Runtime currentRuntime = new Runtime();

    3.    /**

    4.     * Returns the runtime object associated with the current Java application.

    5.     * Most of the methods of class Runtime are instance

    6.     * methods and must be invoked with respect to the current runtime object.

    7.     *

    8.     * @return  the Runtime object associated with the current

    9.     *          Java application.

    10.     */

    11.    public static Runtime getRuntime() {

    12.        return currentRuntime;

    13.    }

    14.    /** Don't let anyone else instantiate this class */

    15.    private Runtime() {}

    16. }

    原有的舊方法,在反序列號方面會有問題,需要我們重寫方法,在Java 1.7之後,實現單利樣式的最佳實踐是利用列舉(列舉型別天然支援序列化)。參考StackOverflow:Implementing Singleton with an Enum (in Java)

    1. // Enum singleton - the preferred approach

    2. public enum Elvis {

    3.       INSTANCE;

    4.       public void leaveTheBuilding() { ... }

    5. }

    贊(0)

    分享創造快樂