框架学习二SpringMVC

SpringMVC

Spring框架提供了构建Web应用程序的全功能MVC模块。使用Spring可插入的MVC架构,可以选择是内置的Spring Web框架还可以是Struts这样的Web框架。通过策略接口,Spring框架是高度可配置的,而且包含多种视图技术,例如JavaServer Pages(JSP)技术、Velocity、Tiles、iText和POI。Spring MVC框架并不知道使用的视图,所以不会强制使用者使用JSP技术。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色。

1.Web请求过程

在这里插入图片描述

2.SpringMVC组件

DispatcherServlet:作为前端控制器,整个流程控制的中心,控制其他组件执行,统一调度,降低组件之间的耦合性,提高每个组件的扩展性。

HandlerMapping:通过扩展处理器映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式

HandlerAdapter:通过扩展处理器适配器,支持更多类型的处理器,调用处理器传递参数等工作

ViewResolver:通过扩展视图解析器,支持更多类型的视图解析,例如:jsp、freemarker、pdf、excel

3.MVC执行过程

先是浏览器发送请求给,DispatcherServlet去HandlerMapping找对应的请求处理器Controller(Servlet),调用Service具体请求处理方法,返回ModelAndView给DispatcherServlet,然后Dispatcher找与返回处理数据匹配的视图映射ViewResolver,将模型数据Model传给View显示

在这里插入图片描述

3.1Dispatcher介绍

DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责:

  1. 文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件解析
  2. 通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器,多个HandlerInterceptor拦截器)
  3. 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器)
  4. 通过ViewResolver解析逻辑视图名到具体试图实现
  5. 本地化解析
  6. 渲染具体的视图
  7. 如果执行过程中遇到异常将交给HandlerExceptionResolver来解析

3.2DispatcherServlet辅助类

spring中的DispatcherServlet使用一些特殊的bean来处理request请求和渲染合适的视图

bean类型说明
Controller处理器/页面控制器,做的是MVC中C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理
HandlerMapping请求到处理器的映射,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerIntercepor拦截器对象);如BeanNameUrlHandlerMapping将URL与Bean名字映射,映射成功的Bean就是此处的处理器
HandlerAdapterHandlerAdapter将会把处理器包装为设配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;如SimpleControllerHandlerAdapter将对实现了Controller接口的Bean进行设配,并且调处理器的handlerRequest方法进行功能处理
HandlerExceptionResolver处理器异常解析器处理器异常解析,可以将异常映射到相应的统一错误界面,从而显示用户友好的界面(而不是给用户看到具体的错误信息)
ViewResolver视图解析器ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;如InternalResourceViewResolver将逻辑视图名映射为jsp视图
LocaleResolver&LocaleContextResolver地区解析器和地区Context解析器解析客户端中使用的地区和时区,用来提供不同的国际化的view视图
ThemeResolver主题解析器,解析web应用中能够使用的主题,比如提供个性化的网页布局
MultipartResolver多部件解析器,主要处理multi-part(多部件)request请求,例如:在HTML表格中处理文件上传
FlashMapManagerFlashMap管理器储存并检索在”input“和”output“的FlashMap中可以在request请求间(通常是通过重定向)传递属性的FlashMap

springMVC搭建

(1)添加jar包

<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>javax.servlet-api</artifactId>
	<version>3.1.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>5.0.8.RELEASE</version>
</dependency>
<dependency>
	<groupId>javax.servlet</groupId>
	<artifactId>jstl</artifactId>
	<version>1.2</version>
</dependency>

(2)修改web.xml

<servlet>
	<servlet-name>springMVC</servlet-name>
	<servlet-class>
		org.springframework.web.servlet.DispatcherServlet
	</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>springMVC</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

1.url-pattern有5种配置模式

​ (1)/xxx:完全匹配/xxx

​ (2)/xxx/*:匹配以/xxx开头的路径,请求中必须包含xxx

​ (3)/*:匹配/下的所有路径,请求可以进入到action或controller,但是转发结果jsp时会再次被拦截,不能访问jsp界面

​ (4).xx:匹配以xx结尾的路径,所有请求必须以.xx结尾,但不会影响访问静态文件。

​ (5)/:默认模式,未被匹配的路径都将映射到servlet,对jpg,js,css等静态文件也将被拦截,不能访问

(3)修改spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:p="http://www.springframework.org/schema/p"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:context="http://www.springframework.org/schema/context"
		xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd"
>
	<!-- 扫描controller-->
	<context:component-scan base-package="com.yhp.controller"/>
	<!-- 视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<!-- jsp所在的位置-->
	<property name="prefix" value="/" />
	<!-- jsp文件的后缀名-->
	<property name="suffix" value=".jsp" />
	</bean>
</beans>

(4)创建控制类

1.@Controller

2.@RequestMapping(”请求地址“)

​ //加在类上:给模块添加根路径

​ //加在方法上:方法具体的路径

  • 设置@RequestMapping method属性

@RequestMapping(method=RequestMethod.GET,value=”请求名“)

4.请求接收参数

接收参数的方式:

(1)HttpServletRequest

(2)页面传值时的key=处理请求的方法的参数名

(3)使用控件名和对象的属性名一致的方式进行接收

方法的参数名和传参的name值不同

//可以设置RequestParam绑定对应值
public String login(@RequestParam(value = "name") String username, String password){}
//可以设置默认值
public String list(@RequestParam(defaultValue = "1") Integer currentPage){}

日期处理

因为springmvc框架默认支持转换得日期格式:yyyy/MM/dd

解决日期问题方式:

  1. 先用String接收日期,再转换:SimpleDataFormate
  2. 使用工具类处理日期

工具类引包

<dependency>
	<groupId>joda-time</groupId>
	<artifactId>joda-time</artifactId>
	<version>2.9.9</version>
</dependency>
//修改配置文件,导入mvc命名空间,添加驱动
<mvc:annotation-driven/>
//添加@DataTimeFormat注解
public String test1(@DateTimeFormat(pattern = "yyyy-MM-dd")Date birthday){}

注意:参数类型使用引用数据类型,基本数据类型使用包装类

5.返参

修改web.xml文件,用来支持jsp操作EL表达式

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  1. HttpServletRequest
  2. ModelMap map,默认作用域request
  3. ModelAndView对象需要new,同时作为返回值类型
  4. Model类保存数据

注意:跳转的方式默认使用的是转发,而不是重定向

6.session存值

(1)使用HttpSession:request.getSession()

(2)使用@sessionAttributes(”key值“)//写的是ModelMap中定义的key值

注意:该注解和ModelMap结合使用,当使用ModelMap存值时,会在session中同时存储一份数据

@SessionAttributes()的小括号如果是一个值,不要加{}

例如:

@SessionAttributes(”key“)

@SessionAttributes({”key1“,”key2“})

清除注解session:SessionStatus类

status.setComplete()

7.弹窗响应

响应流(返回值必须是void)

public void delete(HttpServletResponse response) throws IOException{
	response.setContextType("text/html;charset=UTF-8");
	PrintWriter pw = response.getWriter();
	pw.print("<script>alert('删除成功');location.href="logout.jsp"</script>")
}

注意:如果get请求乱码,tomcat8默认配置utf-8

post乱码处理

  1. 设置jsp页面的编码方式
  2. 设置一个过滤器filter,设置编码方式
<filter>
    <filter-name>myfilter</filter-name>
    <filter-class>
      org.springframework.web.filter.CharacterEncodingFilter
    </filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>myfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8.转发和重定向

默认转发跳转:

@RequestMapping(test)
public String test(){
	return "success";
}

重定向:

return "redirect:success.jsp" 或者:redirect:findall

注意:重定向时地址栏会发生拼接ModelMap中值的问题

9.异常处理

方法1:在web.xml响应状态码配置一个对应页面

<error-page>
	<error>404</error>
	<location>/404.html</location>
</error-page>	

方法2:

@RequestMapping("test")
public String test(){
	String a = null;
	System.out.println(a.charAt(0));
	return "success";
}
//配置异常结果界面
@ExceptionHandler(NullPointerException.class)
public String execptionResult(){
	return "exception";
}

全局异常:@ControllerAdvice注解

使一个Controller成为全局的异常处理类,类中用@ExceptionHandler注解的方法处理所有Controller发生的异常

10.Cookie操作

@CookieValue注解可以获取请求中的cookie
public String testCookie(@CookieValue("JSESSIONID") String cookie){
	System.out.println("cookie:"+cookie);
	return "result";
}

11.获取请求头信息

@RequestHeader
@RequestHeader注解可以获取请求头中的数据!!
public String testHeader(@RequestHeader("User-Agent")String header)

12.RestFul风格

REST:即Representational State Transfer,(资源)表现层状态转化,是一种互联网软件架构

具体说,就是HTTP协议的四个表示操作方式的词

GET、POST、PUT、DELETE

分别代表四种基本操作:

  1. GET用来获取资源
  2. POST用来创建新资源
  3. PUT用来更新资源
  4. Delete用来删除资源

通过修改http的状态值来标记请求

注意:浏览器的form表单只支持GET和POST,不支持DELETE和PUT请求

Spring需要添加一个过滤器,可以将这些请求转换为标准的http方法,支持GET、POST、PUT、DELETE

(1)web.xml添加HiddenHttpMethodFilter配置

<filter>
    <filter-name>methodtest</filter-name>
    <filter-class>
      org.springframework.web.filter.HiddenHttpMethodFilter
    </filter-class>
  </filter>
  <filter-mapping>
    <filter-name>methodtest</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

(2)由于doFilterInternal方法只对method为post的表单进行过滤,所以先设置为post请求,设置隐藏域为真正的方法,HiddenHttpMethodFilter将把本次请求转化为标准的put请求方式,name一定要为”_method“

	<form action="/testrest" method="get">
        <input type="submit" value="get">
    </form>
    <form action="/testrest" method="post">
        <input type="submit" value="post">
    </form>
    <form action="/testrest" method="post">
        <input type="hidden" name="_method" value="put">
        <input type="submit" value="put">
    </form>
    <form action="/testrest" method="post">
        <input type="hidden" name="_method" value="delete">
        <input type="submit" value="delete">
    </form>

(3)controller

@PathVariable获取路径参数

@RequestMapping(value = "/testrest/{var}", method = RequestMethod.GET)
    public String myGet(@PathVariable(value = "var") String name){
        System.out.println("get请求,name="+name);
        return "getsuccess";
    }
    
@RequestMapping(value = "/order",method = RequestMethod.POST)
@RequestMapping(value = "/order/{id}",method = RequestMethod.DELETE)
@RequestMapping(value = "/order/{id}",method = RequestMethod.PUT)

注意:如果访问put和delete请求的时候,报405:method not allowed。处理方式是将过滤器的请求地址改成/,而不是/*

13.静态资源访问

DispatcherServlet拦截资源设置成/,避免了死循环,虽然/不拦截jsp资源,但是它会拦截其他静态资源,例如html,js,css,image等等,那在使用jsp内部添加静态资源就无法成功,所以要单独处理静态资源

处理方法(1):

  1. 修改Spring MVC对应配置文件,添加mvc命名空间和约束

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:mvc="http://www.springframework.org/schema/mvc"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
    		http://www.springframework.org/schema/beans/spring-beans.xsd
    		http://www.springframework.org/schema/context
    		http://www.springframework.org/schema/context/spring-context.xsd
    		http://www.springframework.org/schema/mvc		
    		http://www.springframework.org/schema/mvc/spring-mvc.xsd
    ">
    
  2. 添加处理标签

    <mvc:annotation-driven /> <!--注解驱动-->
    <mvc:resources mapping="/img/**" location="/images/" ></mvc:resources>
    //或者
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
    

    14.Json处理

(1)添加jar包

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.5</version>
</dependency>

注意:maven引入jackson-databind会连带引入core和annotations

非maven项目需要引入这三个包

(2)实现代码:@ResponseBody注解

注意:需要在配置文件添加mvc:annotation-driven

15.SpringMVC拦截器

(1)创建拦截器类:实现HandlerInterceptor接口

preHandler()拦截器开始

postHandler()拦截器结束

afterCompletion()最后执行

(2)配置拦截器

拦截所有请求:

<mvc:interceptors>
	<bean id="my" class="util.MyInterceptor"/>
</mvc:interceptors

拦截指定请求:

<mvc:interceptors>
	<mvc:interceptor >
		<mvc:mapping path="/请求名" />
		<mvc:mapping path="/请求名" />
		<bean id="my" class="util.MyInterceptor"/>
	</mvc:interceptor>
</mvc:interceptors>

springMVC拦截器使用场景

1、日志记录:记录请求信息的日志

2、权限检测,如登录检查

3、性能检测:检测方法的执行时间

springMVC拦截器和过滤器的区别和联系

(1)过滤器

依赖于servlet容器,在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次,使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

(2)拦截器

依赖于web框架,在SpringMVC中就是依赖springMVC框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理

多个过滤器与拦截器的执行顺序:

(1)过滤器的运行是依赖于Servlet容器的,跟springmvc等框架无关,并且多个过滤器的执行顺序跟xml文件中定义的先后顺序有关

(2)对于多个拦截器它们之间的执行顺序跟在springmvc的配置文件中定义的先后顺序有关

在这里插入图片描述

16.文件上传下载

Spring MVC为文件上传提供了直接支持,这种支持是通过即插即用的MultipartResolver实现

Spring使用Jakarta Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver

在SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下不能处理文件上传。

文件上传的步骤

(1)添加jar包

<dependency>
	<groupId>commons-fileupload</groupId>
	<artifactId>commons-fileupload</artifactId>
	<version>1.3.1</version>
</dependency>
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.4</version>
</dependency>

(2)配置MultipartResolver:

<mvc:annotation-driven/>
<bean id="multipartResolver"
	class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
	p:defaultEncoding="UTF-8"
	p:maxUploadSize="5242880"
/>

(3)页面表单,提交方式必须是post

<form action="upload" method="post" enctype="multipart/form-data">
        文件上传:<input type="file" name="myfile">
        <input type="submit" value="上传">
    </form>

(4)配置java代码(注意要创建文件夹保存上传之后的文件)

@RequestMapping("upload")
    public String upload(MultipartFile myfile, HttpServletRequest request){
        //处理文件上传内容
        //1.将上传的文件夹转换成服务器路径
        String realPath = request.getRealPath("/uploadimg");
        System.out.println(realPath);
        //2.得到上传的文件名
        String filename = myfile.getOriginalFilename();
        request.setAttribute("filename",filename);
        //3.上传
        try {
            myfile.transferTo(new File(realPath+"/"+filename));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "uploadsuccess";
    }
方法名称方法解释
byte[] getBytes()获取文件数据
String getContentType()获取文件MIMETYPE类型,如image/jpeg,text/plain等
InputStream getInputStream()获取文件输出流
String getName()获取表单中文件组件的名称name值
String getOriginalFilename()获取文件上传的原名
long getSize()获取文件的字节大小,单位为byte
boolean isEmpty()是否有长传的文件
void transferTo(File dest)可以将上传的文件保存到指定的文件中

文件下载步骤

(1)添加jar包

<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.4</version>
</dependency>

(2)配置处理请求方法

@RequestMapping("download")
    public ResponseEntity<byte[]> down(String filename, HttpServletRequest request) throws Exception{
        //1.转换服务器地址
        String realPath = request.getRealPath("/uploadimg");
        //2.得到要下载的文件路径
        String filePath = realPath+"/"+filename;
        //3.设置响应的头信息
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //4.给用户弹窗的方式进行下载
        //attachment用来表示以附件的形式响应给客户端
        httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(filename,"UTF-8"));
        //5.创建文件
        File file = new File(filePath);
        //6.将文件进行返回
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.CREATED);
        return responseEntity;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值