为了使Spring可插入MVC架构,SpringFrameWork在Spring基础上开发SpringMVC框架,从而使用Spring进行WEB开发时可以选择使用Spring的SpringMVC框架作为web开发的控制器框架。SpringMVC是轻量级,典型的MVC框架,在整个MVC框架中充当控制器框架。

一、编程步骤

1、引入依赖

spring、spring-mvc(核心依赖)、servlet-api规范

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

2、配置web.xml

DispatchServlet 使用servlet标签 url-pattern /

<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置springmvc.xml的位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

3、引入springmvc.xml配置文件

位置随便、名字随意。推荐使用springmvc.xml并放置在resources目录中

开启注解扫描、处理器映射器、处理器适配器、视图解析器

<!--开启注解扫描-->
<context:component-scan base-package="com.icucoder.controller"/>
<!--配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--配置处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--注入前缀和后缀-->
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>

现在使用下面的:

<!--开启注解扫描-->
<context:component-scan base-package="com.icucoder.controller"/>
<!--配置处理器映射器、适配器 参数类型转换等-->
<mvc:annotation-driven/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--注入前缀和后缀-->
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>

4、开发controller 加入相关注解

@Controller
public class HellorController {
@RequestMapping("/hello")
public String hello() {
System.out.println("hello springmvc");
return "index";
}
}

二、springmvc跳转方式

1、原始servlet技术中的跳转方式

1)forward跳转:请求转发,特点是服务器内部跳转,跳转后地址栏不变,一次跳转,跳转时可以使用request作用域传递数据。

2)redirect跳转:请求重定向,特点是客户端跳转,跳转之后地址栏改变,多次跳转,跳转过程不能使用request作用域传递数据。

2、SpringMVC中跳转方式

1)controller到JSP页面跳转(默认是forward跳转)

(1)forward方式:

具体语法:return "视图逻辑名"

@Controller
public class ForwardAndRedirectController {
//forward跳转到页面
@RequestMapping("/forward")
public String forward(){
return "index";
}
}

(2)redirect方式:

具体语法(使用redirect跳转不会经过视图解析器):return "redirect:视图全名"

@Controller
public class ForwardAndRedirectController {
//redirect跳转到页面
@RequestMapping("/redirect")
public String redirect(){
return "redirect:/index.jsp";
}
}

2)controller到controller直接跳转(相同控制器或者不同控制器)

(1)forward方式:

具体语法:return "forward:跳转Controller类上的@RequestMapping路径/跳转类中指定方法上@RequestMapping路径"

@Controller
@RequestMapping("/forwardAndRedirect")
public class ForwardAndRedirectController {
//forward跳转到页面
@RequestMapping("/test1")
public String test1(){
return "forward:/forwardAndRedirect/test2";
}
@RequestMapping("/test2")
public String test2(){
return "index";
}
}

(2)redirect方式:

具体语法:return "redirect:跳转Controller类上的@RequestMapping路径/跳转类中指定方法上@RequestMapping路径"

@Controller
@RequestMapping("/forwardAndRedirect")
public class ForwardAndRedirectController {
//forward跳转到页面
@RequestMapping("/test1")
public String test1(){
return "redirect:/forwardAndRedirect/test2";
}
@RequestMapping("/test2")
public String test2(){
return "index";
}
}

三、springmvc中参数接收

1、概述

1)语法:使用控制器中方法形参列表接收客户端的请求参数

2)要求:要求传递参数key要与对应方法的形参变量名一致才能完成自动赋值

2、不同类型参数接收

1)零散类型参数接收

方法的参数与路径上的参数保持一致即可。

@Controller
@RequestMapping("/param")
public class ParamController {
//路径:/param/test?name=mayun
@RequestMapping("/test")
public String test(String name) {
System.out.println("接收的参数:" + name);
return "index";
}
}

2)对象类型参数接收

直接将要接收对象作为控制器方法参数声明。springmvc封装对象时直接根据传递参数key与对象中属性名一致自动封装对象。

@Controller
@RequestMapping("/param")
public class ParamController {
//路径:/param/test?id=1&name=mayun&sex=false
@RequestMapping("/test")
public String test(User user) {
System.out.println("接收的参数:" + user);
return "index";
}
}

3)数组或集合类型参数接收

(1)数组:将要接收数组类型直接声明为方法的形参即可

要保证请求参数的多个参数key与声明数组变量名一致,springmvc会自动放入同一个数组中。

@Controller
@RequestMapping("/param")
public class ParamController {
//路径:/param/test?names=mahuateng&names=mayun&names=haubin
@RequestMapping("/test")
public String test(String[] names) {
for (String name : names) {
System.out.println("接收的参数:" + name);
}
return "index";
}
}

(2)集合(list set map):

springmvc不能直接通过形参列表方式接收结合类型参数。如果要接收集合类型的参数必须将集合放入对象中接收。

@Controller
@RequestMapping("/param")
public class ParamController {
//路径:/param/test?lists=mahuateng&lists=mayun&lists=haubin
//lists为User的一个属性 private List<String> lists;
@RequestMapping("/test")
public String test(User user) {
user.getLists().forEach(str -> System.out.println(str));
return "index";
}
}

推荐放入vo对象中接收集合类型。 vo= value object 值对象

四、数据传递机制

1、概述

1)数据怎么存

request(forward)、session(redirect)、application(redirect)、地址栏(redirect)

2)数据在页面如何获取

EL表达式。直接将request/response对象作为控制器方法参数声明即可获取。

3)在页面中获取的数据该如何展示

EL+JSTL标签展示

2、forward传递对象示例

1)使用HttpServletRequest传递对象

controller:

@Controller
@RequestMapping("/attr")
public class AttrController { @RequestMapping("/test")
public String test(HttpServletRequest request, HttpServletResponse response) {
String name = "小城";
request.setAttribute("username", name);
return "index";
}
}

jsp(可以引入JSTL标签):

<%@page contentType="text/html; utf-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<body>
<h2>Hello World Index!</h2>
<h3>
${requestScope.username}
<hr>
${username}
</h3>
</body>
</html>

2)使用Model传递对象

Model底层封装的是request,只能适用于forward跳转。

controller:

@Controller
@RequestMapping("/attr")
public class AttrController { @RequestMapping("/test")
public String test(Model model) {
String name = "小城";
model.addAttribute("username",name);
return "index";
}
}

jsp同上。

3、redirect传递对象示例

1)使用地址栏拼接(适用于数据较少情况)

controller:

@Controller
@RequestMapping("/attr")
public class AttrController { @RequestMapping("/test")
public String test() throws UnsupportedEncodingException {
String name = "小城";
return "redirect:/index.jsp?name="+ URLEncoder.encode(name,"UTF-8");
}
}

jsp:

<%@page contentType="text/html; utf-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<body>
<h2>Hello World Index!</h2>
<h3>
${param.name}
</h3>
</body>
</html>

2)使用session对象

controller:

@Controller
@RequestMapping("/attr")
public class AttrController { @RequestMapping("/test")
public String test(HttpServletRequest request) throws UnsupportedEncodingException {
String name = "小城";
request.getSession().setAttribute("username",name);
return "redirect:/index.jsp?name="+ URLEncoder.encode(name,"UTF-8");
}
}

jsp:

<%@page contentType="text/html; utf-8" pageEncoding="UTF-8" isELIgnored="false" %>
<html>
<body>
<h2>Hello World Index!</h2>
<h3>
${sessionScope.username}
</h3>
</body>
</html>

五、静态资源拦截问题

1、出现静态资源拦截问题的原因

由于在web.xml中配置springmvc的核心servlet DispatcherServlet时,url-pattern配置为“/”,因此会导致项目中所有“/”开头请求,均被作为控制器请求处理,这样会导致项目中的静态资源被拦截。

解决方案:

1)url-pattern配置成“/*.do”或者“/*.action”,使用这种指定后缀方式,后面访问路径的结尾必须加入指定后缀,如:http://127.0.0.1:8080/springmvc/user/findAll.do

2)url-pattern依然配置成“/”,但是在springmvc配置文件中加入如下配置:

<!--默认servlet处理机制-->
<mvc:default-servlet-handler/>

默认servlet处理机制:先找静态资源,找到直接响应,找不到当做控制器处理,还是找不到再报错。

六、文件上传

文件上传指的就是将用户本地计算机中文件通过网络的形式上传到服务器上的过程。

1、springmvc中开发文件上传功能

1)开发一个可以进行文件上传的页面

其中form表单提交方式必须为post,form的enctype属性等于application/x-www-form-urlencoded表示文本,等于multipart/form-data表示二进制。

<h3>文件上传</h3>
<form action="${pageContext.request.contextPath}/file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="开始上传">
</form>

2)开发Controller,其方法的使用MultipartFile来接收文件

@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/")
public String index() {
return "file";
} @RequestMapping("/upload")
public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
System.out.println(file.getOriginalFilename());
//根据相对路径获取绝对路径
String realPath = request.getSession().getServletContext().getRealPath("/file");
file.transferTo(new File(realPath, file.getOriginalFilename()));
return "file";
}
}

3)在springmvc配置文件中加入文件上传解析器配置

要求:文件上传解析器必须存在id,并且必须等于multipartResolver。

<!--文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

4)引入文件上传依赖

<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

2、文件上传细节处理

1)修改文件上传时文件的原始名称

//获取文件后缀
String extension= FilenameUtils.getExtension(file.getOriginalFilename());
//生成新的文件名
String newFileName=UUID.randomUUID().toString()+"."+extension;

2)便于文件管理,按照上传日期对进行上传文件管理

//生成当天日期目录
LocalDate now=LocalDate.now();
File dateDir=new File(realPath,now.toString());
if (!dateDir.exists()){
dateDir.mkdirs();
}
file.transferTo(new File(dateDir, newFileName));

3)解决文件上传文件大小限制

在springmvc中默认上传文件没有大小限制。

<!--文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置文件大小限制 单位B 2M=2097152B-->
<property name="maxUploadSize" value="2097152"/>
</bean>

七、文件下载

用户将服务器中文件下载到自己本地计算机中过程称之为文件下载。

1、springmvc中开发文件下载功能

1)定位哪些文件可以被文件下载

2)将需要下载文件放入指定下载目录中

3)开发一个页面提供文件下载链接(一个请求只能对应一个响应,处理文件下载时方法不能有返回(即跳转页面,因为跳转页面也是一次响应),因为下载是文件响应流)

<h3>文件下载</h3>
<a href="${pageContext.request.contextPath}/file/download?fileName=init">下载</a>

4)开发下载的Controller

@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/")
public String index() {
return "file";
} //请求对应响应输出流
@RequestMapping("/download")
public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
//根据下载相对目录获取下载文件的绝对目录
String realPath = request.getSession().getServletContext().getRealPath("/file");
//通过文件输入流读取文件
FileInputStream is = new FileInputStream(new File(realPath, fileName));
     //文件内容字符编码处理
response.setContentType("text/plain;charset=UTF-8");
//获取响应输出流
ServletOutputStream os = response.getOutputStream();
//附件形式下载 attachment 附件,inline 在线打开
response.setHeader("content-disposition", "attachment;fileName=" + fileName);
//处理下载流复制-传统写法
int len;
byte[] b = new byte[1024];
while (true) {
len = is.read(b);
if (len == -1) break;
os.write(b, 0, len);
}
//释放资源
is.close();
os.close();
}
}

2、文件下载细节处理

1)使用工具类

//处理下载流复制-使用工具类
IOUtils.copy(is,os);
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);

注意:操作流的用IOUtils类,操作文件的用FileUtils类。需要引入commons-fileupload依赖。

2)文件名称为中文处理

response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));

八、springmvc与ajax集成

1、 案例实现思路

1)给页面上的按钮绑定一个单击事件,在单击事件触发时发送异步事件($.ajax、$.get()、$.post()、$.getJSON()

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.6.0.js"></script>
</head>
<body>
<h3>all users info</h3>
<button id="btn">获取所有用户信息</button>
<script>
$(function () {
$("#btn").click(function () {
$.get("${pageContext.request.contextPath}/user/all", function (res) {
console.log(res);
}, "JSON");
});
})
</script>
</body>
</html>

2)在控制器中将对应的数据转为json格式

(1)使用fastjson

@Controller
@RequestMapping("/user")
public class UserController { @Autowired
private UserService userService; @RequestMapping("/all")
public void getUser(HttpServletResponse response) throws IOException {
List<User> users = userService.findAll();
String json_users = JSONObject.toJSONString(users);
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json_users);
}
}

需要引入fastjson相关依赖:

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>

(2)使用springmvc提供的注解@ResponseBody(用在方法或者方法的返回值上,自动转换为json格式字符串并响应到前台)

@Controller
@RequestMapping("/user")
public class UserController { @Autowired
private UserService userService; @RequestMapping("/all")
//@ResponseBody
public @ResponseBody List<User> getUser(HttpServletResponse response) throws IOException {
List<User> users = userService.findAll();
return users;
}
}

底层使用的是jackson,所以需要引入相关依赖:

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

可以使用jackson提供的注解来解决日期格式问题,加在实体类的日期字段上:@JsonFormat(pattern="yyyy-MM-dd")

九、springmvc中拦截器使用

类似于javaweb中的Filter,用来对请求进行拦截,可以将多个Controller中执行的共同代码放入拦截器中执行,减少Controller类中代码的冗余。

特点:拦截器只能拦截Controller的请求,不能拦截jsp、静态资源相关请求;拦截器可中断用户的请求轨迹;请求先经过拦截器,之后还会经过拦截器。

1、开发拦截器步骤

1)实现HandlerInterceptor接口,并实现接口中的方法

  请求经过拦截器会优先进入拦截器中的preHandle方法,执行preHandle方法中的内容;如果preHandle返回为true,代码放行请求(会执行当前请求对应的控制器中的方法,当控制器中的方法执行结束之后,会返回拦截器中,并执行拦截器中postHandle方法,postHandle执行完成之后,会响应请求,同时在响应请求完成后会执行afterCompletion方法),如果返回false,则中断请求。

public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
     //可以在这里面判断用户是否登录
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

2)配置拦截器(在springmvc.xml中)

(1)注册拦截器对象

<!--注册拦截器-->
<bean id="myInterceptor" class="com.icucoder.interceptors.MyInterceptor"/>

(2)配置拦截器拦截的请求路径

<!--配置拦截器-->
<mvc:interceptors>
<!--配置一个拦截器 mvc:mapping代表拦截哪个请求路径 ref代表使用哪个拦截器-->
<mvc:interceptor>
<mvc:mapping path="/user/all"/>
<ref bean="myInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

十、springmvc中全局异常处理

当控制器中某个方法在运行过程中突然发生运行时异常时,为了增加用户体验对于用户不能出现500错误代码,应该给用户良好展示错误界面,全局异常处理就能更好解决这个问题。

1、全局异常处理开发步骤

1)编写一个类实现HandlerExceptionResolver接口

public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv = new ModelAndView();
mv.setViewName("error");
return mv;
}
}

2)在springmvc.xml中配置bean

<bean class="com.icucoder.exception.GlobalExceptionResolver"/>

3)编写全局异常处理jsp:error.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>server error.</h3>
</body>
</html>

4)测试抛出一个运行时异常

@Controller
@RequestMapping("/error")
public class ErrorController {
@RequestMapping("500")
public String error500() {
//测试抛出一个运行时异常
throw new RuntimeException("500");
}
}
 

SpringMVC入门一:基础知识(依赖、注解、文件上传/下载、拦截器、异常处理等)的更多相关文章

  1. 04springMVC结构,mvc模式,spring-mvc流程,spring-mvc的第一个例子,三种handlerMapping,几种控制器,springmvc基于注解的开发,文件上传,拦截器,s

     1. Spring-mvc介绍 1.1市面上流行的框架 Struts2(比较多) Springmvc(比较多而且属于上升的趋势) Struts1(即将被淘汰) 其他 1.2  spring-mv ...

  2. html form一点基础知识,实现文件上传

    form用于提交文件需要修改其entype属性. enctype属性:规定在发送表单数据之前如何对其进行编码. 默认情况,enctype的编码格式是application/x-www-form-url ...

  3. springmvc文件上传和拦截器

    文件上传 用到这两个包 配置视图解析器:springmvc配置文件配置 <!-- id必须要是"multipartResolver" --> <bean id=& ...

  4. 2017/2/12:springMVC的简单文件上传跟拦截器

    1.写文件上传的界面jsp代码如下重点为文件上传标签的类型 2.写登录成功跟失败的界面:成功自己写 3.写springMVC的文件上传的controller的方法 4.最后一步配置spring-ser ...

  5. spring mvc注解文件上传下载

    需要两个包: 包如何导入就不介绍了,前端代码如下(一定要加enctype="multipart/form-data"让服务器知道是文件上传): <form action=&q ...

  6. struts2 基础3 文件上传、拦截器

    文件上传: 1.将头设置为enctype=”multipart/form-data” <form action="${pageContext.request.contextPath } ...

  7. struts2之多文件上传与拦截器(8)

    前台jsp <s:form action="uploadAction" enctype="multipart/form-data" method=&quo ...

  8. Java中实现文件上传下载的三种解决方案

    第一点:Java代码实现文件上传 FormFile file=manform.getFile(); String newfileName = null; String newpathname=null ...

  9. java+大文件上传下载

    文件上传下载,与传统的方式不同,这里能够上传和下载10G以上的文件.而且支持断点续传. 通常情况下,我们在网站上面下载的时候都是单个文件下载,但是在实际的业务场景中,我们经常会遇到客户需要批量下载的场 ...

  10. SpringBoot入门一:基础知识(环境搭建、注解说明、创建对象方法、注入方式、集成jsp/Thymeleaf、logback日志、全局热部署、文件上传/下载、拦截器、自动配置原理等)

    SpringBoot设计目的是用来简化Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,SpringBoot致力于在蓬勃发 ...

随机推荐

  1. 实用的linux 命令

    1. 查看当前文件夹下文件或文件夹所占磁盘的大小 du -sh *|sort -rh 2. 查找某个进程号,脚本或程序所在目录的方法 ll /proc/进程id 3. awk 的用法 (1)累加: a ...

  2. React之redux学习日志(redux/react-redux/redux-saga)

    redux官方中文文档:https://www.redux.org.cn/docs/introduction/CoreConcepts.html react-redux Dome:https://co ...

  3. AtCoder Beginner Contest 238 A - F 题解

    AtCoder Beginner Contest 238 \(A - F\) 题解 A - Exponential or Quadratic 题意 判断 \(2^n > n^2\)是否成立? S ...

  4. elasticsearch查询之大数据集分页查询

    一. 要解决的问题 search命中的记录特别多,使用from+size分页,直接触发了elasticsearch的max_result_window的最大值: { "error" ...

  5. Git使用教程(超全,看一篇就够了)

    目录 Git介绍 Git安装 Git使用 问题与解决 推荐学习网址 Git介绍 Git是什么? Git是目前世界上最先进的分布式版本控制系统. SVN与Git的最主要的区别? SVN是集中式版本控制系 ...

  6. 「CTSC2006」歌唱王国

    概率生成函数\(g(x)=\sum_{i\geq 0}t_ix^i\),\(t_i\)表示结果为\(i\)的概率 令\(f(x)\)表示i位表示串结束时长度为i的概率,\(G(x)\)表示i位表示串长 ...

  7. Hive安装教程

    Hive的安装和使用 我的版本: JAVA_HOME=/usr/local/soft/jdk1.8.0_171 HADOOP_HOME=/usr/local/soft/hadoop-2.7.6 HIV ...

  8. Nodejs ORM框架Sequelize快速入门

    Nodejs ORM框架Sequelize快速入门 什么是ORM? 简单的讲就是对SQL查询语句的封装,让我们可以用OOP的方式操作数据库,优雅的生成安全.可维护的SQL代码.直观上,是一种Model ...

  9. 枚举和注解@override、@Deprecated、@SuppressWarnings

    一.枚举 简介: 1)枚举对应英文(enumeration,简写 enum) 2)枚举是一组常量的集合. 3)可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象. 实现方式: 1.自定 ...

  10. 【AGC035D】Add and Remove(脑洞 DP 分治)

    题目链接 大意 给出\(N\)个数的序列,每次操作可以选择连续的三个数,将中间的那个数抽出,将另外两个数的数值加上中间那个数的数值. 一直执行以上操作直到只剩最后两个数,求最后两个数的所有可能的和的最 ...