初探Spring MVC

背景

Spring MVC能对Web应用松耦合(loose coupling),基于模型-视图-控制器(Model-View-Controller, MVC)模式实现,使用新的Spring MVC注解来构建处理Web请求、参数和表单输入的控制器。

请求过程

这里写图片描述

搭建Spring MVC环境

DispatcherServlet is the centerpiece of Spring MVC. It’s where the request first hits the framework, and it’s responsible for routing the request through all the other components.
一种方式是DispatcherServlet 会配置在项目WAR包里的xml文件中;另一种方式是将DispatcherServlet 配置在Servlet Container中。

public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[] { RootConfig.class };
  }

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

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

}

扩展AbstractAnnotationConfigDispatcherServletInitializer的任意类都会自动配置DispatcherServlet 和Spring Application Context,Spring的应用上下文会位于应用程序的Servlet上下文中。
在Servlet 3.0 环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer 接口的类来配置Servlet容器,Spring提供了该接口名为SpringServletContainerInitializer 的实现,它根据@HandlesTypes(WebApplicationInitializer.class) 注解来反查实现WebApplicationInitializer 接口的类。因此当部署到Servlet 3.0 container,容器会自动发现它来配置Servlet上下文。
Under the covers, AbstractAnnotationConfigDispatcherServletInitializer creates both a DispatcherServlet and a ContextLoaderListener . The @Configuration classes returned from getServletConfigClasses() will define beans for DispatcherServlet ’s application context. Meanwhile, the @Configuration class’s returned getRootConfigClasses() will be used to configure the application context created by ContextLoaderListener .

启用Spring MVC

配置完DispatcherServlet 需要启用Spring MVC组件才能起作用。XML:<mvc:annotation-driven> ;JavaConfig:@EnableWebMvc

DispatcherServlet会加载包Web组件的bean,如控制器、视图解析以及处理器映射,如这里的WebConfig 。ContextLoaderListener会加载驱动应用后端的中间层和数据层组件的bean,如这里的RootConfig

WebConfig
@Configuration
@EnableWebMvc   //启用Spring MVC
@ComponentScan("spittr.web")    //启用组件扫描
public class WebConfig extends WebMvcConfigurerAdapter {

  @Bean
  public ViewResolver viewResolver() {
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    return resolver;    //配置JSP视图解析器
  }

  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();    //配置处理静态资源
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    super.addResourceHandlers(registry);
  }

}
RootConfig
@Configuration
@Import(DataConfig.class)
@ComponentScan(basePackages={"spittr"}, 
    excludeFilters={
        @Filter(type=FilterType.CUSTOM, value=WebPackage.class)
    })
public class RootConfig {
  public static class WebPackage extends RegexPatternTypeFilter{
    public WebPackage() {
      super(Pattern.compile("spittr\\.web"));
    }    
  }
}

控制器(Controller)

现在可以使用Spring MVC来构建Web应用了。
Spring MVC 允许以多种方式将客户端中的数据传送到控制器的处理器方法中:

  1. 查询参数(Query Parameter) e.g. domain/Resource?max=10:count=5
  2. 表单参数(Form Parameter)
  3. 路径变量(Path Variable) e.g. domain/111111
@Controller
@RequestMapping("/spittles")
public class SpittleController {
//当返回对象或集合是,值会放在模型Model里,Model key会根据类型推断出。而逻辑视图(Logic View)会根据请求路径(Request Path)推断出。
  @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) {//查询参数(Query Parameter)
    return spittleRepository.findSpittles(max, count);
  }
  //当调用` addAttribute()` 并不指定key时,key会根据指的对象类型(Object Type)推断确定。
  //路径变量(Path Variable),如果@PathVariable中没有value属性,它会假设占位符的名称与方法的参数名称相同。
  @RequestMapping(value="/{spittleId}", method=RequestMethod.GET)
  public String spittle(
      @PathVariable("spittleId") long spittleId, 
      Model model) {
    model.addAttribute(spittleRepository.findOne(spittleId));
    return "spittle";
  }

  @RequestMapping(method=RequestMethod.POST)
  public String saveSpittle(SpittleForm form, Model model) throws Exception {
    spittleRepository.save(new Spittle(null, form.getMessage(), new Date(), 
        form.getLongitude(), form.getLatitude()));
    return "redirect:/spittles";//防止重复提交,故将浏览器重定向
  }
}

Model实际上就是一个Map(Key-Value),它会传递给视图,这样数据就能渲染到客户端了。使用非Spring类型的话,可以用java.util.Map 来代替Model。
在构建面向资源的控制器时,把参数作为请求路径得一部分,即路径参数要优于查询参数。
当InternalResourceViewResolver看到视图格式中的“redirect:”或“forward:”前缀时,会重定向或前往到指定URL地址,而不是解析成视图的名称。

Form Validation

从Spring 3.0开始,SpringMVC支持了Java校验API(Java Validation API, 又称JSR-303)。

  public String processRegistration(
      @Valid Spitter spitter, 
      Errors errors) {
    if (errors.hasErrors()) {
      return "registerForm";
    }
  }

在相应的参数上添加@Valid 注解,Spring会捕获到,确保这个对象满足校验限制。如果校验出现错误,可以通过Errors对象进行访问。Errors参数要紧跟在带有@Valid注解参数的后面。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值