美文网首页Java进阶之路Spring
第2部分 Web中的Spring

第2部分 Web中的Spring

作者: elijah777 | 来源:发表于2019-04-15 14:57 被阅读2次

    第2部分 Web中的Spring

    第5章 构建Spring Web应用

    5.1.2 搭建Spring MVC

    配置DispatcherServlet

    按照传统的方式,像DispatcherServlet这样的Servlet会配置在web.xml文件中,这个文件
    会放到应用的WAR包里面

    DispatcherServlet和Servlet监听器(也就是ContextLoaderListener)的关系

    启用Spring MVC

    多种方式来配置DispatcherServlet,与之类似,启用Spring MVC组件的方法也不
    仅一种。

    Spring是使用XML进行配置的,使用 <mvc:annotation-driven >启用注解驱动的Spring MVC。

    最简单的Spring MVC配置就是一个带有@EnableWebMvc注解的类:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    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;
    
    /**
     * @Auther: shuaihu.shen@hand-china.com
     * @Date: 2018/12/4 09:13
     * @Description:
     */
    @Configuration
    @EnableWebMvc     // 启用mvc
    @ComponentScan("com.web.spittr")  // 启用组件扫描
    public class Webconfig extends WebMvcConfigurerAdapter {
    
        /**
         * 配置JSP视图解析器
         * @return 视图
         */
        @Bean
        public ViewResolver viewResolver(){
            InternalResourceViewResolver resolver = new InternalResourceViewResolver();
            resolver.setPrefix("/WEB-INF/views/");
            resolver.setSuffix(".jsp");
            resolver.setExposeContextBeansAsAttributes(true);
            return resolver;
        }
        
        /**
         * 将对静态资源的请求转发到Servlet容器中默认的Servlet上
         */
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
            configurer.enable();
        }
        
    }
       
    

    需要配置视图解析器和启用组件扫描,对静态资源的处理

    注意

    WebConfig现在添加了@Component-Scan注解,因此将会扫描spitter.web包来查找组件。稍后你就会看到,我们所编写的控制器将会带有@Controller注解,这会使其成为组件扫描时的候选bean。因此,我们不需要在配置类中显式声明任何的控制器。

    添加了一个ViewResolver bean。更具体来讲,是Internal-ResourceViewResolver。我们只需要知道它会查找JSP文件,在查找的时候,它会在视图名称上加一个特定的前缀和后缀(例如,名为home的视图将会解析为/WEB-INF/views/home.jsp)。

    最后,新的WebConfig类还扩展了WebMvcConfigurerAdapter并重写了其configureDefaultServletHandling()方法。通过调用DefaultServlet-HandlerConfigurer的enable()方法,我们要求DispatcherServlet将对静态资源的
    请求转发到Servlet容器中默认的Servlet上,而不是使用DispatcherServlet本身来处理此类请求。

    5.2 编写基本的控制器

    在Spring MVC中,控制器只是方法上添加了@RequestMapping注解的类,这个注解声明了它们所要处理的请求。
    开始的时候,我们尽可能简单,假设控制器类要处理对“/”的请求,并渲染应用的首页

    /**
     * @Auther: shuaihu.shen@hand-china.com
     * @Date: 2018/12/13 08:59
     * @Description:  超级简单的控制器
     */
    @Controller
    public class HomeController {
    
        @RequestMapping(value = "/", method = GET)
        public String home(){
            return "home";
        }
    }
    

    此时此刻运行一下项目便可以成功了。

    程序清单:

    1. SpittrWebAppInitializer.java 核心配置文件 可以替代web.xml
    2. Webconfig.java 视图解析器 启用组件扫描 静态文件处理 类似于dispatcherservlet
    3. RootConfig.java 非核心补充文件
    4. HomeController.java 简单控制器
    5. home.jsp 访问页

    测试:

    import org.junit.Test;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import static org.junit.Assert.*;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
    
    public class HomeControllerTest {
    
        @Test
        public void testHomePage() throws Exception {
            HomeController homeController = new HomeController();
            // 搭建MockMvc
            MockMvc mockMvc = MockMvcBuilders.standaloneSetup(homeController).build();
            // 对 "/" 执行GET请求   预期得到home视图
            mockMvc.perform(get("/")).andExpect(view().name("home"));
            assertEquals("home", homeController.home());
        }
    }
    

    发起了对“/”的GET请求,并断言结果视图的名称为home。

    它首先传递一个HomeController实例
    到MockMvcBuilders.standaloneSetup()并调用build()来构建MockMvc实例。然后它使用MockMvc实例来执行针对“/”的GET请求并设置期望得到的视图名称

    基础知识补充:

    final变量在使用前需要初始化,static final修饰的变量在定义的时候进行初始化。

    直接复制或者在构造参数中复制

    5.3 接受请求的

    参数传递

    这个处理器方法将会处理形如“/spittles/show?spittle_id=12345”这样的请求。尽管这也可以正
    常工作,但是从面向资源的角度来看这并不理想。在理想情况下,要识别的资源(Spittle)应
    <u>该通过URL路径进行标示,而不是通过查询参数。</u><u>对“/spittles/12345”发起GET请求要优于</u>
    <u>对“/spittles/show?spittle_id=12345”发起请求</u>。前者能够识别出要查询的资源,而后者描述的是
    带有参数的一个操作——本质上是通过HTTP发起的RPC。

    两种不同的参数传递方式

       /**
         * 展示不同数量的数据
         * @param max 最大值
         * @param count 数量
         * @param model  
         * @return spitterList
         */
        @RequestMapping(value = "show", method = RequestMethod.GET)
        public String showSpittles(@RequestParam(value = "max",defaultValue = "MAX_VALUE",required = true) long max,
                                   @RequestParam(value = "count",defaultValue = "DEFAULT_COUNT_SIZE",required = true) int count,
                                   Model model) {
            List<Spittle> spittleList = spittleRepository.findSpittles(max, count);
            model.addAttribute("spittleList", spittleList);
            return "spittles";
        }
    
    
       
    
       
    

    5.4 处理表单

     /**
         * 注册BO 带有校验
         * @param spittle
         * @param errors
         * @return
         */
        @RequestMapping(value = "register", method = RequestMethod.POST)
        public String processRegistration(@Validated Spittle spittle, Errors errors) {
    
            // 如果表单校验出差,则返回到注册页面
            if (errors.hasErrors()) {
                return "registerForm";
            }
            // 重定向到基本信息页
            return "redirect:/spitter" + spittle.getUsername();
        }
    
    
        /**
         * 通过spitter的username查找
         * @param username
         * @param model
         * @return
         */
        @RequestMapping(value = "spittle/{username}", method = RequestMethod.GET)
        public String spittle(@PathVariable("username") String username, Model model) {
            List<Spittle> spittleList = new ArrayList<>();
            spittleList.add(spittleRepository.findByUsername(username));
            model.addAttribute("spittleList", spittleList);
            return "spittles";
        }
    

    Java校验API所提供的校验注解

    注 解 描述
    @AssertFalse 所注解的元素必须是Boolean类型,并且值为false
    @AssertTrue 所注解的元素必须是Boolean类型,并且值为true
    @DecimalMax 所注解的元素必须是数字,并且它的值要小于或等于给定的BigDecimalString值
    @DecimalMin 所注解的元素必须是数字,并且它的值要大于或等于给定的BigDecimalString值
    @Digits 所注解的元素必须是数字,并且它的值必须有指定的 @Digits(integer = 0, fraction =10 )
    @Future 所注解的元素的值必须是一个将来的日期
    @Past 所注解的元素的值必须是一个已过去的日期
     /**
         * 通过id查找
         * @param spittleId
         * @param model
         * @return
         */
        @RequestMapping(value = "spittle/{spittleId}", method = RequestMethod.GET)
        public String spittle(@PathVariable("spittleId") Long spittleId, Model model) {
            List<Spittle> spittleList = new ArrayList<>();
            spittleList.add(spittleRepository.findOne(spittleId));
            model.addAttribute("spittleList", spittleList);
            return "spittles";
        }
    
        /**
         * 打开注册页面
         * @return
         */
        @RequestMapping(value = "register", method = RequestMethod.GET)
        public String showRegisterationFrom() {
            return "registerForm";
        }
    

    5.5 小结

    读完之后也基本上入门的内容,代码也跟着写一下,但也有生疏的地方,jsp页面标签的陌生,即使现在已经在项目上不怎么用了,尤其刚搭建项目时,由于jar包的冲突,实在尴尬,页面一直是500,又看了很多帖子,加了几个jar包就好了。

    知识虽然基础,但需要系统的去认识


    ============================================================

    第6章 渲染Web视图

    本章内容:
    将模型数据渲染为HTML
    使用JSP视图
    通过tiles定义视图布局
    使用Thymeleaf视图

    Spring MVC定义了一个名为ViewResolver的接口

    public interface ViewResolver {
        View resolveViewName(String var1, Locale var2) throws Exception;
    }
    
    public interface View {
        String getContentType();
        void render(Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception;
    }
    
    

    View接口的任务就是接受模型以及Servlet的request和response对象,并将输出结果渲染到response中。

    6.3 使用Apache Tiles视图定义

    原始的方式:

    页面定义一个通用的头部和底部。最原始的方式就是查找每个JSP模板,并为其添加头部和底部的HTML。但是这种方法的扩展性并不好,也难以维护。为每个页面添加这些元素会有一些初始成本,而后续的每次变更都会耗费类似的成本。
    更好的方式是:

    使用布局引擎,如Apache Tiles,定义适用于所有页面的通用页面布局。SpringMVC以视图解析器的形式为Apache Tiles提供了支持,这个视图解析器能够将逻辑视图名解析为Tile定义

    6.4 使用Thymeleaf

    JSP规范是与Servlet规范紧密耦合的,这意味着它只能用在基于Servlet的Web应用之中。JSP模板不能作为通用的模板(如格式化Email),也不能用于非Servlet的Web应用

    为了要在Spring中使用Thymeleaf,我们需要配置三个启用Thymeleaf与Spring集成的bean:

    • ThymeleafViewResolver:将逻辑视图名称解析为Thymeleaf模板视图;
    • SpringTemplateEngine:处理模板并渲染结果;
    • TemplateResolver:加载Thymeleaf模板

    配置Thymeleaf视图解析器

    package com.web.spittr.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    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.thymeleaf.spring3.SpringTemplateEngine;
    import org.thymeleaf.spring3.view.ThymeleafViewResolver;
    import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
    import org.thymeleaf.templateresolver.TemplateResolver;
    /**
     * @Auther: shuaihu.shen@hand-china.com
     * @Date: 2018/12/4 09:13
     * @Description:
     */
    @Configuration
    @EnableWebMvc     // 启用mvc
    @ComponentScan("com.web.spittr")  // 启用组件扫描
    public class Webconfig extends WebMvcConfigurerAdapter {
    
        /**
         * 配置JSP视图解析器
         * @return
         */
        @Bean
        public TemplateResolver templateResolver() {
            TemplateResolver templateResolver = new ServletContextTemplateResolver();
            templateResolver.setPrefix("/WEB-INF/views/");
            templateResolver.setSuffix(".html");
            templateResolver.setTemplateMode("HTML5");
            return templateResolver;
        }
    
        /**
         * thymeleaf 视图解析器
         * @param templateEngine
         * @return
         */
        @Bean
        public ViewResolver viewResolver2(
                SpringTemplateEngine templateEngine) {
            ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
            viewResolver.setTemplateEngine(templateEngine);
            return viewResolver;
        }
    
        /**
         * 模板引擎
         * @param templateResolver
         * @return
         */
        @Bean
        public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {
            SpringTemplateEngine templateEngine = new SpringTemplateEngine();
            templateEngine.setTemplateResolver(templateResolver);
            return templateEngine;
        }
    
       
    
        /**
         * 静态文件处理
         * @param configurer
         */
        @Override
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
            configurer.enable();
        }
    
    }
    
    

    引入Thymeleaf 真的让人感到着急,前后一直弄,指导昨天晚上十一点之后才可以,一直不能导入TemplateResolver这个类,找了很久,不知道缺失什么jar包,其实也知道方向如何,只能没有去试,jar的版本冲突,可怜的娃子,以后还是找稳定一些的,作者给的jar不用去尝试新的了。

       <dependency>
                <groupId>org.thymeleaf</groupId>
                <artifactId>thymeleaf</artifactId>
                <version>2.1.4.RELEASE</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring3 -->
            <dependency>
                <groupId>org.thymeleaf</groupId>
                <artifactId>thymeleaf-spring3</artifactId>
                <version>2.1.2.RELEASE</version>
            </dependency>
    
    

    =============================================================

    相关文章

      网友评论

        本文标题:第2部分 Web中的Spring

        本文链接:https://www.haomeiwen.com/subject/jamuwqtx.html