跟着b站狂神说java的视频写了点笔记,附上链接: https://www.bilibili.com/video/BV19E411v7Ty
1. Spring MVC
1. MVC
- MVC是**模型(Model)、视图(View)、控制器(Controller)**的简写,是一种软件设计规范。
- 是将业务逻辑、数据、显示分离的方法来组织代码。
- MVC主要作用是降低了视图与业务逻辑间的双向偶合。
- MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
- 最典型的MVC就是JSP + servlet + javabean的模式
MVC框架职责
- 将url映射到java类或java类的方法 .
- 封装用户提交的数据 .
- 处理请求–调用相关的业务处理–封装响应数据 .
- 将响应的数据进行渲染 . jsp / html 等表示层数据 .
2. SpringMVC
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。 DispatcherServlet的作用是将请求分发到不同的处理器。
3. 中心控制器
Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。
Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)。
SpringMVC的原理如下图所示:
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
4. SpringMVC执行流程
https://bareth.blog.csdn.net/article/details/108181787
图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
- DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。我们假设请求的url为 : http://localhost:8080/SpringMVC/hello,如上url拆分成三部分:
-
http://localhost:8080服务器域名
-
SpringMVC部署在服务器上的web站点
-
hello表示控制器
-
通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器
-
HandlerMapping为处理器映射。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根据视图解析器解析的视图结果,调用具体的视图。
-
最终视图呈现给用户。
2. SpringMVC程序
1. 配置
-
新建module,添加web支持(右键项目,第二个)
-
导入SpringMVC依赖
-
配置web.xml文件,注册 DispatcherServlet
<?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"> <!--配置DispatcherServlet,这是SpringMVC的核心:请求分发器,或者叫前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatcherServlet要绑定SpringMVC的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
编写SpringMVC 的配置文件,添加处理映射器,添加处理器适配器,添加视图解析器
<!--处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器-->
<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.lqr.controller.HelloController"/>
```
- 编写业务Controller ,要么实现Controller接口,要么增加注解;需要返回一个ModelAndView,装数据,封视图
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
String result = "HelloSpringMVC";
mv.addObject("msg",result);
mv.setViewName("test");
return mv;
}
}
- 将自己的类交给SpringIOC容器,注册bean :
<bean id="/hello" class="com.lqr.controller.HelloController"/>
- 写要跳转的jsp页面,显示ModelandView存放的数据,以及我们的正常页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
-
启动tomcat
-
可能出现404的解决方法:在IDEA项目发布中添加lib依赖
2.注解
重点步骤:
-
配置web.xml,这个东西其实是写死的,只要我们去编写对应的contextConfigLocation配置文件
<?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"> <!--配置DispatcherServlet,这是SpringMVC的核心:请求分发器,或者叫前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--DispatcherServlet要绑定SpringMVC的配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <!--启动级别--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
SpringMVC配置文件,配置Controller和InternalResourceViewResolver
<?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/beans/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/beans/spring-mvc.xsd"> <context:component-scan base-package="com.lqr.controller"/> <!--让springmvc不处理静态资源--> <mvc:default-servlet-handler/> <mvc:annotation-driven/> <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.lqr.controller.HelloController"/> </beans>
-
创建Controller
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; //@Controller让Spring IOC容器初始化时自动扫描到 @Controller public class HelloController { //@RequestMapping是为了映射请求路径 @RequestMapping("/hello") //声明Model类型的参数是为了把Action中的数据带到视图中 public String hello(Model model){ model.addAttribute("msg","mvc"); //方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp return "hello"; } }
-
创建视图层
-
配置Tomcat【注意在artifact中导入lib包】
3.小结
使用springMVC必须配置的三大件:1)处理器映射器,2)处理器适配器,3)视图解析器。 通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置。
3.controller
1.controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义【推荐】两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
2.实现controller接口
实现该接口的类获得控制器功能,处理请求且返回一个模型与视图对象
//实现该接口的类获得控制器功能
public interface Controller {
//处理请求且返回一个模型与视图对象
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
编写完毕后,去Spring配置文件中注册请求的bean;name对应请求路径,class对应处理请求的类
<bean name="/hello" class="com.lqr.controller.helloController"/>
编写前端test.jsp,注意在WEB-INF/jsp目录下编写,对应我们的视图解析器
【总结】:
- 实现接口Controller定义控制器是较老的办法
- 【缺点】:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;
3.使用注解@Controller
- @Controller注解类型用于声明Spring类的实例是一个控制器(在讲IOC时还提到了另外3个注解);
这四个是一致的:
@Component 组件
@Service service层
@Controller 控制层
@Repository dao层
- Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。
<context:component-scan base-package=""/>
- 增加一个ControllerTest类,使用注解实现
//@Controller注解的类会自动添加到Spring上下文中
@Controller
public class {
//映射访问路径
@RequestMapping("/hello2")
public String index(Model model){
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", "ControllerTest");
//返回视图位置
return "test";
}
}
4.@RequestMapping
- @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。
- 可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
同时注解类和方法:
@Controller
@RequestMapping("/folder1")
public class TestController {
@RequestMapping("/folder2")
public String test(){
return "test";
}
}
4.RestFul风格
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
实现举例:
(1)新建一个类
@Controller
public class RestFulController {
}
(2)Spring MVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上
@Controller
public class RestFulController {
//映射访问路径
@RequestMapping("/commit/{p1}/{p2}")
public String index(@PathVariable int p1, @PathVariable int p2, Model model){
int result = p1+p2;
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg", "结果:"+result);
//返回视图位置
return "test";
}
}
(3)测试:localhost:80/commit/1/2
(4)使用method属性指定请求类型: 用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
public String index2(Model model){
model.addAttribute("msg", "hello!");
return "test";
}
(5)测试:
- 使用浏览器地址栏进行访问默认是Get请求,会报错405
- 如果将POST修改为GET则正常了,
@RequestMapping(value = "/hello",method = {RequestMethod.GET})
(6)小结:
- Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。
- 所有的地址栏请求默认都会是 HTTP GET 类型的。
- 方法级别的注解变体有如下几个,也就是组合注解:@GetMapping【使用较多】,@PostMapping,@PutMapping,@DeleteMapping,@PatchMapping
5.数据处理及跳转
1.跳转
(1)方法一,实现Controller:
设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面,其中跳转的页面的表示方式:页面 : {视图解析器前缀} + viewName +{视图解析器后缀}
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
(2)方法二,用HttpServletRequest和HttpServletResponse:
设置ServletAPI , 不需要视图解析器,HttpServletRequest,HttpServletResponse可以直接获取使用,通过HttpServletResponse进行输出,通过HttpServletResponse实现重定向,通过HttpServletResponse实现转发
@Controller
public class ResultGo {
//输出
@RequestMapping("/result/t1")
public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
rsp.getWriter().println("Hello,Spring BY servlet API");
}
//重定向,注意重定向不能访问WEB-INF目录下的文件
@RequestMapping("/result/t2")
public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
rsp.sendRedirect("/index.jsp");
}
//请求转发
@RequestMapping("/result/t3")
public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
//转发
req.setAttribute("msg","/result/t3");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
}
}
(3)方法三,SpringMVC的方式:
通过SpringMVC来实现转发和重定向。(无需视图解析器)
测试前,需要将视图解析器注释掉。语法如下:
转发:forward:/xxx.jsp【forward可省略不写】
重定向:redirect:/xxx.jsp
@Controller
public class ResultSpringMVC {
@RequestMapping("/rsm/t1")
public String test1(){
//转发
return "/index.jsp";
}
@RequestMapping("/rsm/t2")
public String test2(){
//转发二
return "forward:/index.jsp";
}
@RequestMapping("/rsm/t3")
public String test3(){
//重定向
return "redirect:/index.jsp";
}
}
通过SpringMVC来实现转发和重定向(有视图解析器)
重定向是不需要视图解析器的,其本质就是重新请求一个新地方。(注意路径问题,可以重定向到另外一个请求实现)
语法:
转发:直接return
重定向:redirect:/xxx.jsp
@Controller
public class ResultSpringMVC2 {
@RequestMapping("/rsm2/t1")
public String test1(){
//转发
return "test";
}
@RequestMapping("/rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
//return "redirect:hello.do"; //hello.do为另一个请求/
}
}
2.数据处理
(1)提交的域名称和处理方法的参数名一致
(2)提交的域名称和处理方法的参数名不一致
建议都加上@RequestParam,用来表示这是前端传输的数据
//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
System.out.println(name);
return "hello";
}
(3)提交的是一个对象
要求提交的表单域和对象的属性名一致 , 参数使用对象即可
@RequestMapping("/user")
public String user(User user){
System.out.println(user);
return "hello";
}
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null
3.数据显示到前端
第一种 : 通过ModelAndView
第二种 : 通过ModelMap
第三种 : 通过Model
总结:
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
4.乱码问题
(1)web.xml中配置过滤器,用的是springmvc自带的org.springframework.web.filter.CharacterEncodingFilter(对get的支持不好)
<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>
(2)可以修改Tomcat配置文件,直接设置编码
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
(3)或者使用自定义的过滤器,去网上搜
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* 解决get和post请求 全部乱码的过滤器
*/
public class GenericEncodingFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//处理response的字符编码
HttpServletResponse myResponse=(HttpServletResponse) response;
myResponse.setContentType("text/html;charset=UTF-8");
// 转型为与协议相关对象
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
// 对request包装增强
HttpServletRequest myrequest = new MyRequest(httpServletRequest);
chain.doFilter(myrequest, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
//自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
//是否编码的标记
private boolean hasEncode;
//定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
public MyRequest(HttpServletRequest request) {
super(request);// super必须写
this.request = request;
}
// 对需要增强方法 进行覆盖
@Override
public Map getParameterMap() {
// 先获得请求方式
String method = request.getMethod();
if (method.equalsIgnoreCase("post")) {
// post请求
try {
// 处理post乱码
request.setCharacterEncoding("utf-8");
return request.getParameterMap();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else if (method.equalsIgnoreCase("get")) {
// get请求
Map<String, String[]> parameterMap = request.getParameterMap();
if (!hasEncode) { // 确保get手动编码逻辑只运行一次
for (String parameterName : parameterMap.keySet()) {
String[] values = parameterMap.get(parameterName);
if (values != null) {
for (int i = 0; i < values.length; i++) {
try {
// 处理get乱码
values[i] = new String(values[i]
.getBytes("ISO-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
}
hasEncode = true;
}
return parameterMap;
}
return super.getParameterMap();
}
//取一个值
@Override
public String getParameter(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
if (values == null) {
return null;
}
return values[0]; // 取回参数的第一个值
}
//取所有值
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> parameterMap = getParameterMap();
String[] values = parameterMap.get(name);
return values;
}
}
6. SSM框架整合
7. JSON
JSON
(JavaScript Object Notation, JS 对象标记)。在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。
1. JSON 语法规则
键值对
表示对象,数据由逗号分隔花括号
保存对象方括号
保存数组
JSON 键值对 是用来保存 JavaScript 对象的一种方式
- 由
花括号
括起来的逗号
分割的成员构成 - 键值对组合中的键名写在前面并用双引号
""
包裹,使用冒号:
分隔,然后紧接着值
{"name": "lqr","age": "24","sex": "男"}
2. JSON 与 JS 对象的关系
JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
3. JSON 和 JS 对象互转
JSON
就是一个字符串,不能展开JavaScript
是一个对象,可以展开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<script type="text/javascript">
var user = {
name: "lqr",
age: 24,
sex: "男"
};
console.log(user);
//将js对象转换为json对象
var json = JSON.stringify(user);
console.log(json);
//将json对象转换为js对象
var obj = JSON.parse(json);
console.log(obj);
</script>
</body>
</html>
4. 使用Jackson数据交互
Jackson
是一个 Java 的用来处理JSON
格式数据的类库,性能非常好。当然不止这一个类库,比如还有阿里巴巴的fastjson
等等。
Jackons的特征:
- 无需创建映射:JacksonAPI为大多数序列化对象提供了默认映射
SpringMVC配置文件:
<?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.lqr.controller"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!--json乱码问题配置-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>
controller
package com.lqr.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lqr.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author KyrieLuo
* @create 2020/11/17-20:29
*/
//上述我们使用了@ResponseBody注解,他是配合@Controller使用的,该注解可以使不走视图解析器,而是直接返回一个字符串
//同样可以直接将@Controller替换为@RestController,也可以达到不走视图解析器,直接返回字符串的效果,此时就不用使用@ResponseBody注解了
@RestController
public class UserController {
@RequestMapping("/j1")
public String json1() {
//创建一个对象
User user = new User("lqr", 20, "男");
return user.toString();
}
@RequestMapping(value = "/j2",produces = "application/json;charset=utf-8")
public String json2() throws JsonProcessingException {
//创建jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("lqr", 24, "男");
//将对象转换成json格式
String str = mapper.writeValueAsString(user);
//由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
return str;
}
@RequestMapping(value = "/j3")
public String json3() throws JsonProcessingException {
//创建jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建容器
List<User> list = new ArrayList<User>();
//创建多个对象
User user1 = new User("lqr1", 20, "男");
User user2 = new User("lqr2", 20, "男");
User user3 = new User("lqr3", 20, "男");
User user4 = new User("lqr4", 20, "男");
User user5 = new User("lqr5", 20, "男");
//将所有对象存入容器
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
//将对象转换成json格式
String str = mapper.writeValueAsString(list);
//由于@RequestMapping注解,这里会将str转成json格式返回;十分方便
return str;
}
//增加一个新的方法,测试日期对象的输出:默认日期格式会变成一个数字,是1970年1月1日到当前日期的毫秒数,Jackson 默认是会把时间转成timestamps形式
@RequestMapping(value = "/j4")
public String json4() throws JsonProcessingException {
//创建jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建一个日期对象
Date date = new Date();
//将对象转换为json格式
String str = mapper.writeValueAsString(date);
//ObjectMapper对时间解析后的默认格式为:Timestamp(时间戳)
return str;
}
//我们新增一个方法,自定义日期的格式
@RequestMapping(value = "/j5")
public String json5() throws JsonProcessingException {
//创建jackson的对象映射器,用来解析数据
ObjectMapper mapper = new ObjectMapper();
//创建一个日期对象
Date date = new Date();
//自定义日期格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-mm-dd hh:mm:ss");
//将对象转换为json格式
String str = mapper.writeValueAsString(simpleDateFormat.format(date));
return str;
}
}
5. fastjson
fastjson.jar
是阿里开发的一款专门Java处理JSON开发的包
- Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。
- Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
菜鸟教程:https://www.runoob.com/w3cnote/fastjson-intro.html
Fastjson 源码地址:https://github.com/alibaba/fastjson
Fastjson 中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN
三个主要的类
JSONObject:代表 json对象
- JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
- JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
JSONArray:代表 json对象数组
- 内部是有List接口中的方法来完成操作的。
JSON:代表 JSONObject
和 JSONArray
的转化
- JSON类源码分析与使用
- 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。
新建一个方法,利用fastjson的方法返回json字符串:
@RequestMapping(value = "/j6")
public String json6() throws JsonProcessingException {
//创建容器
List<User> list = new ArrayList<User>();
//创建多个对象
User user1 = new User("lqr1", 20, "男");
User user2 = new User("lqr2", 20, "男");
//将所有对象存入容器
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
return JSON.toJSONString(list);
}
8. Ajax
html+css+js(熟练)
js:
- 函数:闭包
- DOM
- id name tag
- create remove
- BOM
- window
- document
- ES6
1. 简介
- AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
- AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
- 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网页。
- 使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。
json
是Ajax发送小部分数据的一种轻量级数据格式,可以简单易懂的给服务器或者浏览器交互数据,包括json对象,json数组对象。
Ajax的核心是XMLHttpRequest对象(XHR)。 XHR为向服务器发送请求和解析服务器响应提供了接口。能够以异步方式从服务器获取新数据。
XMLHttpRequest
简称XHR
,用于在后台与服务器交换数据。XHR
为向服务器发送请求和解析服务器响应提供了接口,能够以异步方式从服务器获取新数据。
2. jQuery.ajax
jQuery
是一个 JavaScript 库, 提供多个与AJAX
有关的方法。通过 jQuery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON,同时您能够把这些外部数据直接载入网页的被选元素中。jQuery Ajax本质就是XMLHttpRequest
,对其进行了封装,方便调用
参数
jQuery.ajax(...)
url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端可接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
格式
$.ajax({
type:'POST',
url:'发送请求的地址',
dataType:'服务器返回的数据类型',
data:{key/value},
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
$.ajax({
type:'GET',
url:'发送请求的地址?数据名'+=数据内容[+"&数据名"+数据内容+...],
dataType:'服务器返回的数据类型',
success:function(data){
//请求成功函数内容
},
error:function(jqXHR){
//请求失败函数内容
}
});
3. 失去焦点函数demo
实现原理很简单,通过onblur
属性绑定当失去焦点事件,失去焦点时,调用a1()
函数,使用jquery的post()
方法发起一个post请求
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
<script>
function a1() {
$.post({
url:"${pageContext.request.contextPath}/a1",
data:{"name":$("#name").val()},
success:function (data,status) {
// alert(data);
// alert(status);
console.log(data);
console.log(status);
}
})
}
</script>
</head>
<body>
用户名:<input type="text" id="name" οnblur="a1()"/>
</body>
</html>
controller
@RestController
public class AjaxController {
@RequestMapping("/test")
public String test() {
return "test";
}
@RequestMapping("/a1")
public void ajax1(String name , HttpServletResponse response) throws IOException {
if ("admin".equals(name)){
response.getWriter().print("true");
}else{
response.getWriter().print("false");
}
}
}
当我们点击输入框,不输入内容,再点击外部任意处时,失去焦点发起请求,服务器响应后,再经回调函数处理,控制台打印了相关信息:
- data:输入框的内容不是
admin
,后端返回false
- status:成功执行请求响应,所以打印
success
4. 过程总结
Ajax把主动权交给了前端