浅析 SpringMVC 原理和配置.

一、原理

      Spring MVC基于模型-视图-控制器(Model-View-Controller,MVC)模式实现,它能够帮你构建像Spring框架那样灵活和松耦合的Web应用程序,将请求处理的逻辑和视图中的渲染实现解耦。

      

1、DispatcherServletSpring MVC的核心 。Spring MVC 中的请求页面都会委托给DispatcherServlet来执行处理。

2、DispatcherServlet需要知道将请求发送给哪个控制器,所以DispatcherServlet会查询一个或多个处理器映射(handler mapping) 来确定请求的下一站在哪里。

3、到了控制器(controller),请求会卸下其负载(用户提交的信息)并耐心等待控制器处理这些信息。

4、控制器在处理完成后,通常会产生一些信息,这些信息称为模型(model)。但是这个模型到底是渲染哪个页面的呢?所以控制器还会返回视图相关的东西。Spring 有个思想就是前后端分离,为了和视图解耦,所以控制器只返回了视图名。即,这里控制器返回了模型和视图名(modelAndViews)。

tips:Model 实际上就是一个Map(也就是key-value对的集合),它会传递给视图,这样数据就能渲染到客户端了,当调用addAttribute()方法并且不指定key的时候,那么key会根据值的对象类型推断确定,比如 List<Spittle>,那么推断他的 key 就是 spittleList。如果你希望使用非Spring类型的话,那么可以用java.util.Map来代替Model。

5、MVC 要怎么依靠一个视图名找到对应的视图呢?答案就是 视图解析器(view resolver)。

6、视图解析器(ViewResolver )接口会根据试图名和Locale对象返回一个View实例。View 接口的任务就是接受Model 以及Servlet的request和response对象,并将输出结果渲染到response中。

7、视图 (比如 JSP)。最终会被相应的容器(比如Tomcat)解析成 HTML 页面,并响应用户的请求。

tips实际上,设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理。

二、使用 Java 配置

    按照传统的方式,像 DispatcherServlet 这样的Servlet会配置在web.xml文件中 ,但是,借助于Servlet 3规范和Spring 3.1的功能增强,这种方式已经不是唯一的方案了 。我们会使用Java将DispatcherServlet配置在Servlet容器中。开始前,我们先来理解下 DispatcherServlet 和 Servlet 监听器(也就是ContextLoaderListener) 这两个应用上下文 。

DispatcherServlet 上下文:当DispatcherServlet启动的时候,它会创建Spring应用上下文,并加载配置文件或配置类(即带有@configuration注解的配置类)中所声明的bean,主要是Web 组件中的 bean, 包括 控制器(controller)、映射器(handler mapping)、视图解析器(view resolver)等。

ContextLoaderListener 上下文:这个上下文 由 ContextLoaderListener  创建,主要负责加载应用中的其他 bean 。这些bean通常是驱动应用后端的中间层和数据层组件。

1、实现:
    我们通过继承 AbstractAnnotationConfigDispatcherServletInitializer 类来配置SpringMVC,以作为传统 XML 配置的替代方案。实际上,AbstractAnnotationConfigDispatcherServletInitializer  会 同时创建 DispatcherServlet 和 ContextLoaderListener 。当然,我们需要手动配置我们的映射路径、视图解析器 并启用组件扫描 以及一系列我们可以自定义的配置。当然,如果我们没有配置视图解析器,SpringMVC 会启用默认的视图解析器(通过查找 ID 与视图名称相匹配的Bean,并且这个Bena 要实现View 接口)。如果没有配置路径映射,DispatcherServlet会映射为应用的默认Servlet,所以它会处理所有的请求,包括对静态资源的请求,如图片和样式表等。

public class SplittrWebAppInitailzer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    /*返回会创建ContextLoaderListener 上下文*/
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootConfig.class};
    }

    返回会创建 DispatcherServlet 上下文[] getServletConfigClasses() {
        new Class<?>[]{WebConfig.配置路径映射protected String[] getServletMappings() {
        new String[]{"/"};
    }
}
最小但可用的SpringMVC配置

@Configuration
@ComponentScan(basePackages = {"com"},excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,value = EnableWebMvc.)
        })
 RootConfig {
}
RootConfig.java

@Configuration
@EnableWebMvc //启用SpringMVC,当然也可以使用 <mvc:annotation-driven /> 注解驱动
@ComponentScan(basePackages = "com.controller")
class WebConfig  WebMvcConfigurerAdapter {

    /**
     * 在查找的时候,它会在视图名称上加一个特定的前缀和后缀
     * (例如,名为home的视图将会解析为/WEB-INF/pages/home.jsp)。
     *
     * @return
     
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        设置是否把所有在上下文中定义的bean作为request属性可公开访问。
          这样在JSP 2.0中可使用${}来存取,JSTL中使用c:out。
          默认为false。
        resolver.setExposeContextBeansAsAttributes(true);
        resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class); 设置解析JSTL
        return resolver;
    }

    
     * 通过调用DefaultServlet-HandlerConfigurer的enable()方法,
     * 我们要求DispatcherServlet将对静态资源的请求转发到Servlet容器
     * 中默认的Servlet上,而不是使用DispatcherServlet本身来处理此类请求
     *
     * @param configurer
     void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}
WebConfig.java

    InternalResourceViewResolver所采取的方式并不那么直接。它遵循一种约定,会在视图名上添加前缀和后缀,进而确定一个Web应用中视图资源的物理路径。当逻辑视图中包含斜线时,这个斜线也会带到资源的路径名中。
    通过  resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class)  配置了视图解析器的ViewClass后,可以保证 JSTL的格式化和信息标签能够获得Locale对象以及Spring中配置的信息资源。

2、测试:

    @RequestMapping(value = {"/","/home"},method = RequestMethod.GET)
     String getHome(Model model){
        return "home";
    }
controller

       

3、请求参数说明

A、处理requet URL 部分(不含queryString)的注解: @PathVariable;
B、处理request header部分的注解: @RequestHeader,@CookieValue;
C、处理request body部分的注解:@RequestParam,@RequestBody;
D、处理attribute类型是注解: @SessionAttributes,@ModelAttribute;

@RequestParam:可以处理get方式中的queryString的值,也可以处理post方式的body data 的值。用来处理Content-Type 为 application/x-www-form-urlencoded 编码的内容,提交方式GET、POST。

@RequestBody:

该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json,application/xml等;
特殊情况下,也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String,String>里。
返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据

@ModelAttribute
该注解有两个用法,一个是用于方法上,一个是用于参数上;
用于方法上时: 通常用来在处理@RequestMapping之前,为请求绑定需要从后台查询的model;
用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;要绑定的值来源于:
    A) @SessionAttributes 启用的attribute 对象上;
    B) @ModelAttribute 用于方法上时指定的model对象;(会绑定需要的对象,比如model.addAttribute("pet", pet);
    C) 上述两种情况都没有时,new一个需要绑定的bean对象,然后把request中按名称对应的方式把值绑定到bean 对象的各个属性中。

(1) SpringMVC 在 处理表单的时候,可以接受一个POJO对象(不用添加任何注解)作为参数。对象中的属性会使用请求中同名的参数进行补充,默认调用@ModelAttribute。
                                                        可以接受一个基本数据类型(不用添加任何注解)作为参数。会使用请求中同名的参数进行补充,默认调用@RequestParam。

(2) 当InternalResourceViewResolver看到视图格式中的“redirect:”前缀时,它就知道要将其解析为重定向的规则,而不是视图的名称。InternalResourceViewResolver还能识别“forward:”前缀。当它发现视图格式中以“forward:”作为前缀时,请求将会前往(forward)指定的URL路径,而不再是重定向。

分享一篇这方面讲得特别好的博客:http://blog.csdn.net/truong/article/details/28097837

4、添加自定义Servlet、Filter、Listener

class MyServlet  HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
        doGet(request,response);
    }

    void doGet(HttpServletRequest request,IOException {
        System.out.println("这是新建的Servlet");
    }
}
自定义Servlet类

class MyServletInitializer implements WebApplicationInitializer {
    void onStartup(ServletContext servletContext)  ServletException {
        ServletRegistration.Dynamic myServlet = servletContext.addServlet("MyServlet",MyServlet.);
        myServlet.addMapping("/myServlet");
    }
}
注册Servlet

    注册Filter、Listener 也可以用类似的方式。但是,如果你只是注册Filter,并且该Filter只会映射到DispatcherServlet上的话,那么在AbstractAnnotationConfigDispatcherServletInitializer中还有一种快捷方式。 

class MyFilter  Filter {
     destroy() {
    }

    void doFilter(ServletRequest req,ServletResponse resp,FilterChain chain) );
        chain.doFilter(req,resp);
    }

    void init(FilterConfig config)  ServletException {

    }

}
自定义Filter类

     Filter[] getServletFilters() {
        new Filter[]{ MyFilter()};
    }
在AbstractAnnotationConfigDispatcherServletInitializer的继承上添加...

三、使用 XML 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app
        version="3.0"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <!--Web应用图标:指出IDE和GUI工具用来表示Web应用的大图标和小图标-->
    icon>
        small-icon>/images/small.gif</large-icon>/images/large.gif>
    >
    
<!--定义了WEB应用的名字display-name>mvc声明WEB应用的描述信息description>mvc test>
上下文参数:在servlet里面可以通过 getServletContext().getInitParameter("name")得到设置根上下文配置文件位置context-paramparam-name>contextConfigLocationparam-value>classpath:applicationContext.xml配置过滤器filterfilter-name>encoding-filterfilter-class>org.springframework.web.filter.CharacterEncodingFilterinit-param> >encoding>UTF-8filter-mappingurl-pattern>/*配置监听器 注册ContextLoaderListenerlistenerlistener-class>org.springframework.web.context.ContextLoaderListener配置Servlet 注册DispatcherServletservletservlet-name>appServletservlet-class>org.springframework.web.servlet.DispatcherServletload-on-startup>1servlet-mapping>/会话超时配置(单位为分钟)session-configsession-timeout>120mime类型配置,用来指定对应的格式的浏览器处理方式配置静态页面的打开编码mime-mappingextension>htmmime-type>text/html;charset=gb2312>html欢迎文件页配置welcome-file-listwelcome-file>index.jsp错误页面配置配置了当系统发生404错误时,跳转到错误处理页面NotFound.jsperror-page> error-code>404location>/NotFound.jsp配置了当系统发生java.lang.NullException(即空指针异常)时,跳转到错误处理页面error.jspexception-type>java.lang.NullException>/error.jsp> <!--以上是常见的配置,以下的东西也没搞懂怎么用,特别是 security-role 的含义指的是?--> 安全限制配置与login-config元素联合使用,指定服务器应该怎样给试图访问受保护页面的用户授权security-constraintweb-resource-collectionweb-resource-name>ProtectedArea>/resources/*如果没有<http-method>方法,表示禁止所有的HTTP方法访问对应的资源--> http-method>GET哪些用户应该具有受保护资源的访问权 如果没有 <auth-constraint> ,配置实际上是不起作用的。 如果内容为空,表示所有的身份都被禁止访问--> auth-constraintrole-name>ALL Role> 登录验证配置四种认证类型 BASIC:HTTP规范,Base64 这种方式被认为是最不安全的认证,因为它没有提供强烈的加密措施 login-configauth-method>BASIC DIGEST:HTTP规范,数据完整性强一些,但不是SSL 相比于BASIC认证,它是种比较安全的认证,它在认证时将请求数据 通过MD5的加密方式进行认证 >DIGEST CLIENT-CERT:J2EE规范,数据完整性很强,公共钥匙(PKC) 这是一种基于客户端证书的认证方式,比较安全。但缺陷是在没有安全证书的客户端无法使用 >CLIENT-CERT FORM:J2EE规范,数据完整性非常弱,没有加密,允许有定制的登录界面 这是种基础自定义表单的认证,你可以指定登录时的验证表单 >FORMform-login-configform-login-page>/login.htmlform-error-page安全角色这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易(没看懂这句话)security-role> web-app>

tipsweb.xml 的加载顺序是:ServletContext -> context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。

四、结语 

    2017年最后一篇博文了,坚持在2017年的最后一个晚上写完。毕竟2017的事总不好意思拖一年呀!坚持写博客真是个好习惯,好记性毕竟不如白纸黑字来的牢靠啊,如果把记性比作网上搜索的话,博客就是自己的一份离线存储。

    本来想好好回顾下2017,打一大堆满满的文字,装一个文艺的青年。真到落笔的时候,什么都不想写。敬往事一杯酒,悠悠岁月不回头!

    祝大家新年快乐!2018!我来了......

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


开发过程中是不可避免地会出现各种异常情况的,例如网络连接异常、数据格式异常、空指针异常等等。异常的出现可能导致程序的运行出现问题,甚至直接导致程序崩溃。因此,在开发过程中,合理处理异常、避免异常产生、以及对异常进行有效的调试是非常重要的。 对于异常的处理,一般分为两种方式: 编程式异常处理:是指在代
说明:使用注解方式实现AOP切面。 什么是AOP? 面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 通俗描述:不通过修改源代码方式,在主干功能里面添加新功能。 AOP底层使用动态代理。 AOP术语 连接点
Spring MVC中的拦截器是一种可以在请求处理过程中对请求进行拦截和处理的机制。 拦截器可以用于执行一些公共的操作,例如日志记录、权限验证、数据转换等。在Spring MVC中,可以通过实现HandlerInterceptor接口来创建自定义的拦截器,并通过配置来指定拦截器的应用范围和顺序。 S
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:ServletContext、HttpSession、HttpServletRequest、PageContext。 ServletContext 共享域:
文件上传 说明: 使用maven构建web工程。 使用Thymeleaf技术进行服务器页面渲染。 使用ResponseEntity实现下载文件的功能。 @Controller public class FileDownloadAndUpload { @GetMapping(&quot;/file/d
创建初始化类,替换web.xml 在Servlet3.0环境中,Web容器(Tomcat)会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。 Spring提供了这个接口的实现,名为SpringS
在 Web 应用的三层架构中,确保在表述层(Presentation Layer)对数据进行检查和校验是非常重要的。正确的数据校验可以确保业务逻辑层(Business Logic Layer)基于有效和合法的数据进行处理,同时将错误的数据隔离在业务逻辑层之外。这有助于提高系统的健壮性、安全性和可维护
什么是事务? 事务(Transaction)是数据库操作最基本单元,逻辑上一组操作,要么都成功,要么都失败,如果操作之间有一个失败所有操作都失败 。 事务四个特性(ACID) 原子性 一组操作要么都成功,要么都失败。 一致性 一组数据从事务1合法状态转为事务2的另一种合法状态,就是一致。 隔离性 事
什么是JdbcTemplate? Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。 准备工作 引入jdbcTemplate的相关依赖: 案例实操 创建jdbc.properties文件,配置数据库信息 jdbc.driver=com.mysql.cj.
SpringMVC1.MVC架构MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范是将业务逻辑、数据、显示分离的方法来写代码MVC主要作用是:降低了视图和业务逻辑之间的双向耦合MVC是一个架构模型,不是一种设计模式。1.model(模型)数据模型,提供要展示的数据,因此包
SpringMVC学习笔记1.SpringMVC应用1.1SpringMVC简介​SpringMVC全名叫SpringWebMVC,是⼀种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于SpringFrameWork的后续产品。​MVC全名是ModelViewController,是模型(model)-视图(view)-控制器(co
11.1数据回显基本用法数据回显就是当用户数据提交失败时,自动填充好已经输入的数据。一般来说,如果使用Ajax来做数据提交,基本上是没有数据回显这个需求的,但是如果是通过表单做数据提交,那么数据回显就非常有必要了。11.1.1简单数据类型简单数据类型,实际上框架在这里没有
一、SpringMVC简介1、SpringMVC中重要组件DispatcherServlet:前端控制器,接收所有请求(如果配置/不包含jsp)HandlerMapping:解析请求格式的.判断希望要执行哪个具体的方法.HandlerAdapter:负责调用具体的方法.ViewResovler:视图解析器.解析结果,准备跳转到具体的物
1.它们主要负责的模块Spring主要应用于业务逻辑层。SpringMVC主要应用于表现层。MyBatis主要应用于持久层。2.它们的核心Spring有三大核心,分别是IOC(控制反转),DI(依赖注入)和AOP(面向切面编程)。SpringMVC的核心是DispatcherServlet(前端控制器)。MyBatis的核心是ORM(对
3.注解开发Springmvc1.使用注解开发要注意开启注解支持,2.注解简化了,处理映射器和处理适配器,只用去管视图解析器即可案例代码:1.web.xml,基本不变可以直接拿去用<!--调用DispatcherServlet--><servlet><servlet-name>springmvc</servlet-name>
拦截器概述SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。**过滤器与拦截器的区别:**拦截器是AOP思想的具体应用。过滤器servlet规范中的一部分,任何javaweb工程都可以使用
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:xsi="
学习内容:1、SSH&SSM2、Spring3、Struts2&SpringMVC4、Hibernate&MyBatis学习产出:1.SSH和SSM都是有Spring框架的,他们两个差不多。2.Spring分为四个模块,持久层,表示层,检测层,还有核心层,核心层分为2个关键核心功能。分别为,控制反转(IOC),依赖注入(DI),和面向切面编程
一、SpringMVC项目无法引入js,css的问题具体原因是css和js等被SpringMVC拦截了:解决方案:在spring-mvc.xml中配置<mvc:default-servlet-handler/><?xmlversion="1.0"encoding="UTF-8"?><beansxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
开发环境:Eclipse/MyEclipse、Tomcat8、Jdk1.8数据库:MySQL前端:JavaScript、jQuery、bootstrap4、particles.js后端:maven、SpringMVC、MyBatis、ajax、mysql读写分离、mybatis分页适用于:课程设计,毕业设计,学习等等系统介绍