• Spring 实战-第五章-构建Spring Web应用程序


    SpringWeb应用程序,这里指的的是Spring MVC框架,包括了控制器,对象,视图解析,渲染等功能。

    ref:http://blog.csdn.net/zuoluoboy/article/details/19766131 

    MVC结构图如上,其中DispacherServlet是整个系统的核心,用于分配、调用各个模块。

    流程上,请求到服务器,DispatcherServlet查询处理映射器(handler mapping),确定需要使用哪个Controller,当Controller接收到请求后,会将数据打包和需要使用的视图名称,

    返回到DispatcherServlet,DispatcherServlet会根据视图名称,找到对应的机图解析器(view resolver),视图解析器会根据数据和视图进行渲染,然后返回。

    按照传统方式,需要增加很多xml配置,java based配置方式相对更简单明了。

    配置DispatcherServlet

    package spittr.config;
    
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    import spittr.web.WebConfig;
    
    /**
     * Created by jwlv on 2017/10/27.
     */
    public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        //for "root" application context (non-web infrastructure) configuration.
        //返回的带有@Configuration注解的类将会用来配置ContextLoaderListener创建的应用上下文中的Bean
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[]{RootConfig.class};
        }
    
        // for DispatcherServlet application context (Spring MVC infrastructure) configuration.
        //返回的带有@Configuration注解的类将会用来定义DispatcherServlet应用上下文中的Bean
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[]{WebConfig.class};
        }
    
        //将一个或多个路径映射到DispatcherServlet上
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }

    当DispatcherServlet启动的时候,会创建Spring应用上下文,并加载配置文件或配置类中所声明的bean。

    配置WebConfig

    package spittr.web;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.ViewResolver;
    import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
    /**
     * Created by jwlv on 2017/10/27.
     */
    @Configuration
    @EnableWebMvc
    @ComponentScan("spittr.web")
    public class WebConfig extends WebMvcConfigurerAdapter{
    
        @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();
        }
    
    //    @Autowired
    //    private AnnotationConfigWebApplicationContext applicationContext;
    }

    @EnableWebMvc用来启用注解驱动的SpringMVC,如果是通过xml配置,需要xml中增加<mvc:annotation-driven>,这两个是等效的

    于此同时,这还启用了其他特性,包括

    1. Spring 3 style type conversion through a ConversionService instance in addition to the JavaBeans PropertyEditors used for Data Binding.

    2. Support for formatting Number fields using the @NumberFormat annotation through the ConversionService.

    3. Support for formatting Date, Calendar, Long, and Joda Time fields using the @DateTimeFormat annotation.

    4. Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is present on the classpath.

    5. HttpMessageConverter support for @RequestBody method parameters and @ResponseBody method return values from @RequestMapping or@ExceptionHandler methods.

    ref:https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-config-enable

    viewResolver()方法会用来解析视图地址,根据controller返回的视图名称,和这里配置的前缀后缀,会找到对应的视图。

    比如controller返回了“homepage”,根据这里的配置,找到的地址是~/WEB-INF/views/homepage.jsp。

    定义控制器

    package spittr.web;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import static org.springframework.web.bind.annotation.RequestMethod.GET;
    
    /**
     * Created by jwlv on 2017/10/27.
     */
    @Controller
    @RequestMapping({"/home","/testhome"})
    public class HomeController {
        @RequestMapping(method=GET)
        public  String home(){
            return "home";
        }
    
        @RequestMapping(value="/homepage", method=GET)
        public  String home2(){
            return "home";
        }
    
    }

    Controller的Mapping

    handler mapping会根据请求的地址,结合controller上的RequestMapping,找到合适的controller,RequestMapping注解可以用于类和方法,可以灵活组合,method参数表示了请求的类型

    如上controller,可以对应如下地址

    类级别:http://localhost:8080/home,http://localhost:8080/testhome

    方法级别:http://localhost:8080/homepage

    类和方法组合:http://localhost:8080/home/homepage,http://localhost:8080/testhome/homepage

    Controller的传值

    请求传入到Controller,可以查询参数、路径参数、对象等方式实现

    //通过查询参数传入
    @RequestMapping(method=RequestMethod.GET)
    public List<Spittle> spittles(
            @RequestParam(value="max",defaultValue = "9999") long max,
            @RequestParam(value="count",defaultValue = "20") int count) {
        return spittleRepository.findSpittles(max,count);
    }
    
    //通过路径参数传入
    @RequestMapping(value="/{spittleId}",method=RequestMethod.GET)
    public String findOne(
            @PathVariable("spittleId") long spittleId,
            Model model){
        model.addAttribute("spittle",spittleRepository.findOne(spittleId));
        return "spittle";
    }
    
    //通过对象Post表单传入
    @RequestMapping(value="/register",method = POST)
    public String processRegistration(
            @Valid Spitter spitter,
            Errors errors){
        if(errors.hasErrors()){
            return "registerForm";
        }
        spitterRepository.save(spitter);
        return "redirect:/spitter/"+ spitterRepository.findByUsername("").getUsername();
    }

    Controller传入到View,可以通过Model、Map、对象或集合,本质是传KeyValue

    //调用addAttribute()方法并且不指定key的时候,key会根据值的对象类型判断,
    //此处因为是一个List<Spittle>,故键将会推断为spittleList
    @RequestMapping(method = RequestMethod.GET)
    public String spittles(Model model){
        model.addAttribute(
                spittleRepository.findSpittles(Long.MAX_VALUE,20));
        return "spittles";
    }
    
    //显示指定key
    @RequestMapping(method = RequestMethod.GET)
    public String spittles(Model model){
        model.addAttribute("spittleList",
                spittleRepository.findSpittles(Long.MAX_VALUE,20));
        return "spittles";
    }
    
    //使用Map作为入参
    @RequestMapping(method = RequestMethod.GET)
    public String spittles(Map model) {
        model.put("spittleList",
                spittleRepository.findSpittles(Long.MAX_VALUE,20));
        return "spittles";
    }
    
    //当处理器方法返回对象或集合时,这个值会放到模型中,模型的key会根据其类型推断得出。此处为spittleList
    //逻辑视图的名称将会根据请求路径推断得出。因为这个方法处理针对“/spittles”的GET请求,
    //因此视图的名称将会是spittles(去掉开头的斜线)
    @RequestMapping(method = RequestMethod.GET)
    public List<Spittle> spittles(Model model) {
        return spittleRepository.findSpittles(Long.MAX_VALUE,20);
    }

    校验表单

    Spring3.0开始,Spring MVC中提供了对Java校验API的支持(Java Validation API,又称JSR-303),当启用注解驱动时,不需要额外的配置,只要保证在类路径下包含这个API的实现即可,比如Hibernate Validator。

    package spittr;
    
    import org.apache.commons.lang3.builder.EqualsBuilder;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Size;
    
    /**
     * Created by jwlv on 2017/11/7.
     */
    public class Spitter {
        private Long id;
    
        @NotNull
        @Size(min = 5,max = 16)
        private String username;
    
        @NotNull
        @Size(min = 5,max = 25)
        private String password;
    
        @NotNull
        @Size(min = 2,max = 30)
        private String firstName;
    
        @NotNull
        @Size(min = 2,max = 30)
        private String lastName;
        
        ...    
    }

    同时在Controller中使用@Valid注解,Errors对象要紧跟在有@Valid注解的参数后面,使用的时候,如果有不符合格式的传入,errors.hasErrors()会返回true。

    @RequestMapping(value="/register",method = POST)
        public String processRegistration(
                @Valid Spitter spitter,
                Errors errors){
            if(errors.hasErrors()){
                return "registerForm";
            }
            spitterRepository.save(spitter);
            //return "redirect:/spitter/"+ spitter.getUsername();
            return "redirect:/spitter/"+ spitterRepository.findByUsername("").getUsername();
        }

    code:https://github.com/ljw8947/SpringInAction/tree/master/Capter5/Spittr

    参考:

    https://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html

    http://benweizhu.github.io/blog/2014/07/19/spring-validation-by-example/

  • 相关阅读:
    Mongodb介绍(非原创)
    软件架构设计常用方法-软件架构设计学习第五天(非原创) 发布成功,点击查看文章
    浅谈Javascript中的原型、原型链、继承
    GitHub当作私密的版本控制系统远端版本库私有化
    TortoiseGit 绑定 GitHub/Gitee ssh秘钥
    一次停电引发服务器硬件故障
    sed往指定位置插入变量的小技巧
    SQL server 2008 R2 安装步骤
    Sublime Text提示Unable to download XXX. Please view the console for more details安装插件失败解决
    Sublime Text3配置Lua运行环境
  • 原文地址:https://www.cnblogs.com/lvjianwei/p/7815219.html
Copyright © 2020-2023  润新知