springMVC应用

spring MVC 应用

一 :spring MVC 介绍

1:spring mvc 是啥?

spring mvc 是spring框架功能的一部分

负责controller处理器,基于MVC设计模式

底层实现了封装了servlet,简化web开发

2: spring mvc 框架的作用

springMVC :web端的框架

  1. 简化获取请求参数
  2. 简化作出相应

spring:ioc|di

​ 1.对象的创建和管理,只负责用对象,不负责生产对象

​ 2.aop 简化代码,横向的散落到核心业务中

​ 3. jdbc 数据库工具类,简化jdbc操作,适合多表查询

 		4. test,不需要每次都自己搭建测试环境
 		5. tx:简化业务层事物的添加,
3:spring mvc 框架的容器组成

​ 常规的web项目开发需要两个容器,

一个是springMVC 的ioc 容器,内部装了controller和其他相关的view 相关的

内容springmvc 可以调用spring容器。而且是单向的,

另一个是spring的容器ioc的容器,内部封装了service repository etc 可以被

springmvc调用,但是他不能调用springmvc里面的内容

4:springmvc框架的核心组件
  1. dispatcherServlet:本质是一个servlet,而且是项目中唯一的servlet,他是所用请求的入口和出口

在web.xml 里面配置一下

  1. handlerMapping:处理器映射器,内部记录对应的地址的映射

  2. handlerAdapter:避免sipatcherservlet直接调用handler(controller)简化请求参数,相应处理

  3. handler:就是以后的controller,开发人员要处理请求的地方,处理请求是以方法为单位,更加简单的获取请求参数,调用业务逻辑,更加简单的作出相应

  4. viewResolver:视图解析器,将你返回的字符串找到对应的页面,返回给dispatcher,最后回给前面页面

二: springMVC 框架的基本使用

步骤一:导入jar依赖

spring core…

spring-web: 整合整个web项目的

spring-webmvc springmvc框架的包

步骤二:创建controller(handler)
步骤三:编写配置文件

springmvcioc 容器相关,(controller handleradapter,handlermapping viewResolver)

<!--handler自己定义的controller-->
 <!--handlerMapping
     handleradapter
     viewresovler
    框架已经定义好了我们只需要ioc
 -->
 <!--handler-->
 <context:component-scan base-package="com.it.controller"></context:component-scan>

 <!--handlermapping-->
 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
 <!--handlerAdapter-->
 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>


 <!--jsp-->
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <!--前缀-->
     <property name="prefix" value="/"></property>
     <!--后缀-->
     <property name="suffix" value=".jsp"></property>
 </bean>

web.xml : dispatcherservlet初始化容器

<!--dipatcherServlet-->
 <servlet>
     <servlet-name>ds</servlet-name>
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

     <!--初始参数-->
     <init-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>classpath:applicatonContext.xml</param-value>
     </init-param>
     <!--提前初始化-->
     <load-on-startup>1</load-on-startup>
 </servlet>
 <!--映射-->
 <servlet-mapping>
     <servlet-name>ds</servlet-name>
     <!--拦截所有除了jsp-->
     <url-pattern>/</url-pattern>
 </servlet-mapping>
步骤四:访问测试

三:spring MVC 框架的常用的注解

  1. @RequestMapping
    1. 位置:可以添加在方法 类(接口)上面
    2. 作用:将当前controller添加到handlerMapping中
    3. 参数:value String [] 具体映射路径,

    注意方法上必须添加,类上面可以不添加。默认方法的路径

    1. 且属性是个数组 String value[] ({“path1”,“path2”…})
    2. 也可以 path String [] = {“path1”,“path2”…}但是得申明path={}的形式
    3. method RequestMethod[] 允许的请求方式:post get
  >   method={RequestMethod.POST,RequestMethod.GET}
  1. produces:返回编码格式 produces=“application/json;charset=utf-8”

  2. 扩展

    GetMapping=@RequestMapping(method=get)

    @PostMapping 指定请求方式的注解

@RequestParam(“name”)

简化参数部分

  1. 原始方案获取参数

在handler对应的方法中传入请求和响应对应的对象(resquest,response)

再使用请求对象获取参数

缺点:没有用到springmvc的优点

  1. 直接接受

在handler对应的方法的参数列表中声明对应参数的名称和对应形参的类型

优点:更加方便的获取到了参数

缺点: 1.形参名必须要 和传参的名字相同

​ 2. 方法中有太多的形参不是一件好事

如果参数名和形参名不同,可以在形参类型前面加上,一旦指定形参名字,就不会再找到形参的名称了

@RequestParam(“name”)

@RequestParam的属性:

  1. name         		
  1. value

  2. defaultValue:默认值

  3. 封装对象,我们只需要传入对象就可以,handlerAdapter帮我们解析对象的参数转化问题

如果参数过多,都写入形参列表可不是一件漂亮事,因此,把这些参数都封装成一个对象,我们只需要把对象传入里面就可以,适配子会帮我们解析参数。

  1. 文件上传

前端三要素:

  1. method=post
  2. encytype = multipart/from=data
    3. input type=file

后端解析:

  1. commons-io
  1. conmmons-fileipload

原始文件上传步骤:&&&&&&&&&&&&&&&&

  1. 创建磁盘解析工厂
    2. 创建核心解析器
  2. 传入磁盘解析器
    4. 循环判断,传入的文件是字符还字节
  3. 文件类型进行存储到本地磁盘
mvc方式:
  1. 方法中形参(MultipartFile file)

MutipartFile涉及的方法

  1. getName()返回input里面输入的nam属性
  2. getOriginalName()原始文件名
  3. getSize()文件大小
  4. transferTo(new File("d/myfile")存储到磁盘位置
  1. 在mvc配置文件中进行解析器申明(fileupload)

文件解析器是给handleradapter配置的

但是handler是根据解析器的命名进行DI的

在ioc中要求命名固定

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
				               <property name="defaultEncoding"  value="UTF-8" />
				               <property name="maxUploadSize" value="#{20*1024*1024}" />
				          </bean>
5.@PathVariable

截取路径中的参数

为了获取路径动态传入的参数

获取路径动态传参

方法(@PathVariable 参数类型 参数名)

默认:参数名取的http 请求的传参,而不会取到路径中的动态路径部分

注意:

@PathVariable如果形参名he动态路径名一致,{名称}不需要额外的执行

如果不一致@PathVariable(name=“动态路径名”) 形参

@PathVariable(name=“pid”) 和 @RequestParam(name=“pid”)

相同点:ElementType.PARAMETER

不通电:PathVariable获取动态路径中{pid}
RequestParam获取请求参数中叫pid ?pid=xx

6.@CookieValue

​ 位置:方法内参

​ 作用:快速获取cookie的value并赋值给形参

​ 属性:name:cookie的名称 value:cookie的值 defaultValue 默认值

​ 例如:@CookieValue(value=“JSESSIONID”,defalutValue=“xxx”)String jsessionid

7. RequestHeader

​ 位置:方法内参

​ 作用:获取请求头的信息赋给方法的形参

​ 属性:name value defulatValue请求头不存在的时候,默认值

四:springMVC 框架简化响应部分

响应方式:

  1. 快速转发jsp|html(如何将数据放到共享域)

springmvc 框架提供了视图解析器,可以配合视图解析求得前缀后缀,在handler的方法中,返回页面的名字面积可以找到对应的页面。返回类型是一个字符串!

注意:
  1. 前提字符串前面不能加特殊’转发和重定向符号’! 字符串前不能包含 forward: redirect:
    2.不能使用restcontroller responsebody注解
如何将数据放到共享域!

servletContext
httpsession 重定向 一会会话
request 转发!
pageContext

方案一:传统方法

handler方法上可以传入请求对象!

请求对象获取其他的共享域!set/get/removeAttribute();

方案2: spring简化存储共享域的方式

modelAndView: 数据和视图:

自己将数据放到modelandview对象!同时把要跳转的视图路径!将modelandview对象返回!springmvc视图解析器会自动识别并转发到对应的页面!同时将modelandview中的数据放到request共享域!

使用
  1. handler返回值变成ModelAndView
  2. 方法中创建一个modelandview对象
  3. modelandview设置视图.setViewName(“index”);
  4. modelandview添加数据.addobject(key,value);

model:只携带数据!

map:根model是一样的!

1. 返回值的类型必须是String
2. 参数中传递一个map或者model
3. 向map或者model中添加数据即可!
4. adapter会拿到map和model获取数据,放到共享域中!
总结:以上三种提供数据放入共享域的方案! modelandview,model,map默认存在到request共享域!

默认存在到request共享域!handler类上添加 @SessionAttributes(names={“当初你往以上三个对象添加的key”})

  1. 转发

forward:/项目下的路径即可! 不用项目的根路径!方法返回值是是字符串

  1. 重定向

redirect:/项目下的路径即可! 不用项目的根路径!方法返回值是字符串

  1. 返回字符串(重点)
  2. 返回一个普通的字符串:@ResponseBody 可以加到类上和方法上!

类:类下的所有方法都返回字符串!方法:单一方法返回字符窜!

@RestController = @Controller+@ResponseBody

  1. 返回一个对象或者一个集合或者map或者map集合
    1. 导包 jackson-databind
    2. 配置json转化器

配置转化器方法1:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" >
 	<property name="messageConverters">
				                  <list>
				                        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
				                              <property name="supportedMediaTypes">
				                                    <list>
				                                          <value>text/html; charset=UTF-8</value>
				                                          <value>application/json;charset=UTF-8</value>
				                                    </list>
				                              </property>
				                        </bean>
				                        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
				                              <property name="supportedMediaTypes">
				                                    <list>
				                                          <value>text/html; charset=UTF-8</value>
				                                          <value>application/json;charset=UTF-8</value>
				                                    </list>
				                              </property>
				                        </bean>
				                  </list>
				            </property>
				         </bean>
3. 配置转化器方法2:<mvc:annotation-driven />

他替代了handlermapping handleradapter handleradapter的转化器等等!

4. json返回数据处理

实例类处理json生成数据:

@JsonInclude(JsonInclude.Include.NON_NULL) //不为null属性才会生成json

位置:实体类上!

@JsonInclude(JsonInclude.Include.NON_NULL) //不为null属性才会生成json
					   public class User {

						    @JsonProperty("user_name")
						    private String name;

						    @JsonIgnore
						    private int age;

						    private String info;

						    @JsonFormat(pattern = "yyyy年MM月dd日 HH:mm:ss",timezone = "GMT+8")
						    private Date date;

  1. 返回字节
  2. 方法返回值是void!

  3. 参数传入response对象!

  4. 直接使用response对象进行直接写出操作!

@RequestMapping("/bt")
					    public void returnBys(HttpServletResponse response) throws IOException {
					        ServletOutputStream outputStream = response.getOutputStream();
					        
					    }
数据传输问题:

​ ajax+html返回字符串

​ jsp(共享域)数据‘传递’

五: springMVC 解决静态资源拦截以及跨域请求问题

  1. 静态资源处理

动态资源值得不止资源本身,而是资源的执行结果

静态资源处理
方案1:
  			<mvc:default-servlet-handler />
		   后期再做handler路径声明的时候,尽量不要起静态资源后缀名的!
方案2: 指定映射文件夹

<mvc:resources mapping="/static/**" location="/static/" />

mapping指定要放行的路径!

location放行的路径对应的文件夹!

**问题:**一旦指定了放行的路径!就不能给handler起对应的路径命名!

建议: 使用第一种!

  1. 跨域访问问题

同原路径:当一个页面!内部发起一个ajax请求!请求某一个路径获取资源!浏览器会判断,当前访问页面的路径和ajax发起请求访问的路径!是否是同源!

如果同源:浏览器正常帮助发起ajax请求,并得到返回结果!如果非同源: 浏览器拒绝给你返回数据!他认为你在访问他人的项目,而且没得到运行!

除非第三方的服务器运行其他的源访问!浏览器才会给你返回数据!

如何区分同源:

先看协议版本
再看ip地址
最后看端口号

​ http://127.0.0.1:8080 http://localhost:8080 非同源

​ https://www.baidu.com http://www.baidu.com 非同源

​ http://www.baidu.com:80 http://www.baidu.com 同源

​ http://www.baidu.com:8080/qf http://www.baidu.com:8080/baidu 同源

默认情况下 web项目是运行浏览器根据同源策略进行资源拦截!

  1. 服务器如何放弃同源策略!

    同源策略需要在springmvc的容器配置中添加!注意不是web.xml

<mvc:cors>
			        <mvc:mapping 
			        			 //当前项目的任何路径 运行外部访问
			        			 path="/**"
			                     allowed-origins="*"   允许任何其他域名访问
			                     allowed-methods="POST, GET, OPTIONS, DELETE, PUT,PATCH"  允许任何方式访问
			                     allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
			                     allow-credentials="true" />
			    </mvc:cors>

六: springMVC的拦截器

Javaweb中 servlet处理请求 listener监听请求 filter过滤器请求(放行)只拦截servlet,静态资源
HandlerInterceptor拦截器
区别:

handlerinterceptor出现在springmvc内部调用

filter只能在dispatcherservlet之前出现,因此filter拦截更加强硬,handlerInterceptor拦截更加精细化,可以出现在springmvc的一个组件请求和响应位置。

使用
  1. 如何申明拦截

创建一个类实现HandlerInterceptor接口并实现里面的三个方法

  1. 拦截那些位置
  2. boolean perHandler(request,response,Handler)

返回值为false表示要拦截,拦截后要给用户友好提示,所以要用到 重定向或者转发

  1. void postHandler(request,response,Handler)

handler 执行完毕后在再进行其他验证,例如登陆后的权限验证

  1. void afterComplettion(request,response,Handler,exceptitor)

该方法在渲染完毕后,就是视图解析器找到页面的时候

  1. 设置拦截路径

位置:在springmvc配置文件中

  1. 声明拦截器
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="具体拦截路径"/>
		<!--拦截器位置-->            
        <bean 			                              class="com.it.interceptor.MyInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>
注意:
1. 拦截路径无需写项目根路径
2. 拦截路径方式:
   1. 层次路径  xxx/xxx/xx
   2. 通配符拦截    ?(一层单个字符)     *(一层多个字符)   **(多个层次,多个字符拦截)
  1. 使用拦截器,验证有没有登录等。
1.完善登录功能

 	    		    登录页面  登录处理  登录展示

 	    		    如何判断有没有登录! session

 	    		 2.拦截功能


     	    	     1. /user/*  /user/xxx /user 拦不拦截呢?
     	    	     2. /user/** /user/xx  /user 拦不拦截呢?
     	    	     3. /**/user/*   /user/a 拦不拦截呢?  /user拦不拦截呢

七:springmvc自带异常处理功能

1.利用状态码进行页面跳转

判断对应的状态码给用户一个友好的提示!一般用于404!
web.xml
<!-- 标注错误码以及对应的路径-->
	 <error-page>
	     <error-code>404</error-code>
	     <location>/static/html/404.html</location>
	 </error-page>
适合使用的场景:4系列 非代码错误!给用户友好提示可以修改的!

一下两种适合.代码异常! 500系列!
1.我网络异常请两个小时后再试
2.改bug 
代码异常必须触发某一个方法!
2.handler局部异常处理 
作用范围:一个handler
@ExceptionHandler
public String dealException(RuntimeException re, HttpServletRequest request){
 //当当前的handler中的方法出现异常!
 //只有当前的controller出现异常
//1.发送邮件
System.out.println("发送邮件");
//2.友好提示
return "info";
}

	     注意:1.不需要添加requestmapping 
	     	  2.可以添加responsebody!
	     	  3.可以转发或者重定向或是视图显示

	  3.全局异常处理 

	  	  注意:全局处理可以根据对应的异常类型进行单独处理!

	  	    @ControllerAdvice
			public class ExceptionHandler {
			    //下面的方法要捕捉那个异常!
			    @org.springframework.web.bind.annotation.ExceptionHandler(NullPointerException.class)
			    public String dealException(NullPointerException ex, Model model){
			        String message = ex.getMessage();
			        //1.发送邮件
			        System.out.println("发送邮件");
			        model.addAttribute("ms", "空指针异常!");
			        return "info";
			    }

			    //ArithmeticException

			    @org.springframework.web.bind.annotation.ExceptionHandler(ArithmeticException.class)
			    public String dealException2(ArithmeticException ex, Model model){
			        String message = ex.getMessage();
			        //1.发送邮件
			        System.out.println("发送邮件");
			        model.addAttribute("ms", "除零异常!");
			        return "info";
			    }
			}
			 如果有具体和非具体的异常!具体异常优先!

八:springmvc整合spring框架

如果一个项目中使用了spring框架和springmvc框架,这个项目一定有两个配置文件,就是springioc文件和springmvcIOC容器,而且mvcioc容器是ioc容器的子容器。

springmvc容器可以引用spring的容器的bean,

spring不可以获取mvc的bean(ioc di aop tx jdbc)

各自的角色:

mvc是控制器层的(简化响应,简化接收参数)

springservice层和dao 层(service和dao的ioc容器,aop,tx,spring-jdbc)

各自容器的内容:

springmvc: controller handlermapping handleradapter viewresolver interceptor

default-servlet-handler json转化器 mutilpartfileresovler cors

springioc: service dao adviece tx aop

各自的配置文件

ioc容器: ioc容器初始化的时机: web —> ioc初始化的时机: —>web项目启动(web项目部署到运行中的tomcat服务器中!)

具体初始化点:servlet filter listener

servlet—默认第一次访问,申明 load-on-startup

listener–选择对应的listener类型 servletecontextlistener

filter—默认项目启动时初始化

springmvc初始化点:

dispatcherservlet --> init 声明 load-on-startup 1

值为mvc的配置文件

contextConfigLocation classpath:applicationContext-web.xml

spring框架选择的初始化点: spring选择的初始化点事 listener servletcontextlistener

大致思路: 声明一个全局的变量!

contextConfigLocation classpath:applicationContext.xml

又声明了spring框架提供的contextloaderlistener(servletcontextlistener)在listener.init()进行全局变量contextConfigLocation,拿到spring配置文件进行spring的容器的初始化!

容器结果:

spring的容器: key:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE

springmvc的容器: org.springframework.web.servlet.FrameworkServlet.CONTEXT.servlet-name

九:spring ioc容器和spring MVC容器的关系

试验一:springmvc容器中引用spring容器中的bean

结果:可以引用

实验二:spring中引用springmvc中的bean

Assert():报红;

结果:spring容器无法找到springmvc容器中的bean!

开发中业务是单向调用,除非特殊情况。

controller --> | service – > dao --> jdbcutils --> datasoure

如果service一定要引用controller怎么办?
方案一:在controller和service放到springmvc容器中

结果:夭折spring容器中无法再找到springmvc中的service,因此

aop、tx、无法实现

方案二:在spring容器中引入controller

springmvc只会找到自己容器中的controller,修改springmvc框架中的controller

在handlemapping中:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
             <property name="detectHandlerMethodsInAncestorContexts" value="true" />
         </bean>

十:总结

1.spring+springmvc整合!
2.理解spring+springmvc容器的初始化过程!
3.spring容器和springmvc容器的关系!
4.springmvc框架的执行流程和核心组件以及作用!
5.springmvc涉及的核心注解

Skills:
<!-- use-default-filters = false 下面才生效-->
       <context:component-scan base-package="com.itqf" use-default-filters="false">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
       </context:component-scan>

       <mvc:annotation-driven />

       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
          <property name="prefix" value="/WEB-INF/jsp/" />
          <property name="suffix" value=".jsp" />
       </bean>
ajax获取数据问题
$.ajax({
              url:"${pageContext.request.contextPath}/all",
              //data:"name=张三&money=1100",
              contentType:"application/json;charset=UTF-8",
              data: {name:"张三",money:110},
              type:"GET",
              success:function (data) {
                  alert(data)

                  //注意:如果响应的类型是application/json不需要再进行转换!

                  //data jsonstr
                  //JSON.parse(data);
              }
          })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值