一,构建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 处理表单