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 處理表單