SpringMVC
第一记:springMVC整个的原理或者说整个响应流程
步骤一:当客户端发起一个请求,首先接受到的请求的是Dispatcher servlet(前端控制分发器或者就叫做请求分发器),前端控制分发器会将请求转发到HandlerMapping映射组件。这个前端控制器除了分发的作用,比如还可以对url的一些操作进行设置,例如,在使用rest风格下载图片,在url中有图片的名称,但图片的名程是一.jpg结尾。前端控制器会自动去除后面的jpg.从而导致下载失败。修改默认值,不去除后缀,就消除了这种现象。
步骤二:当请求到HandlerMapping:该组件,将请求的url映射到具体的Hanler上,注意此时具体的Handler还没有处理请求。这里Handler就是controller层的实现类,就是controller类。
步骤三:当HandlerMapping映射完成后还把映射结果返回给Dispatcher Servlet.其实在这个返回的过程中,可以进行异常的获取,以及做一些拦截操作,这一些操作称之为执行链。
步骤四: Dispatcher Servlet收到映射值后分发到具体Handler处理,在具体的handler处理之前,还有一个过程,就是会经过适配器。
步骤五:适配器有两种方法:因为具体的Handler一般处理请求要么通过实现接口的方式,来复写固定方法接受请求,要么就是使用注解的方式来接受请求,因此在具体的handler处理之前是需要进行适配的。
步骤六:适配器之后就是具体的Handler处理逻辑请求,并返回结果,这个结果是ModelAndView对像.这个对象包含了数据模型以及视图的名称。
步骤七:VeiwResolve,就是根据视图名称找到视图.进行视图的解析处理,最后封装成view对象。(这里为了方便记忆,首先根据视图名称找到jsp,其次,将jsp和Model组成了视图对象)
步骤八:最后就是视图的渲染,(就是将数据写入到jsp里面)然后返回给客户端。整个SpringMVC的过程处理完毕。其实,视图有很多表现形式:例如:jsp,pdf,表格等。
第二记:spring之核心配置文件
步骤一:首先在web.xml里面配置前端核心分发器。在web.xml里面增加了<servlet/>
节点以及<servlet-mapping/>
节点。范列
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>这里是springMVC自带的DispatherServlet类</servlet-class>
<load-on-startup>1(启动就加载)</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/(代表所有请求)</url-pattern>
</servlet-mapping>
步骤二:springmvc的核心配置文件,springmvc的核心配置文件,有两定义方式,第一种,默认的定义方式,就是默认的配置文件放置在WEB-INFO/目录下,并且配置文件的名称为springMVC(这个与前面的web.xml里面的servlet节点下的servlet-name的名称保持一致)-servlet.xml。先讲解这种配置文件的配置。以下步骤是实现接口(controller)的方式。
第一步配置:配置映射组件(BeanNameUrlHandlerMapping)
第二步配置:配置适配器(simplecontrollerHanlerAdapter)
第三步配置:配置具体Handler(<bean name="/hello" class="具体controller类"/>
)
第四步配置:配置视图解析器以及视图渲染器。范列如下
<bean class="***.InternelResourceViewResolver">
<property name="prefix" value="WEB-INFO/view/"/>
<property name = "suffix" value=".jsp"/>
//下面是渲染器
<property name = "viewClass" class="***.JstlView" />
</bean>
接下来通过自定义的方式配置核心配置文件,通过自定义的方式配置核心配置文件,需要在web.xml里面指定自定义配置文件的位置,范例如下:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>这里是springMVC自带的DispatherServlet类</servlet-class>
//初始化指定springmvc的核心配置文件
<init-param>
<param-name>contextConfigLacation</param-name>
<param-value>classpath:springmvc</param-value>
</init-param>
<load-on-startup>1(启动就加载)</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/(代表所有请求)</url-pattern>
</servlet-mapping>
接下来通过注解的方式配置核心配置文件
第一步配置:配置映射组件(RequestMappingHandlerMapping)
第二步配置:配置适配器(RequestMappingHanlerAdapter)
第三步配置:配置具体Handler(<context :component-scan base-package="/controller">
)
第四步配置:配置视图解析器以及视图渲染器。范列如下
<bean class="***.InternelResourceViewResolver">
<property name="prefix" value="WEB-INFO/view/"/>
<property name = "suffix" value=".jsp"/>
//下面是渲染器
<property name = "viewClass" class="***.JstlView" />
</bean>
优化上面的注解:可以用一个注解替代上面第一步和第二步
<mvc annotation-drivern/>
,其次就是默认jsp.那么渲染器也不用配置了。
第三记,springmvc之静态资源。
第一步:问题的引出,当你在jsp页面中,使用img标签引入静态图片,如果只用以上配置,将导致静态资源不能被找到,原因是前端核心分发器的配置的路径和tomcat默认的defaultServlet的拦截路径一样都是斜杠/。因为tomcat的默认servlet不起作用。因此需要在springmvc的核心配置文件里面声明启动tomcat默认的servlet.在核心配置文件里面添加如下配置, 如下面所是:
<mvc:default-servlet-handler/>
但是上面的配置是存在缺陷的,因为这个声明只对tomcat服务器有效,对其他web服务器不一定有效。其次就是这个只能针对静态资源放在webapp目录下,对WEB-INFO/目录下的静态资源不起作用。因此需要第二步的配置。
第二步:通过springmvc支持的映射方式来完成静态资源的访问,只要在springmvc的核心配置文件里面加上如下的配置就可以
<mvc:resource mapping="/image/**" location="/WEB-INFO/image/"/>
<mvc:resource mapping="/css/**" location="/WEB-INFO/css/"/>
<mvc:resource mapping="/js/**" location="/WEB-INFO/js/"/>
<mvc:resource mapping="/image/**" location="/image/"/>
之后在spring boot 中的使用:
例如:WebMvcConfiguration配置类,只要实现WebMvcConfigurationSupport类,就可以复写WebMvcConfigurationSupport类里面的addResourceHandlers(ResourceHandlerRegistry registry);
上诉的mapping 路径,就可以使用registry.addResourceHandler("/image/**");来替代。
location就可以使用registry.addResourceLocations(“classpath:/WEB-INFO/image”);
来替代。
这里小记一下,如果想直接访问jsp页面呢,那么就需要在核心配置文件里面添加如下的配置
<mvc:view-controller path="/userLogin" view-name="login"/>
如过不进行这样的配置,一般就需要在controller层进行转发。
第四记springMVC之返回值。
springmvc的返回值一般有四种模式,接下来以此讲解这几种模式。
第一种模式:返回值的类型为ModelAndView:当返回值为这个值的时候表示的是,返回的数据模型加视图的名字。这是最基础,以后可能会用的比较少。
第二种模式:返回值的类型为String:当返回值为字符串时,有三种情况:
第一种情况:就是返回一个普通的字符串:例如:return “success”,这样就表返回success视图,或者说success.jsp.
第二种情况:“forward”+“路径”:例如:return “forware:login” ,这表示转发请求,但浏览器的url不会发生变化。
第三种情况:“redirect”+“路径”:例如:return “redirect:login”, 这表示重新定向请求的,url会发生变化。这次请求获取不到上次请求的模型数据。
第三种模式:返回值类型为空 void:例如@RequestMapping("/test").那么就默认类似于返回test.jsp.所以在前端前面返回404错误。
第四种模式:返回值类型为Object:这种模式需要结合字符和对象解析器,最后将对象编程json格式。
第五记 springMVC之注解。
注解 | 注解解释 |
---|---|
@controller | 将注解类变成了接口Controller的子类,并注入到Ioc容器种 |
@RequestMapping | 配置映射请求路径 URL |
@RequestParam | 表示参数来源于请求参数 |
@PathVariable | 表示参数来源于请求路径中 |
@ RequestHeader | 表示参数来源于请求头中 |
@CookieValue | 表示参数来源于Cookie中 |
@RequestBody | 表示参数来源于消息体中,一般是post的调用 |
@ModelAttribute | 表示将请求参数变成后台对象的 |
@valid | 后台数据校验 |
@initBinder | 类型转换注册属性编辑器 |
@ControllerAdvice | 处理全局异常的 |
@ExceptionHandler | 处理特定异常 |
@ResponseBody | 一般结合返回值为Object一起使用 |
@RestController | 这个注解表示为该类加上了controller注解,并为该类中的每一个方法都加上@ResponseBody |
@SessionAttributes | 这个注解表示获取同一会话中的session数据 |
第六记 SpringMVC之@RequestMapping的详解
第一: 该注解可以对路径的起到分层的效果,该注解即可以放在类上面也可以放在方法上面。其次在方法里面的有forward 和 redirect转发,如果转发路径前面不加斜杠,就表示相对路径,如果加了斜杠表示决定路径。
第二:@RequestMaping("/test/*") 里面路径的表示模式有三种:
第一种模式:ant模式,然后ant模式下面有分为三类通配符。##### 第一类:单个符号:@RequestMaping("/test/`") ,表示匹配单层目录,却必须斜杠,后面也必须跟变量。
第二类:两个*符号:@RequestMaping("/test/**") ,表示匹配多层目录或者单层目录,不一定要斜杠。
第三类:一个?符号:@RequestMaping("`/test/?") ,表示匹配一个字符,有且只有一个字符。
第二种模式:rest模式,rest模式也分两类:
第一类:普通的占位符合哦模式:@RequestMaping("/test/{id}") ,这个需要结合注解@PathVariable 一起使用。这个是在id值在路径种。
第二类:就是普通的占位符+正则表达式@RequestMaping("/test/{id:\\d+}
")。对输入的值做校验。
第三种模式:固定的写法:有path 和 value .他们可以互换,其次,他们还可以有多个值:例如:@RequestMaping(value={"/test",“test1”})
第三;可以限定请求方式
一般Http的请求方式有八种,但是常用的方式就四种,get,post,put,delete.如果想对某个方法的请求方式做限定。可以使用注解的变量来限制,例如:@RequestMaping(value={"/test",“test1”},method=RequestMathod.POST)
第四:可以限定参数以及头部
可以对请求的参数限制传输那几格参数,以及参数的值,以及还有请求头部。示例如下:
@RequestMaping("/test",params={"id","username=admin",password="1234"})
@RequestMaping("/test",header={"Cookie","Accept-Language=zh-CN,zh,q=0.7"})
第七记:springMVC之请求方法的输入参数
方法的请求的输入参数可以分为七种模式:
第一种模式就是JAVAEE模式:实例
@RequestMapping("test")
public String test(HttpRequest request,HttpResponse response,HttpSession session){
}
第二种模式就是字节流模式:实例
@RequestMapping("test")
public String test(InputStream inputt,OutputStream response){
//其实等价于:
InputStream inputStream = request.getInputStream();
OutputStream outputStream = response.getOutputStream();
}
第三种模式就是字符流的模式
@RequestMapping("test")
public String test(Reader reader,Writer writer){
//其实等价于:
Reader reader = request.getReader();
Writer writer = response.getWriter();
}
第四种模式,返回值为void,方法的输入参数,在方法里面的赋的值,在jsp页面能够获取。
@RequestMapping("test")
public String test(Model model,Map map ,ModelMap modelMap){
//其实等价于:
model.attribute(key,value)
map.put(key.value)
modelMap.attribute(key.value)
modelMap.put(key.value)
return "result"
}
第五种模式,方法的输入参数是String.针对这种方式就能用到很多注解。如以下注解:
@RequestParam:来源于请求参数。@RequestHeader:来源于请求头 @CookieValue:来自于cookie中的值。@RequestBody:来源post的请求,多个字段最后用&拼接的。@PathVariable:来源于请求路径(restful风格,这种路径不能带点,springmvc.jpg:后面的jpg会被截取)。
第六种模式,自定义参数类型,就是牛逼的对象。这个需要使用的注解@ModelAttribute.该注解需要注意的地方就是,如果该注解不是放在方法参数前面而是放在方法上面的,当我们访问任何一个方法时,都会先执行该被这个注解所修饰的方法。然后把这个方法产生的数据放在Request作用域里面呢。实例
@ModelAttribute("/types")
public List<String> test(){
return new List();
}
调用这个方法产生了key:types,值为数组的对象,放入到request作用域。
第七种模式,输入参数是Errors,能够捕获到调用方法前产生的异常。例如在调用前回有校验,如果检验失败,那么这个对象就不会为空。
第八记:SpringMVC之类型转换。
类型转换的实现方式有两种,以下详细讲解两种方式:
讲解之前,先解决post请求中的中文乱码问题,可以在web.xml里面配置字符编码过滤器,具体可以网上百度。其次数据的绑定流成:获取值—》转换—》后台校验—》数据绑定。
第一种方式:编辑器:首先写一个编辑器类继承了PropertyEditorSupport类。复写里面的两个:一个是getAsText();把对象变成字符串。另一个setAsText():把字符串变成对象。编辑器类写好后,在springmvc的核心配置文件里面配置编辑器。实例如下
<bean class="***.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="entity.Address" value="editor.AddressEditor" />
</map>
</property>
</bean>
经过实践这种方式不能完成注册,所以还是需要用注解的方式来进行注册
@InitBinder
public void InitBinder(DataBinder dataBinder){
dataBinder(Address.class ,new AddressEditor)
}
这种方法存在缺点,其写在controller层的,其他controller用不到,其次,只能从字符串转变成对象。
第二种方式:转换器:转换器的实现方式与编辑器实现的方式差不多,需要新建了转换器类实现了Convert<S,D>接口。复写里面的convert方法,方法的输入参数是字符串,返回参数是需要转换的对象。转换器类写好之后,就需要在核心配置文件里面进行配置。
<bean class="***.FormattingConversionServiceFactoryBean">
<property name="converts">
<map>
<entry key="convert.String2AddressConvet" />
</map>
</property>
</bean>
第九记:springMVC之@SessionAttributes域全局异常处理(@ControllerAdvice与@ExceptionHandler)
SessionAttributes(“userVo”):会把方法中定义的某个参数的值放入到session中。
@ControllerAdvice这个注解放在类上,表示这个类异常拦截类,
@ExceptionHandler:这个注解打在方法上,表示了捕获某个特定的异常。
第十记springmvc之拦截器
HandleInterceptor:定义了一个类继承该拦截器,该拦截器里面有三个方法:有preHandle(在方法前调用,在视图渲染前,可以修改模型数据),postHandle(在方法后调用,但是视图渲染前),afterCompletion(在视图渲染之后调用,可以释放资源).
进行拦截器的配置,在springmvc的核心配置文件。
<mvc:interceptors>
<bean class="interceptor.HelloInterceptor"/>
<mvc:interceptor>
<mvc:mapping path="/user/register">
<mvc:exclude-mapping path="/user/test7">
<mvc:interceptor>
<mvc:interceptors>
第十一记springmvc之ajax请求:
对于ajax请求主要是处理返回值,如果不用@ResponseBody注解,需要自己使用HttpResponse.getWriter()方法,将字符流返回给ajax.这样比较麻烦,所以,在方法上了@ResponseBody,就不用HttpResponse.getWriter()操作,就可以直接返回字符串。但是如你想将对象最后以json的方式返回,光加一个@ResponseBody注解是不行。还需要导入相应的jar包。springmvc默认支持三种对象转json的方式:也就是转换器。如下是三种方式
第一种:jackson:默认支持。
第二种:gson:谷歌开发,默认支持。
第二种:fastson :阿里爸爸开发,这个需要在核心配置文件里面配置,默认不支持。
第十二记springmvc之文件上传
第一步:下载jar包:commons-fileupload
第二步:配置文件解析器
<bean id = "mutipartResolver" class="***.CommsMutipartResolver"/>
第三步:实现的方法上,upload(CommonsMutipartFile commonsMutipartFile)这个方法的参数前面必须加上@RequestParam注解。要不然请求失败。
第四步:把文件另存为:commonsMutipartFile.transferto(new File(路径,文件名))
第五步:同时上传多个文件,上面的方法变成数组模式upload(CommonsMutipartFile[] commonsMutipartFiles)
第六步:其实文件上传可以在第二步进行上传文件的大小
<bean id = "mutipartResolver" class="***.CommsMutipartResolver">
<property name="maxUploadSizePerFile" value="50000000000" />
<bean>