服务网点网站建设,xx企业网站建设方案书,网站幻灯片 按纽,惠州网红酒店文章目录 1. SpringMVC概述1.1. 什么是SpringMVC#xff1f;1.1.1. MVC与SpringMVC 1.2. SpringMVC项目的优势 2. SpringMVC项目的创建与使用2.1. 创建SpringMVC项目2.2. 设置路由2.3. 获取参数2.3.1. 获取一个参数2.3.2. 获取多个参数2.3.3. 获取日期参数2.3.4. 参数重命名Re… 文章目录 1. SpringMVC概述1.1. 什么是SpringMVC1.1.1. MVC与SpringMVC 1.2. SpringMVC项目的优势 2. SpringMVC项目的创建与使用2.1. 创建SpringMVC项目2.2. 设置路由2.3. 获取参数2.3.1. 获取一个参数2.3.2. 获取多个参数2.3.3. 获取日期参数2.3.4. 参数重命名RequestParam2.3.5. 获取json字符串2.3.6. 获取URL中的参数2.3.7. 上传文件2.3.8. 获取Cookie2.3.9. 获取Header2.3.10. 存储和获取Session 2.4. 返回数据2.4.1. 返回普通的text文本/静态页面2.4.2. 返回JSON对象2.4.3. 实现请求转发与重定向 1. SpringMVC概述
1.1. 什么是SpringMVC
Spring Web MVC Model View Controller是基于 Servlet API 构建的原始 Web 框架从一开始就包含在 Spring Framework 中。正式名称“Spring Web MVC”来自其源模块的名称spring-webmvc但它通常被称为“Spring MVC”。
1.1.1. MVC与SpringMVC
MVC 是 Model View Controller 的缩写它是软件工程中的一种软件架构模式它把软件系统分为模型、视图和控制器三个基本部分。 Model模型是应用程序中用于处理应用程序数据逻辑的部分通常模型对象负责在数据库中存取数据。 View视图是应用程序中处理数据显示的部分通常视图是依据模型数据创建的是前端客户端的可视的页面。 Controller控制器是应用程序中处理用户交互的部分通常控制器负责从视图读取数据控制用户输入并向模型发送数据。
MVC 执行流程
用户客户端向发送的请求首先到服务器端的 Controller。Controller 将请求继续转发给 Model。Model 处理业务并将数据结果返回给 Controller。Controller 会将数据交给 View 引擎。View 会将数据进行转换渲染生成最终的页面给用户客户端。
MVC与Spring MVC之间的区别 MVC 是一种思想而 Spring MVC 是对 MVC 思想的具体实现。 Spring MVC 是⼀个实现了 MVC 模式并继承了 Servlet API 的 Web 框架当⽤户在浏览器中输⼊了 URL 之后我们的 Spring MVC 项目就可以感知到用户的请求。
1.2. SpringMVC项目的优势
现在绝大部分的 Java 项目都是基于 Spring或 Spring Boot的而 Spring 的核心就是 Spring MVC也就是说 Spring MVC 是 Spring 框架的核心模块而 Spring Boot 是 Spring 的脚手架因此我们可以推断出现在市面上绝大部分的 Java 项目基本上都是 Spring MVC 项目这也是我们要学 Spring MVC 的原因。
学习SpringMVC项目主要学习的是三个功能
连接将用户浏览器和 Java 程序连接起来也就是访问⼀个地址URL能够调用到我们的 Spring 程序。获取参数用户访问的时候会携带⼀些参数数据在程序中要能够获取到这些参数。输出数据执行了业务逻辑之后要把程序执行的结果返回给用户。
2. SpringMVC项目的创建与使用
2.1. 创建SpringMVC项目
首先我们需要新建 SpringBoot 项目。 要注意在添加依赖的时候一定要添加 Web 模块它其实就是 SpringMVC 的依赖。 2.2. 设置路由
设置路由可以实现程序与用户之间的映射路由映射也就是当用户访问某一个 URL 时会将用户的请求对应到程序中的某个类的某个方法中实现浏览器连接程序的作用设置路由可以使用RequestMapping注解实现注意要实现路由访问必须使用 Controller 将对象储存到 Spring 中。
package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;Controller // 让 spring 框架启动时, 加载
ResponseBody // 返回⾮⻚⾯数据
RequestMapping(/user) // 一级路由
Slf4j // 日志框架
public class UserController {RequestMapping(/hi) // 二级路由public String sayHi() {return h1Hi, Spring MVC./h1;}
}其中访问方法所返回数据或页面的 URL 为http://IP:端口号/类上的路由地址/方法上加的路由地址这样就能访问到每个方法所返回的页面或者数据了也可以只在方法上设置路由地址且当类中只有一个方法时类上/方法上也可以不设置路由地址挑一个设置即可此时直接使用一级路由就能直接访问了。
由于历史原因方法返回默认是一个静态页面如果要设置返回一个页面数据需要搭配使用 ResponseBody注解放在类上类里面所有的方法都会默认放回的是页面数据而不是一个静态页面放到方法上生效的只是当前方法。
启动程序我们去浏览器通过访问http://127.0.0.1:8080/user/hi地址观察结果。
RequestMapping默认情况下同时支持 GET 和 POST 等其他请求方式而如果我们想要仅支持一种请求方式需要做一些配置。
我们需要设置 RequestMapping 的method属性为RequestMethod.xxxRequestMethod 其实是一个枚举里面储存了多种的请求方式。
我们这里设置一个 POST 请求。
Controller
ResponseBody
Slf4j
RequestMapping(/user)
public class UserController {RequestMapping(method RequestMethod.POST, value /onlypost)public String func1() {return post;}
}我们使用 postman 构造 GET 与 POST 请求看看能不能进行处理。
首先我们来试一试GET请求 通过抓包可以看到返回给用户的结果是405出错了这就表示该方法是不支持 GET 请求的我们再来试一试POST请求。 构造 POST 请求 返回结果 返回了一个post数据与我们预期相同所以像上面那样进行配置可以使一个方法只支持 GET 或 POST 一种请求格式。
当然还有另外的方法如果只支持 POST 请求我们还可以使用PostMapping注解来实现。
PostMapping(/hello)
public String func2() {return hello;
}同理如果需要只支持 GET 请求我们也可以使用GetMapping注解来进行实现。
2.3. 获取参数
在 MVC 项目中因为 SpringMVC 是基于 Servlet 的所以使用 Servlet 那一套操作也是可以的只不过有点繁琐Spring 中就有了更方便获取参数的方式。
2.3.1. 获取一个参数
假设有一个类User客户端会传一个用户id到后端我们需要返回一个User对象。
package com.example.demo.model;import lombok.Data;Data
public class User {private int id;private String name;private String password;
}根据 id 查询 User 对象这里主要是示范 Spring Web API 的使用就不添加数据库查询了这里直接构造相应 id 的对象返回即可重点是模拟数据的传入与传出。
我们直接在方法中加上一个形参要与前端传入的参数名相同访问路径时就会后会自动根据形参的名字以前端传来参数的 key 进行匹配如果能够对应后端就能成功接收参数。
RequestMapping(/getuserbyid)
public User getUserById(Integer id) {User user new User();user.setId(id);user.setName(张三);user.setPassword(zs12345678);return user;
}我们再通过 postman 来构造一个 id 参数并获取到一个 User 对象。
Spring 会根据响应的返回值决定返回数据的类型比如你返回一个对象或 Map就会返回一个 json 格式的数据你返回一个页面那它返回的就是页面类型的数据。 因为 SpringMVC 是基于 Servlet 的所以 Servlet 中的那一套 API 在这里也适用在MVC中方法中的HttpServletRequest 与 HttpServletResponse 参数默认是隐藏的如果想要使用需要显示地进行声明获取请求参数时需要通过 HttpServeletRequest 对象手动获取我们只声明一个即可相较来看写法上就比较繁琐了。
RequestMapping(/getUserById2)
public User getUserById2(HttpServletRequest request) {User user new User();user.setId(Integer.parseInt(request.getParameter(id)));user.setName(李四);user.setPassword(ls12345678);return user;
}还需要知道默认情况下前端多传或者少传参数都是可以的少传参数的情况下结果就是 null而多传参数并不会被 SpringMVC 读取。
2.3.2. 获取多个参数
我们还可以获取多个参数此时可以给方法设置多个参数也可以设置一个对象参数直接获取多个前端传来的参数。
比如一个登录的逻辑需要用户传来账户名与密码这里就不实现一个登录逻辑了我们直接将获取到的账户名与密码作为响应返回出去。
RequestMapping(/login)
public String login(String name, String password) {return 用户名 name 密码 password;
}我们从前端传入同名的键值对后端就能够自动获取到。 当然我们也可以使用对象来进行接收前端的参数后端会根据 key 与对象中的属性名自动地进行匹配。
RequestMapping(/object)
public String getObject(User user) {return user.toString();
}User 中的属性有 idname 和 password我们直接从前端传递三个对应名称的键值对SpringMVC 会自动进行对象的初始化参数映射。 除此之外我们还可以接收form表单的形式的参数可以使用是 GET/POST 请求方式。
2.3.3. 获取日期参数
使用DateTimeFormat注解完成日期参数格式转换该注解有个pattern的属性值为我们所传递的日期参数的格式即可。
RequestMapping(/dateParam)
public String dateParam(DateTimeFormat(pattern yyyy-MM-dd HH:mm:ss) LocalDateTime updateTime) {return updateTime.toString();
}2.3.4. 参数重命名RequestParam
如果后端方法形参名和与客户端请求参数名不匹配时就会出现参数接收不到的情况这种情况我们可以使用RequestParam来重命名后端的参数值后端参数映射。
其中RequestParam里面的参数为前端传来的参数名字它可以自动匹配到注解所在的形参中。
RequestMapping(/rename)
public String getNameAndPass(RequestParam(name) String username, RequestParam(pass) String password) {return 用户名 username 密码 password;
}还需要注意使用 RequestParam 注解修饰的参数默认情况下参数是必传如果不传或少传就会报 400 请求错误。 这个情况是因为 RequestParam 注解里面还有一个属性required默认情况下值为true这个属性的意思是是否是必须参数所以参数重命名后重命名的参数默认情况下不能缺少如果不想将参数设置成必须但是想重命名那么就需要额外设置required属性值为false。
RequestMapping(/rename)
public String getNameAndPass(RequestParam(name name, required false) String username, RequestParam(name pass, required false) String password) {return 用户名 username 密码 password;
}2.3.5. 获取json字符串
如果我们想要获取 json 格式的参数需要使用RequestBody注解修饰参数声明了这个参数接收 json 数据。
RequestMapping(/object2)
public String getObject2(RequestBody User user) {return user.toString();
}像上面这样我们能够获取到 json 格式的参数了。 但这样设置后就不能接收其他格式的数据了。
2.3.6. 获取URL中的参数
这里所说的从 URL 获取参数并不是获取查询字符串部分的参数而是直接拿 URL 地址中的参数简单来说就是从 URL 中?前面的字段中获取参数这种方式的优点是搜索引擎抓取关键字权重更高有利于提高曝光度且让 URL 更简洁。
获取方法使用特定 URL 格式和在参数前加上注解PathVariable
RequestMapping(/hero/{id}/{name})
public String geuURL(PathVariable Integer id, PathVariable String name) {return id: id name: name;
}我们访问http://127.0.0.1:8080/user/hero/1234/梧桐网页就能够获取到如下内容 其中hero表示二级目录地址后面使用{}的就表示参数。
2.3.7. 上传文件
文件的上传我们需要使用到RequestPart注解和MultipartFile我们写方法形参定义的时候需要一个MultipartFile变量来接收前端传递的文件参数并设置RequestPart的属性来表示接收前端参数的名字。
//上传文件
RequestMapping(/upimg)
public boolean updateImg(RequestPart(img) MultipartFile file) {boolean result false;try {//将图片保存file.transferTo(new File(D:\\image\\yan.jpg));result true;} catch (IOException e) {log.error(图片上传失败! e.getMessage());}return result;
}我们使用 postman 构造一个请求给服务器端发送一个图片我们来看看目标目录下是否得到了我们上传的文件。 目标目录 在上面的代码中是将保存文件的路径写死的了但是在实际开发到上线的过程当中是涉及到至少三个环境的开发测试生产所以保存的文件路径并不会写死而是将保存文件的路径放在配置文件当中然后读取配置环境中的保存图片路径。
还要注意 一次上传文件大小默认是1MB一次请求上传文件大小默认是10MB可以在配置文件中进行修改。
# 设置一次上传文件大小默认是1MB
spring.servlet.multipart.max-file-size100MB
# 设置一次请求上传文件大小默认是10MB
spring.servlet.multipart.max-request-size100MB这里我们来实现一个小案例就是实现一下上传头像的功能那这个功能的实现有如下过程
配置保存的路径并获取设置不会重名的图片名称UUID获取图片格式得到文件的格式将随机 UUID 与图片格式拼接得到完整的图片文件名储存图片
对于不重名文件名的设定我们可以使用 UUIDUUID 可以自动生成一个唯一的标识序列简单理解就是 UUID 可以生成一个全球唯一 id它由MAC 随机种子 加密算法得出。
# 设置文件保存路径
img.pathD:\\image\\
//获取配置文件的保存路径
Value(${img.path})
private String path;RequestMapping(/upload)
public String upLoad(RequestPart(img) MultipartFile file) throws IOException {// 1.生成一个唯一的 idString name UUID.randomUUID().toString().replace(-, );// 2. 得到源文件的后缀名, 和 id 组合成新的文件名name (file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(.)));// 保存文件System.out.println(path);path name;file.transferTo(new File(path));return path;
}2.3.8. 获取Cookie
一般用户是不会传递这种参数的基本上都是浏览器构造发过来的Cookie 和 Session 通常配合使用在登录验证的场景下。
这里同样可以使用 Servlet 那一套 API 获取。
RequestMapping(/servlet)
public void get(HttpServletRequest req, HttpServletResponse resp) {//...
}使用 Servlet 方式获取 Cookie
RequestMapping(/cookie)
public void getCookie(HttpServletRequest req) {//获取请求中全部的 ookieCookie[] cookies req.getCookies();for (Cookie c : cookies) {log.info(CookieKey : c.getName() CookieValue : c.getValue());}
}我们可以在浏览器随便加上一些 Cookie。 此时我们访问http://127.0.0.1:8080/user/cookie来看看控制台是否有输出我们所传的 Cookie。 有记录就说明我们成功获取到了 Cookie。
简洁地获取Cookie使用CookieValue注解所传参数为你需要获取 Cookie 的 key使用该注解修饰一个变量变量里面就会自动获取对应的value值。
RequestMapping(/cookie2)
public String getCookie2(CookieValue(zhangsan) String cookie) {return zhangsan : cookie;
}如果需要多个 Cookie 值就写多个 CookieValue 修饰变量就行。
2.3.9. 获取Header
Header 用的比较多的就是获取用户的浏览器的一些基本信息了。
使用 Servlet 获取 Header
RequestMapping(/getua)
public String getUA(HttpServletRequest req) {return 用户设备信息User-Agent : req.getHeader(User-Agent);
}更简单地获取 Header使用 RequestHeader 注解
和前面使用注解 CookieValue 用法类似也是设置一个 key 来获取对应的 value。
RequestMapping(/getua2)
public String getUA2(RequestHeader(User-Agent) String ua) {return 用户设备信息User-Agent : ua;
}2.3.10. 存储和获取Session
在登录逻辑中我们需要存储 Session 对象这一步存储操作SpringMVC 与 Servlet 操作是一样的获取方式则有两种方式。
存储Session对象
RequestMapping(/setsession)
public boolean setSession(HttpServletRequest req) {boolean result false;//1. 获取SessionHttpSession session req.getSession(true);//2. 设置Session里面的内容session.setAttribute(sunli, sl1213456);result true;return result;
}访问路径当新建一个Session对象后后端会返回一个 Cookie 给前端根据这个 Cookie 下次验证的时候就能自动登录不用再次输入账号密码登录了。 使用 Servlet 获取 Session****
RequestMapping(/getsession)
public String getSession(HttpServletRequest req) {String result ;//1.获取SessionHttpSession session req.getSession(false);//2.验证if (session ! null session.getAttribute(sunli) ! null) {result (String) session.getAttribute(sunli);}return result;
}更加简洁获取 Session使用SessionAttribute 该注解有两个属性value表示需要获取 Session 对象里面内容的 key 值还有一个require表示修饰的参数是否必须一般需要设置为false如果设置成true没有获取到对应的value就会返回一个400的页面。
RequestMapping(/getsession2)
public String getSession2(SessionAttribute(value sunli, required false) String session) {return session;
}2.4. 返回数据
2.4.1. 返回普通的text文本/静态页面
SpringMVC/SpringBoot 默认返回的是视图xxx.html这是历史原因了在方法中返回的数据默认是一个静态页面如果没有找到这个静态页面就会显示404。
Controller
public class TestController {RequestMapping(/sayhi)public String sayHi() {return hello.html;}
}页面访问结果 我们再简单写一个静态页面放入static目录来验证一下是否能够获取到。
访问页面结果 而如果想要返回一个 text 文本数据则需要使用注解ResponseBody修饰对应的方法或者修饰类才能实现。
Controller
ResponseBody
public class TestController {RequestMapping(/sayhi)public String sayHi() {return hello.html;}
}ResponseBody既可以修饰类也可以修饰方法修饰类时类中所有方法都会返回一个非静态页面数据修饰方法时只有被修饰的方法返回的是一个非静态页面的数据返回的值如果是字符会就转换为 text/html如果返回的是对象会转换成 application/json 返回给前端。
组合注解RestController Controller ResponseBody
小案例实现一个加法计数器。
前端页面
!DOCTYPE html
html langen
headmeta charsetUTF-8titlecalc/title
/head
bodyform actioncalch1计算器/h1数字1 input namenum1 typetextbr数字2 input namenum2 typetextbrinput typesubmit value 查看结果 /form
/body
/html后端处理代码返回计算结果
package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
public class CalcController {RequestMapping(/calc)public String calc(Integer num1, Integer num2) {// 非空验证if (num1 null || num2 null) {return h2参数错误!/h2a hrefjavascript:history.go(-1)返回/a;}return h1 (num1num2) /h1;}
}前端输入数据 后端返回结果
2.4.2. 返回JSON对象
要将指定数据构造成 JSON 格式返回直接返回一个HashMapString, Object对象即可SpringMVC会自动处理成 JSON 对象。
RequestMapping(/getjson)
public HashMapString, String method_8() {HashMapString, String map new HashMap();map.put(Java, Java Value);map.put(MySQL, MySQL Value);map.put(Redis, Redis Value);return map;
}小案例实现登录功能。
前端代码如下实现的功能大致是发送含有账号与密码参数的请求等待后端验证是否登录成功给出简单的提示。
!DOCTYPE html
html langen
headmeta charsetUTF-8script srchttps://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js/scripttitlelogin/titlescriptfunction mysub() {let username jQuery(#username).val();let password jQuery(#password).val();jQuery.getJSON(/login,{username:username,password:password},function (result) {if(result.succ200){alert(返回结果result.msg);}else{alert(操作失败请重试。);}});}/script
/head
bodydiv styletext-align: center;h1登录/h1⽤户input idusernamebr密码input idpassword typepasswordbrinput typebutton value 提交 onclickmysub() stylemargin-top: 20px; margin-left: 50px;/div
/body
/html在后端我们首先需要接收账号与密码参数然后对这些参数进行确认为了方便起见我们将账号与密码写死即账号是zhangsan密码是123才能登录成功。
我们返回一个 json 格式的数据给前端里面包含是否登录成功msg状态码succ将这两种参数以键值对的形式储存到哈希表中返回即可。
package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;RestController
public class LoginController {RequestMapping(value /login)public HashMapString, Object login(String username, String password){HashMapString, Object res new HashMap();int succ 200;if(username ! null password ! null username.equals(zhangsan) password.equals(123)){res.put(msg,登录成功);}else{res.put(msg,登录失败);}res.put(succ,succ);return res;}
}实现效果 2.4.3. 实现请求转发与重定向
return 不但可以返回一个视图还可以实现跳转跳转的方式分别为两种
forward请求转发redirect请求重定向
请求转发是服务器端的行为不管几次转发都是只发生服务器端经过多次转发拿到数据后发送给浏览器。
请求转发实现方式1
RequestMapping(/fw)public String myForward() {//转发 html 静态页面return forward:/hello.html;}这种方式其实forward:/是可以省略的因为我们知道默认情况下返回的就是一个静态页面。 转发是发生在服务器内所以浏览器中的路由地址自始至终是不会发生改变的 请求转发实现方式2
RequestMapping(/fw2)
public void myForward2(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.getRequestDispatcher(hello.html).forward(req, resp);
}效果是一样的
请求重定向其实是多次客户端和浏览器的交互是浏览器和服务器共同的行为浏览器发送请求后服务端只是发送一个重定向响应告诉浏览器要继续访问哪个 URL浏览器收到服务器的重定向响应后就会去访问目标地址。
请求重定向的实现方式1 与请求转发类似只不过将forward改为redirect。
RequestMapping(/rd)
public String myRedirect() {return redirect:/hello.html;
}效果图 从rd路径跳转到hello.html页面了重定向浏览器中的路由地址是会发生改变的。 请求重定向的实现方式2
RequestMapping(/rd2)
public void myRedirect2(HttpServletResponse resp) throws IOException {resp.sendRedirect(hello.html);
}效果和上面一样的就不添效果图了。
请求转发forward与请求重定向redirect之间的区别
定义不同请求转发发生在服务端程序内部当服务器端收到一个客户端的请求之后会先将请求转发给目标地址再将目标地址返回的结果转发给客户端请求重定向指的是服务器端接收到客户端的请求之后会给客户端返回了一个临时响应头这个临时响应头中记录了客户端需要再次发送请求重定向的 URL 地址客户端再收到了地址之后会将请求发送到新的地址上。请求方不同请求转发是服务器端的行为是服务器提出请求去获取资源而请求重定向是客户端的行为服务器只是告诉客户端去哪里拿资源实际上是客户端提出请求去获取资源。数据共享不同请求转发是服务器端实现的所以整个执行流程中客户端浏览器只需要发送一次请求因此整个交互过程中使用的都是同一个 Request 请求对象和一个 Response 响应对象所以整个请求过程中请求和返回的数据是共享的而请求重定向客户端发送两次完全不同的请求所以两次请求中的数据是不同的是不共享的。最终URL地址不同请求转发是服务器端代为请求再将结果返回给客户端的所以整个请求的过程中 URL 地址是不变的而请求重定向是服务器端告诉客户端去另外一个地方于是客户端会再次发送一个请求因此客户端最终访问的 URL 会发生变化不是最初的那个URL。代码实现是不同的写法上类似但还是有区别看上面的代码。