JavaEE之SSM框架——SpringMVC

目录

1.springMVC介绍

2.web请求过程

3. springMVC组件介绍

4.MVC执行过程

4.1Dispatcher介绍

4.2 DispatcherServlet辅助类

5.springMVC搭建

5.1 /和/*的区别

5.2 url-pattern有5种配置模式

6.接参

7.返参

8.session存值

9.弹窗响应

10.转发和重定向

11.异常处理

12.Cookie操作

13.获得头信息

14.RestFul风格

15.静态资源访问

16.Json处理

17.SpringMVC拦截器

18.文件上传下载


1.springMVC介绍

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建

Web 应用程序的全功能 MVC 模块。 使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还

是 Struts 这样的 Web 框架。通过策略接口,Spring 框架是高度可配置的,而且包含多种视图技术,例如

JavaServer Pages(JSP)技术、Velocity、Tiles、iText 和 POI。Spring MVC 框架并不知道使用的视图,所以不会

强迫您只使用 JSP 技术。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它

们更容易进行定制。

mvc架构的应用

webwork,struts1,struts2,springmvc...

2.web请求过程

3. springMVC组件介绍

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

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

等。

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

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

4.MVC执行过程

4.1Dispatcher介绍

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

  1. 文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;

  2. 通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个 HandlerInterceptor拦截器);

  3. 通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);

  4. 通过ViewResolver解析逻辑视图名到具体视图实现;

  5. 本地化解析;

  6. 渲染具体的视图等;

  7. 如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。

4.2 DispatcherServlet辅助类

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

5.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> 

5.1 /和/*的区别

< url-pattern > / </ url-pattern > 不会匹配到.jsp,即:.jsp不会进入spring的 DispatcherServlet类 。

< url-pattern > /* </ url-pattern > 会匹配*.jsp,会出现返回jsp视图时再次进入spring的DispatcherServlet 类,

导致找不到对应的controller所以报404错。

可以配置/ ,此工程 所有请求全部由springmvc解析,此种方式可以实现 RESTful方式,需要特殊处理对静态文件

的解析不能由springmvc解析

可以配置.do或.action,所有请求的url扩展名为.do或.action由springmvc解析,此种方法常用

不可以/,如果配置/,返回jsp也由springmvc解析,这是不对的。

5.2 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="请求名")

(5)测试

6.接参

接收方式:

(1)HttpServletRequest

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

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

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

示例:

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:annotation-driven/> 
public String test1(@DateTimeFormat(pattern = "yyyy-MM-dd")Date birthday){} 

补充:参数类型使用引用数据类型,基本数据类型使用包装类

7.返参

修改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类保存数据

8.session存值

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

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

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

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

示例:

@SessionAttributes("key")

@SessionAttributes({"key1","key2"})

清除注解session:SessionStatus类

status.setComplete();

9.弹窗响应

输出流的问题(返回值必须是void)

@RequestMapping("delete") 
​
public void delete(HttpServletResponse response) throws IOException{ 
​
System.out.println("删除成功"); 
​
response.setContentType("text/html;charset=UTF-8"); 
​
PrintWriter pw=response.getWriter(); 
​
pw.print("<script type='text/javascript'>alert('删除成 
​
功');location.href='MyJsp.jsp'</script>"); 
​
} 

补充:如何设置get请求乱码?tomcat8已经默认配置

post处理乱码

注意:这里只能处理接受后数据的编码,如果是其他位置的编码问题还需要再考虑处理方案

10.转发和重定向

默认转发跳转

@RequestMapping("/forwardView") 
​
public String forwardView(){ 
​
return "forward:/WEB_INF/pages/success.jsp"; 
​
}

重定向:

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

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

11.异常处理

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

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

方法2:

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

全局异常:@ControllerAdvice

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

12.Cookie操作

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

13.获得头信息

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

14.RestFul风格

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

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

GET POST PUT DELETE

它们分别代表着四种基本操作:

- GET用来获取资源

- POST用来创建新资源

- PUT用来更新资源

- DELETE用来删除资源

示例:

order?method=insert&id=1

order?method=delete&id=1

order?method=update&id=1

order?method=select&id=1

- /order/1 HTTP GET :得到id = 1 的 order

- /order/1 HTTP DELETE: 删除 id=1 的order

- /order/1 HTTP PUT : 更新id = 1的 order

- /order/1 HTTP POST : 新增 order

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

Spring中实现RESTful风格

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

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

实现步骤:

(1) web.xml添加HiddenHttpMethodFilter配置

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

(2) 实现查,改,删 框架

@RequestMapping(value = "/list",method = RequestMethod.GET) 

@RequestMapping(value = "/{id}",method = RequestMethod.DELETE) 

@RequestMapping(value = "/{id}",method = RequestMethod.PUT) 

(3) Jsp代码:

<a href="javascript:void(0)" οnclick="deleteById()">删除</a> 

<form action="/order/1" method="post" id="deleteForm"> 

<input type="hidden" name="_method" value="DELETE" /> 

</form> 
<a href="javascript:void(0)" οnclick="updateById()">修改</a> 

<form action="/order/1" method="post" id="updateForm"> 

<input type="hidden" name="_method" value="PUT" /> 

</form> 
<script>
    function updateById() { 

var form = document.getElementById("updateForm"); 

form.submit(); 

}

function deleteById() { 

var form = document.getElementById("deleteForm"); 

form.submit(); 

} 

</script> 

需要注意: 由于doFilterInternal方法只对method为post的表单进行过滤,所以在页面中必须如下设置:

<form action="..." method="post"> 

<input type="hidden" name="_method" value="put" /> 

</form> 

代表post请求,但是HiddenHttpMethodFilter将把本次请求转化成标准的put请求方式! name="_method"固定写法!

(4) controller

@PathVariable获取路径参数

@RequestMapping("/user/list/{id}") 

public String getData(@PathVariable(value = "id") Integer id){ 

System.out.println("id = " + id); 

return "list" ; 

}

其他请求:

@RequestMapping(value = "/order",method = RequestMethod.POST) 

@RequestMapping(value = "/order/{id}",method = RequestMethod.DELETE) 

@RequestMapping(value = "/order/{id}",method = RequestMethod.PUT) 

@RequestMapping(value = "/order",method = RequestMethod.GET) 

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

15.静态资源访问

需要注意一种,DispatcherServlet拦截资源设置成了 / 避免了死循环,但是 / 不拦截jsp资源,但是它会拦截其他静态资

源,例如 html , js , css,image等等, 那么我们在使用jsp内部添加 静态资源就无法成功,所以,我们需要单独处理下静态

资源!

处理方案: 在springmvc的配置文件中添加mvc命名空间下的标签!

##### 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> 

方式2:

<mvc:default-servlet-handler></mvc:default-servlet-handler>

16.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/

17.SpringMVC拦截器

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

preHandle() 拦截器开始

postHandle() 拦截器结束

afterCompletion 最后执行

(2)配置拦截器

拦截所有请求(测试:拦截内容包含jsp吗?)

<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的拦截器(Interceptor)和过滤器(Filter)的区别与联系

一 简介

(1)过滤器:

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

(2)拦截器:

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

二 多个过滤器与拦截器的代码执行顺序

(1)过滤器的运行是依赖于servlet容器的,跟springmvc等框架并没有关系。并且,多个过滤器的执行顺序跟xml文

件中定义的先后关系有关

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

最终顺序:

18.文件上传下载

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

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

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

如果想使用Spring的文件上传功能,则需要先在上下文中配置MultipartResolver。

fifileUpload

文件上传的步骤:

(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

enctype="multipart/form-data" 

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

@RequestMapping("/upload") 

public String saveFile(@RequestParam("name") String name , @RequestParam("file")MultipartFile 

file) throws IOException { 

//接收表单提交的数据,包含文件 

System.out.println("name = " + name); 

String path=request.getRealPath("/"); 

if (!file.isEmpty()) 

{ 

file.transferTo(new File(path+"upload/"+file.getOriginalFilename())); 

} 

return "success"; 

}

文件下载步骤:

(1)添加jar包

<dependency> 

<groupId>commons-io</groupId> 

<artifactId>commons-io</artifactId> 

<version>2.4</version> 

</dependency> 

(2)配置处理类方法

@RequestMapping("down") 

public ResponseEntity<byte[]> test(String imgname,HttpServletRequest request) throws 

IOException{ 

String serverpath= request.getRealPath("/img"); 

serverpath=serverpath+"/"+imgname; 

//创建http头信息的对象 

HttpHeaders header=new HttpHeaders(); 

//标记以流的方式做出响应 

header.setContentType(MediaType.APPLICATION_OCTET_STREAM); 

//设置以弹窗的方式提示用户下载 

//attachment 表示以附件的形式响应给客户端 

header.setContentDispositionFormData("attachment",URLEncoder.encode(imgname,"utf-8")); 

File f=new File(serverpath); 

ResponseEntity<byte[]> resp= 

new ResponseEntity<byte[]> 

(FileUtils.readFileToByteArray(f), header, HttpStatus.CREATED); 

return resp; 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值