1. 程式人生 > >Spring實戰4 第5章 構建Spring Web應用程式

Spring實戰4 第5章 構建Spring Web應用程式

一,構建Spring Web應用程式##

1,Spring MVC起步

1.1跟蹤Spring Mvc請求
請求資訊路徑圖
在請求離開瀏覽器是,帶有使用者請求的內容資訊
第一站是Spring的DispatcherServlet,在Spring MVC中,它就是前端控制器。它的任務是將請求傳送給Spring MVC控制器。控制器是一個用於處理請求的Spring元件。DispatcherServlet需要知道將請求傳送給哪個控制器。所以DispatcherServlet會查詢一個或多個處理器對映。
一旦選擇了合適的控制器,DispatcherServlet會將請求傳送給選中的控制器,到了控制器,請求就會卸下負載,耐心等待控制器處理資訊。
控制器邏輯處理後產生的資訊稱為模型(model).這些資訊會發送給一個檢視,通常是jsp.
控制器做的最後一件事情就是將模型資料打包,標識出檢視名,然後加上請求一塊返回DispatcherServlet.
返回給DispatcherServlet的檢視名僅僅傳遞了一個邏輯名稱。DispatcherServlet會使用檢視解析器來匹配具體的檢視實現。然後檢視使用模型資料渲染輸出,最後輸出通過響應物件傳遞給客戶端。

1.2搭建Spring Mvc
首先配置DispatcherServlet,我們會使用java將DispatcherServlet配置在Servlet容器中。
如下為程式清單

public class SpittrWebAppInitializer  
        extends AbstractAnnotationConfigDispatcherServletInitializer {  
    @Override  
    protected Class<?>[] getRootConfigClasses() { //根容器  
        return new Class<?>[] { RootConfig.class };  
    }  

    @Override  
    protected Class<?>[] getServletConfigClasses() { //Spring mvc容器  
        return new Class<?>[] { WebConfig.class };  
    }  

    @Override  
    protected String[] getServletMappings() { //DispatcherServlet對映,從"/"開始  
        return new String[] { "/" };  
    }  
} 

擴充套件AbstractAnnotationConfigDispatcherServletInitializer的任意類都會自動的配置 DispatcherServlet和Spring應用上下文,Spring應用上下文會位於應用程式的上下文中。
第一個方法getServletMappings(),它會將一個或多個路徑對映到DispatcherServlet。"/"表示會是應用預設Servlet.它會處理進入應用的所有請求。
兩個應用上下文
getServletConfigClasses()方法要求DispatcherServlet載入應用上下文時,使用定義在WebConfig配置類中的bean.
Spring web應用中還會有另外一個應用上下文,它是由ContextLoaderListener建立的。
DispatcherServlet載入包含Web元件的bean,如控制器,檢視解析器,處理器對映。而ContextLoaderListener載入應用中的其他bean,這些bean通常是驅動應用的中間層和資料層元件。實際上,AbstractAnnotationConfigDispatcherServletInitializer會同時建立
DispatcherServlet和ContextLoaderListener。
最小但可用的Spring Mvc配置


Webconfig

@Configuration
@EnableWebMvc //啟用Spring MVC
@ComponentScan("spitter.web") //啟用元件掃描
public class WebConfig extends WebMvcConfigurerAdapter {

    // 配置一個JSP檢視解析器
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB_INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

//配置靜態資源處理
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

RootConfig

@Configuration
@ComponentScan(basePackages = { "spitter" }, excludeFilters = {
        @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })
public class RootConfig {

}

2,編寫基本控制器
在Spring Mvc中,控制器上添加了@RequetMapping註解,它聲明瞭要處理的請求。如下為最簡單的控制器。(不擴充套件了。。)

@Controller
public class StuController {

    @RequestMapping(value="/",method = GET)
    public String home(){
        return "home";
    }
}

2.1 測試控制器

public class HomeControllerTest {
    @Test
    public void testHomePage() throws Exception {
        HomeController controller =  new HomeController();
        //搭建MockMvc 
        MockMvc mockMvc = standaloneSetup(controller).build();
        //執行GET請求,得到預期的檢視
        mockMvc.perform(get("/")).andExpect(view().name("home"))
    }
}

2.2 傳遞模型資料到檢視中

@Controller  
@RequestMapping("/spittles")  //定義類級別的請求
public class SpittleController { 
    @Autowired   
    private SpittleRepository spittleRepository;  

    @RequestMapping(method = RequestMethod.GET)  
    public String spittles(Model model) {  
        model.addAttribute(  
                spittleRepository.findSpittles(Long.MAX_VALUE, 20));  
        return "spittles";  
    }  

3 接受請求的輸入
Spring Mvc允許以多種方式將客戶端中的資料傳送到控制器的處理器方法中
1,查詢引數 2,表單引數 3,路徑變數

3.1 處理查詢引數

/**
     * 客戶端給控制器的handler以查詢引數方式傳入引數
     */
    @RequestMapping(method = RequestMethod.GET)  
    public List<Spittle> spittles(  
            @RequestParam(value = "max", defaultValue = MAX_LONG_AS_STRING) long max,  
            @RequestParam(value = "count", defaultValue = "20") int count) {  
        return spittleRepository.findSpittles(max, count);  
    }  

3.2通過路徑引數接受輸入

/**
     * 客戶端給控制器的handler以路徑引數方式傳入引數,@PathVariable註解的引數
     * 應該和@RequestMapping註解中的佔位符名稱完全相同;
     * 如果函式引數也和佔位符名稱相同,則可以省略@PathVariable註解的引數
     */
    @RequestMapping(value = "/{spittleId}", method = RequestMethod.GET)  
    public String showSpittle(  
            @PathVariable("spittleId") long spittleId,  
            Model model) {  
        model.addAttribute(spittleRepository.findOne(spittleId));  
        return "spittle";  
    }

3.3 處理表單