Gitee仓库:狂神-SpringMVC: 学习狂神的课程,练习项目 - Gitee.com
一、MVC框架的历史
1、什么是MVC
- MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
- 是将业务逻辑,数据、显示分离的方法来组织代码。
- MVC主要作用是降低了视图与业务逻辑间的双向耦合。
- MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
最经典的MVC就是JSP + Servlet + javabean的模式。
- Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
- View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
- Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责表示。也就是说控制器做了调度员的工作。
2、model时代
Model1时代
- 在web早期的开发中,通常采用的都是Model1.
- Model1中,主要分为两层,视图层和模型层。
- Model1 优点:架构简单,比较适合小型项目开发;
- Model1 缺点:JSP职责不单一,职责过重,不便于维护;
Model2时代
Model2把一个项目分成三部分,包括 视图、控制、模型
- 用户发请求
- Servlet接收请求数据,并调用对应的业务逻辑方法
- 业务处理完毕,返回更新后的数据给Servlet
- Servlet转向到JSP,由JSP来渲染页面
Model2这样不仅提高的代码的复用率与项目的扩展性,且大大降低了项目的维护成本。
Model1模式的实现比较简单,适用于快速开发小规模项目,Model中JSP页面身兼View和Controller两种角色,将控制逻辑和表现逻辑混杂在一起,从而导致代码的重用性非常低,增加了应用的扩展性和维护的难度,Model2消除了Model1的缺点。
MVC框架要做哪些事情?
- 将url映射到java类或java类的方法
- 封装用户提交的数据
- 处理请求-- 调用相关的业务处理–封装响应数据
- 将响应的数据进行渲染,jsp/html等表示层数据
常见的服务器端MVC框架有
Struts、Spring MVC、 ASP.NET MVC、 Zend Framework、JSF;常见前端MVC框架:vue、angularjs、react、backbone;由MVC演化出了另外一些模式,如:MVP、MVVM等等……
面试:你的项目架构,是设计好的,还是演进的
- alibaba -> PHP
- 随着用户变多 -> java
- 王坚 -> 去IOE -> MYSQL
- MYSQL -> AliSQL -> AliRedis
- All in one -> 微服务
二、SpringMVC
1 、什么是 Spring MVC?
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
分析源码,看到DispatcherServlet继承了HttpServlet。
内部有对request、response的前置处理,后置处理。
2、为什么要学习Spring MVC?
Spring MVC的特点:
- 轻量级,简单易学
- 高效,基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简介灵活
最重要一点还是用的人多,使用得公司多,接触得项目基本都用到了。
Spring的web框架围绕DispatcherServlet[调度Servlet]设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解形式进行开发,十分简洁;
3、DispatcherServlet
Spring MVC框架像许多其它MVC框架一样,以请求为驱动,围绕一个中心Servlet分派请求及提供其它功能,DispatcherServlet是一个实际的Servlet(它继承自HttpServlet基类)。
SpringMVC的原理如下图所示:
4、SpringMVC执行原理
注: 图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
简要分析执行流程
- DispatcherServlet表示前置器是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
– 我们假设请求的url为:http://localhost:8080/SpringMVC/hello
– 如上url拆分成三部分:
– http://localhost:8080服务器域名
– SpringMVC部署在服务器上的web站点
– hello表示控制器
– 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。 - HandleMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler.
- HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello.
- HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
- HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
- Handler让具体的Controller执行。
- Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
- HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
- DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
- 视图解析器将解析的逻辑视图名传给DispatcherServlet。
- DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
- 最终视图呈现给用户。
三、编写SpringMVC的项目
首先在父项目导入依赖
<dependencies>
<!-- webmvc依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.10</version>
</dependency>
<!-- servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
</dependency>
<!-- jstl依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- 一键生成插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<!-- 单元测试,打印日志 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
1、配置版
首先创建maven项目,然后添加项目支持
选择WebApp的4.0版本
项目结构
配置Project Structure,否则会识别不出web项目结构,报500can not find springmvc-servlet.xml
报错页面
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注册DispatcherServlet-->
<!--配置DispatchServlet:这个是SpringMVC的核心,请求分发器,前端控制器-->
<servlet>
<servlet-name>springmvc1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet要绑定Spring(SpringMVC)的配置文件,如果配置文件xxx-servlet在默认配置文件下即WEB-INF下就尽量不要配了,
配置反而会出错-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc1-servlet.xml</param-value>
</init-param>
<!--启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 在SpringMVC中, / /* -->
<!-- / 匹配所有的请求;(不包括.jsp)-->
<!-- /* 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>springmvc1</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springMVC1-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--处理映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<bean id="/hello" class="com.kuang.controller.HelloController"/>
</beans>
HelloController.java
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 创建返回对象
ModelAndView modelAndView = new ModelAndView();
// 放入参数
modelAndView.addObject("msg", "hello Controller");
// 设置跳转的页面 /WEB-INF/jsp/hello.jsp
modelAndView.setViewName("hello");
return modelAndView;
}
}
防止启动项目报错404,导入jar包到项目内
启动项目测试
2、注解版
只有列出来的2个文件和配置版有不同。
项目结构
springmvc2-servlet.xml
<?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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.kuang.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler/>
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven/>
<!-- 视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
HelloController.java
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(Model model) {
model.addAttribute("msg", "hello Controller");
return "hello";
}
启动项目测试
小结
实现步骤其实非常的简单:
- 新建一个web项目
- 导入相关jar包
- 编写web.xml , 注册DispatcherServlet
- 编写springmvc配置文件
- 接下来就是去创建对应的控制类 , controller
- 最后完善前端视图和controller之间的对应
- 测试运行调试.
四、Restful风格
1、什么是Restful
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
2、RestFul的功能
- 资源:互联网所有的事物都可以被抽象为资源
- 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。
传统方式操作资源 :
通过不同的参数来实现不同的效果!方法单一,post 和 get
http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
使用RESTful操作资源 :
可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE
编写项目测试
RestfulController.java
// @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上。PathVariable:路径变量
@RequestMapping(value = "/restful1/{a}/{b}")
public String restful1(@PathVariable int a, @PathVariable int b, Model model) {
int result = a + b;
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", "result = " + result);
//返回视图位置
return "hello";
}
// 使用method属性指定请求类型
@RequestMapping(value = "/restful2/{a}/{b}", method = RequestMethod.POST)
public String restful2(@PathVariable int a, @PathVariable int b, Model model) {
int result = a + b;
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", "result = " + result);
//返回视图位置
return "hello";
}
思考:使用路径变量的好处?
- 使路径变得更加简洁;
- 获得参数更加方便,框架会自动进行类型转换。
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/hello/1/a,则路径与方法不匹配,而不会是参数转换失败。👇🏾👇🏾
方法级别的注解变体有如下几个:组合注解
@GetMapping = @RequestMapping(method =RequestMethod.GET)
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
五、重定向和转发
servlet本身具有转发和重定向,springMVC对他做了封装
1、通过SpringMVC来实现转发和重定向 - 无需视图解析器
视图解析器,默认就是转发,所以要把他注释掉
@RequestMapping("/redirect1")
public String redirect1(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
System.out.println(session.getId());
// return "hello";
// 转发方式一
// return "/WEB-INF/jsp/hello.jsp";
// 转发方式二
return "forward:/WEB-INF/jsp/hello.jsp";
// 重定向
// return "redirect:/index.jsp";
}
2、通过SpringMVC来实现转发和重定向 - 有视图解析器
- 重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.
- 可以重定向到另外一个请求实现 .
@RequestMapping("/redirect2")
public String redirect2(Model model) {
model.addAttribute("msg", "hello Controller");
// return "hello";
// 重定向
return "redirect:/index.jsp";
}
六、请求和响应的数据处理
1、处理提交数据
提交的域名称和处理方法的参数名一致
// http://localhost:8080/springmvc3_restful/user/test1?name=Daniel
@RequestMapping("/test1")
public String test1(Model model, String name) {
// 1.接收前端传过来的数据
System.out.println("前端传过来的数据" + name);
// 2.将返回的结果传递给前端
model.addAttribute("msg", name);
// 3.视图跳转
return "hello";
}
提交的域名称和处理方法的参数名不一致
// http://localhost:8080/springmvc3_restful/user/test2?username=Daniel
@RequestMapping("/test2")
public String test2(Model model, @RequestParam("username") String name) {
// 1.接收前端传过来的数据
System.out.println("前端传过来的数据" + name);
// 2.将返回的结果传递给前端
model.addAttribute("msg", name);
// 3.视图跳转
return "hello";
}
提交的是一个对象
// http://localhost:8080/springmvc3_restful/user/test3?name=Daniel&age=18
@RequestMapping("/test3")
public String test3(Model model, User user) {
// 1.接收前端传过来的数据
System.out.println("前端传过来的数据" + user.toString());
// 2.将返回的结果传递给前端
model.addAttribute("msg", user.toString());
// 3.视图跳转
return "hello";
}
启动项目运行
2、数据显示到前端
第一种 : 通过ModelAndView
@RequestMapping("/t1")
public ModelAndView test1(ModelAndView model) {
model.addObject("msg", "Jenny311");
model.setViewName("hello");
return model;
}
第二种 : 通过ModelMap
@RequestMapping("/t2")
public String test2(ModelMap model) {
model.addAttribute("msg", "Jenny311");
return "hello";
}
第三种 : 通过Model
@RequestMapping("/t3")
public String test3(Model model) {
model.addAttribute("msg", "Jenny311");
return "hello";
}
总结对比:
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
七、JSON
1、什么是JSON
在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
jsonTest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--编写一个javascript对象-->
<script type="text/javascript">
const user = {
"name":"sly",
"age":"55"
};
console.log(user);
console.log("转成字符串");
const stringify = JSON.stringify(user);
console.log(stringify);
console.log("转成JSON对象");
const parse = JSON.parse(stringify);
console.log(parse);
</script>
</body>
</html>
启动项目
2、Jackson
导入依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
项目结构
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvc4</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc4-json.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc4</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
</web-app>
JacksonController.java
package com.kuang.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kuang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
// 相当于@Controller + @ResponseBody
@RestController
public class JacksonController {
// 不走视图解析器,直接返回(字符串)
@ResponseBody
// 防止乱码
@RequestMapping(value = "/jackson1", produces = "application/json;charset=utf-8")
public String jackson1() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(12, "安卓", "男");
return objectMapper.writeValueAsString(user);
}
@RequestMapping("/jackson2")
public String jackson2() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
// 测试集合的输出
List<User> userList = new ArrayList<>();
User user = new User(12, "安卓", "男");
User user2 = new User(12, "安卓", "男");
userList.add( user);
userList.add( user2);
return objectMapper.writeValueAsString(userList);
}
@RequestMapping("/jackson3")
public String jackson3() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
// 测试集合的输出
Date date = new Date();
return objectMapper.writeValueAsString(date);
}
}
启动项目测试
输出集合
输出日期格式
Jackson 默认是会把时间转成timestamps(时间戳)形式
3、Fastjson
fastjson.jar是 阿里 开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。
导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.10</version>
</dependency>
fastjson 三个主要的类:
(1) JSONObject 代表 json 对象
- JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
- JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
(2) JSONArray 代表 json 对象数组
- 内部是有List接口中的方法来完成操作的。
- JSON代表 JSONObject和JSONArray的转化
(3) JSON类源码分析与使用
仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。
FastJsonController.java
package com.kuang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kuang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class FastjsonController {
@RequestMapping("/fastJson")
public String fastJson() {
//创建对象
User user1 = new User("安卓1", 12, "男1");
User user2 = new User("安卓2", 12, "男2");
User user3 = new User("安卓3", 12, "男3");
User user4 = new User("安卓4", 12, "男4");
List<User> list = new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
String fast = JSON.toJSONString(list);
System.out.println("*******Java对象 转 JSON字符串*******");
String str1 = JSON.toJSONString(list);
System.out.println("JSON.toJSONString(list)==>" + str1);
String str2 = JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)==>" + str2);
System.out.println("\n****** JSON字符串 转 Java对象*******");
User jp_user1 = JSON.parseObject(str2, User.class);
System.out.println("JSON.parseObject(str2,User.class)==>" + jp_user1);
System.out.println("\n****** Java对象 转 JSON对象 ******");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject) JSON.toJSON(user2)==>" + jsonObject1.getString("name"));
System.out.println("\n****** JSON对象 转 Java对象 ******");
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>" + to_java_user);
return fast;
}
}
启动项目
八、Ajax
1、什么是Ajax
同步与异步区别
局部更新
资源跳转方式: 请求转发 重定向 (整体更新)
应用场景:
- 购物时需要对商品的数量和白条进行局部更新
- 内容自动补全
- 用户登录失败的提示信息
JS原生的异步无刷新方法
项目结构
normalTest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe测试体验无数新页面</title>
<script>
function go() {
var url = document.getElementById("url").value;
document.getElementById("iframe1").src=url;
}
</script>
</head>
<body>
<!--编写一个javascript对象-->
<div>
<p>请输入地址:</p>
<p>
<input type="text" value="https://www.baidu.com" id="url">
<input type="button" value="提交" onclick="go()">
</p>
</div>
<div>
<iframe id="iframe1" style="width: 100%;height: 500px"/>
</div>
</body>
</html>
启动项目测试
2、Ajax的实现方式
JS的ajax
- 出现最早。
- 使用一个核心对象XmlHttpRequest。
- 专门用于进行ajax请求发送,和响应的接收
缺点
- 若使用JS的AJAX技术,为了实现简单功能,就需要书写大量复杂代码。(滑动的效果)
- JS的AJAX代码,浏览器兼容性比较差。
JQuery的ajax
- 底层封装了JS的ajax代码,做了浏览器的兼容性。
- 程序员仅需要调用简单的JQ的AJAX方法,就可以实现复杂的AJAX功能。
- 少量代码,实现复杂功能,浏览器兼容性好,一处编写,处处执行
3、JQuery的Ajax的介绍
jquery是一个优秀的js框架,自然对js原生的ajax进行了封装,封装后的ajax的操作方法更简洁,功能更强大,与ajax操作相关的jquery方法有如下几种,但开发中经常使用的有三种:
其中,参数说明如下:
url : 请求路径。 向某个路径发送请求。
data : 发送请求时的参数列表。
写法格式 : {“属性名1”:”属性值1” , ”属性名2”:”属性值2”}
callback : 响应成功之后调用函数, 称为回调函数。
ajax局部刷新发生在回调函数中。
该回调函数仅在响应成功并且响应状态码200时,才会调用
Function(data){
Alert(data)
}
type : 设置响应体的类型。(要求,服务器不设置响应体类型)【可以忽略】
type默认值:html
type常用值:text、html、json
JQuery的源码,中的Ajax方法描述
如需复杂的ajax参数设置请使用$.ajax
jQuery.ajax({[settings]})
其中,settings是一个js字面量形式的对象,格式是{name:value,name:value }
常用的name属性名如下:
4、Ajax项目实战
JS技术核心,实际就是在操作这两个对象
ES6新加了几个对象,ES7、8改动很少
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="${pageContext.request.contextPath}/statics/jquery-3.4.1.js"></script>
<!--编写一个javascript对象-->
<script>
function a() {
$.post(
{
url: "${pageContext.request.contextPath}/ajax1",
data: {"name": $("#username").val()},
success: function (data) {
alert(data);
console.log(data);
console.log(status);
},
error: function () {
alert(data);
console.log(data);
console.log(status);
}
}
)
}
</script>
</head>
<body>
用户名:<input type="text" id="username" onblur="a()"/><br>
</body>
</html>
AjaxController.java
@Controller
public class AjaxController {
@RequestMapping("/ajax1")
public void ajax1(String name, HttpServletResponse response) throws IOException {
System.out.println("调用成功" + name);
response.getWriter().println("true");
}
}
启动项目测试
查看控制台
九、登陆验证、拦截器
过滤器与拦截器的区别
拦截器是AOP思想的具体实现
项目结构
MyInterceptor.java
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("===========处理前===========");
// true:放行,执行下一个拦截器
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("===========处理后===========");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("===========清理===========");
}
}
springmvc7-interceptor.xml
<?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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.kuang.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!-- 视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 拦截器配置 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 两个星代表所有东西 -->
<mvc:mapping path="/**"/>
<bean class="com.kuang.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
TestController.java
@Controller
public class TestController {
@RequestMapping("/test1")
public void test1() {
System.out.println("我是test1");
}
}
启动项目测试