un1queyan

  • 主页
  • 随笔
  • 归档
所有文章 友链 关于我

un1queyan

  • 主页
  • 随笔
  • 归档

springMVC框架


阅读数: 次    2021-06-22

springMVC框架

一、spring-web

1、spring框架开发Java项目

spring容器只需要初始化一次即可。

这样我们就写一个工具类。

1
2
3
4
5
6
7
8
9
10
11
12
public class SpringUtil {

private static ApplicationContext context;

static {
context=new ClassPathXmlApplicationContext("classpath:spring.xml");
}

public static <T> T getBean(Class cls){
return (T)context.getBean(cls);
}
}

2、spring框架开发web项目

我们也可以使用工具类来初始化spring容器。

我们也可以将spring容器的初始化工作交给tomcat完成。

编写一个servletContextListener:

在Tomcat创建servlet上下文对象时,来初始化spring容器,然后将spring容器绑定到servlet上下文中。

spring框架已经完成这个操作,只需要导入spring-web依赖。

在web.xml中配置这个监听器和spring的配置文件的位置。

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
<!--  初始化spring容器-->
<!-- 配置spring文件路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring.xml</param-value>
</context-param>
<!-- 配置servlet上下文监听器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

3、tomcat接受请求

tomcat接受请求,只会去servlet容器中查找对应的servlet对象。

如果将servet放到spring容器中托管,tomcat不会去spring容器中查找。

解决:springMVC

springMVC前端控制器

4、父子容器

spring父容器:托管service、dao==

springMVC子容器:必须托管controller

子容器可以依赖父容器中的bean,父容器不能依赖子容器的bean。

ssm框架:所有bean都可以交给子容器托管,无需父容器。

ssh框架:dao层只能托管给父容器。

controller必须托管给springMvc子容器。

原因:dispacherServlet是springMvc提供的,只能转发请求给springMvc的controller。

二、springMVC

1、JavaEe的MVC开发模型

控制层Controller:使用servlet接受请求。

模型层model:使用javabean(service、dao、实体类、工具类)处理请求。

视图层view:使用jsp或html进行页面展示。

image-20210923092243214

2、springMVC

(1)springMVC框架是spring框架的一个子框架。

使用时,必须先导入spring的依赖。

(2)它是一个MVC的框架。

image-20210923093727954

三、springMVC框架的搭建

1、导入spring框架的依赖

2、导入springMVC框架的依赖

1
2
3
4
5
6
<!--    导入springMvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>

通过依赖传递,自动下载和导入spring的jar包。

3、在web.xml中配置springMVC提供的前端控制器(核心控制器)DispatcherServlet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--  配置前端控制器-->
<!-- 1、初始化springMVC子容器-->
<!-- 2、转发请求-->
<!-- 3、响应视图-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 默认的名字:dispatcher-servlet.xml-->
<!-- 如果不是默认的名字,需要如下配置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc.xml</param-value>
</init-param>

<!-- tomcat启动时就初始化DispatcherServlet-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

url-pattern:

1
*.do 或者 *.action
1
/     非jsp的请求(controller和静态资源的请求),推荐
1
2
/*    所有请求
/abc/* 根目录下的abc目录下的所有请求

4、springMVC配置文件

默认名字:【servlet-name】-servlet.xml

如果不使用默认名称,需要在web.xml中作出配置说明。

比如:springmvc.xml

1
2
3
4
5
6
<?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">

</beans>

四、HelloWorld编写

1、编写controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.yan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloWorldController {

// http://localhost:8080/mvc/hello
@RequestMapping("/mvc/hello")
public String hello(){
System.out.println("hello,world!");

// 前后端不分离的开发:返回的是视图
// 前后端分离的开发:返回的是数据(json)
return "/hello.jsp";
}
}

@Component:bean实例化注解

​ @Controller

 @Service

​ @Repository

@RequestMapping(“url”) : 请求映射url

​ @GetMapping

​ @PostMapping

​ @PutMapping

​ @DeleteMapping

2、注解扫描

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">

<!-- 注解扫描-->
<context:component-scan base-package="com.yan"></context:component-scan>

</beans>

3、创建视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/23
Time: 10:32
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

你好,世界!

</body>
</html>

4、测试

将项目部署到tomcat下,启动。

image-20210923103747807

image-20210923103808095

5、简单分析执行流程

(1)浏览器发送请求

(2)tomcat接受请求

(3)tomcat将请求交给dispacherServlet

(4)dispacherServlet将请求转发给HelloWorldController

(5)执行请求映射的方法,HelloWorldController中的hello方法

(6)HelloWorldController返回视图

(7)将视图交给视图解析器

(8)视图解析器返回渲染后的视图

(9)dispacherServlet将渲染后的视图返回给tomcat

(10)tomcat将视图响应给浏览器

五、接受请求参数

1、简单类型的请求参数

(1)请求参数和方法的形参同名:自动传参

1
2
3
4
5
6
7
@RequestMapping("/mvc/login")
public String login(String username,String passwd){
System.out.println(username);
System.out.println(passwd);

return "/index.jsp";
}

(2)请求参数和方法的形参不同名:自动传参

需要手动映射

1
2
3
4
5
6
7
@RequestMapping("/mvc/login")
public String login(@RequestParam(value = "username") String un, @RequestParam(value = "passwd") String pw){
System.out.println(un);
System.out.println(pw);

return "/index.jsp";
}

2、实体对象接收

对象的属性要和请求参数的名字一致;

如果不一致,需要手动映射。

(1)编写User类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.yan.domain;

public class User {
private int uid;
private String username;
private String passwd;
private String name;
private String tel;

public int getUid() {
return uid;
}

public void setUid(int uid) {
this.uid = uid;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPasswd() {
return passwd;
}

public void setPasswd(String passwd) {
this.passwd = passwd;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}
}

(2)编写接受请求的方法

1
2
3
4
5
6
7
@RequestMapping("/mvc/login")
public String login(User user){
System.out.println(user.getUsername());
System.out.println(user.getPasswd());

return "/index.jsp";
}

3、使用ServletAPI接收请求参数

(1)导入servlet依赖

1
2
3
4
5
6
7
<!--    servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>

(2)编写controller

1
2
3
4
5
6
7
8
9
@RequestMapping("/mvc/login")
public String login(HttpServletRequest request){
String username = request.getParameter("username");
String passwd = request.getParameter("passwd");
System.out.println(username);
System.out.println(passwd);

return "/index.jsp";
}

4、请求参数:一键多值

使用数组

(1)页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/23
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>

<form action="/mvc/login" method="get">
用户名<input type="text" name="username"><br>
密码 <input type="password" name="passwd"><br>
爱好 <input type="checkbox" value="lanqiu">篮球
<input type="checkbox" value="zuqiu">足球
<input type="checkbox" value="pingpang">乒乓球
<br>
<input type="submit" value="登录">
</form>

</body>
</html>

(2)controller

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/mvc/login")
public String login(String username,String passwd,String[] aihao){
System.out.println(username);
System.out.println(passwd);
for (String s : aihao) {
System.out.println(s);
}

return "/index.jsp";
}

5、@RequestBody

一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。

默认请求参数格式时:键值对格式。

通过请求头设置请求参数格式:Content-Type

常见的值有:

application/x-www-form-urlencoded(请求参数是键值对);

1
2
3
4
5
6
7
8
9
10
11
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 

  Accept: text/plain, */*
  Accept-Language: zh-cn
  Host: 192.168.24.56
  Content-Type:application/x-www-form-urlencoded
  User-Agent: WinHttpClient
  Content-Length: 3693
  Connection: Keep-Alive
  
  username=zhangsan&passwd=123

multipart/form-data(上传请求,必须是POST)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 

  Accept: text/plain, */*
  Accept-Language: zh-cn
  Host: 192.168.24.56
  Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2
  User-Agent: WinHttpClient
  Content-Length: 3693
  Connection: Keep-Alive

  -------------------------------7db372eb000e2

  Content-Disposition: form-data; name="file"; filename="kn.jpg"

  Content-Type: image/jpeg

  (此处省略jpeg文件二进制数据...)
  -------------------------------7db372eb000e2

  Content-Disposition: form-data; name="username"
  Content-Type: text/html
  zhangsan
  -------------------------------7db372eb000e2

  Content-Disposition: form-data; name="passwd"
  Content-Type: text/html
  123
  -------------------------------7db372eb000e2--

application/json(请求参数是json格式)

1
2
3
4
5
6
7
8
9
10
11
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 

  Accept: text/plain, */*
  Accept-Language: zh-cn
  Host: 192.168.24.56
  Content-Type:application/json
  User-Agent: WinHttpClient
  Content-Length: 3693
  Connection: Keep-Alive
  
  {"username":"zhangsan","passwd":"123"}

当前端传递的数据格式是json格式时,一般使用post请求。

后端使用@RequestBody接收。

(1)页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/23
Time: 13:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<input type="button" value="测试requestBody" onclick="ajax();">

<script>
function ajax(){
var xhr=new XMLHttpRequest();
xhr.open("post","http://localhost:8080/mvc/login");
xhr.setRequestHeader("Content-type","application/json")
xhr.onreadystatechange=function(){
if(xhr.status==200&&xhr.readyState==4){
alert(111);
}
};
var json={"username":"xijinping","passwd":"123"};
xhr.send(JSON.stringify(json));
}
</script>
</body>
</html>

(2)controller

@RequestBody形参类型:Map或者实体类都可以。

1
2
3
4
5
6
@RequestMapping("/mvc/login")
public String login(@RequestBody Map map) {
System.out.println(map.get("username"));
System.out.println(map.get("passwd"));
return "/index.jsp";
}

(3)导入json依赖

这里使用jackson

1
2
3
4
5
6
<!--    json-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0-rc2</version>
</dependency>

(4)启动mvc注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
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
">

<!-- 注解扫描-->
<context:component-scan base-package="com.yan"></context:component-scan>

<!-- mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>

</beans>

六、响应视图和数据

1、请求跳转方式

请求转发:一次请求,通过属性绑定传递数据。

image-20210923152823298

响应重定向:两次请求,通过绑定请求参数传递数据。

image-20210923153046358

2、String和Model

返回一个String视图路径和model数据。

请求转发:

model中的数据,以属性方式绑定到请求对象上。

重定向:

model中的数据,以参数的形式绑定在url后面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/23
Time: 10:45
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
</head>
<body>
<div>
属性: ${requestScope.error}
参数: ${param.error}
</div>

<form action="/mvc/login" method="post">
用户名<input type="text" name="username"><br>
密码 <input type="password" name="passwd"><br>
爱好 <input type="checkbox" value="lanqiu" name="aihao">篮球
<input type="checkbox" value="zuqiu" name="aihao">足球
<input type="checkbox" value="pingpang" name="aihao">乒乓球
<br>
<input type="submit" value="登录">
</form>

</body>
</html>

转发:

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/mvc/login")
public String login(String username,String passwd,Model model) {
if(username.equals("zhangsan")&&passwd.equals("123")){
return "/index.jsp";
}

model.addAttribute("error","登录失败");
//转发:req.setAtrribute("error","登录失败");
return "/login.jsp";
}

重定向:

1
2
3
4
5
6
7
8
9
10
@RequestMapping("/mvc/login")
public String login(String username,String passwd,Model model) {
if(username.equals("zhangsan")&&passwd.equals("123")){
return "/index.jsp";
}

model.addAttribute("error","登录失败");
//重定向:resp.sendRediRect("/login.jsp?error=登录失败");
return "redirect:/login.jsp";
}

3、ModelAndView

转发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping("/mvc/login")
public ModelAndView login(String username, String passwd) {
ModelAndView mv=new ModelAndView();

if(username.equals("zhangsan")&&passwd.equals("123")){
mv.setViewName("/index.jsp");
}else{
mv.addObject("error","登陆失败");
mv.setViewName("/login.jsp");
}

return mv;
}

重定向:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping("/mvc/login")
public ModelAndView login(String username, String passwd) {
ModelAndView mv=new ModelAndView();

if(username.equals("zhangsan")&&passwd.equals("123")){
mv.setViewName("/index.jsp");
}else{
mv.addObject("error","登陆失败");
mv.setViewName("redirect:/login.jsp");
}

return mv;
}

4、void和ServletAPI

1
2
3
4
5
6
7
8
9
10
11
12
13
//转发
@RequestMapping("/mvc/login")
public void login(String username, String passwd, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


if(username.equals("zhangsan")&&passwd.equals("123")){
req.getRequestDispatcher("/index.jsp").forward(req,resp);
}else{
req.setAttribute("error","登录失败");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}

}
1
2
3
4
5
6
7
8
9
10
11
//重定向
@RequestMapping("/mvc/login")
public void login(String username, String passwd, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

if(username.equals("zhangsan")&&passwd.equals("123")){
resp.sendRedirect("/index.jsp");
}else{
resp.sendRedirect("/login.jsp?error=登录失败");
}

}

七、视图解析器

1、ViewResolver

视图解析器。

它实现了页面和数据的分离。

通过视图解析器,将数据渲染到页面上,返回响应的视图。

2、springMVC视图解析器

有13种,常用的是jsp视图解析器,thymleaf视图解析器,excell视图解析器==。

默认jsp。

3、执行流程

通过controller返回一个modelandview;

dispacherServlet将modelandview交给视图解析器;

视图解析器,通过逻辑view(视图名)转为物理view(视图文件);

然后调用view的render方法将数据渲染视图上;

最后返回渲染后的视图。

dispacherServlet将渲染后的视图给tomcat;

tomcat响应视图。

4、配置视图解析器

1
2
3
4
5
6
<!--    配置jsp视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 视图路径的前缀和后缀-->
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping("/mvc/login")
public ModelAndView login(String username, String passwd) {
ModelAndView mv=new ModelAndView();

if(username.equals("zhangsan")&&passwd.equals("123")){
mv.setViewName("index");
}else{
mv.addObject("error","登陆失败");
mv.setViewName("redirect:/login.jsp");
}

return mv;
}

注意:转发时,视图解析器自动加前缀和后缀。

​ 重定向时,视图解析器不会加前缀和后缀,需要手动添加。

八、字符集过滤器

1、springMVC提供了请求和响应的字符集过滤器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class CharacterEncodingFilter extends OncePerRequestFilter {
private String encoding;
private boolean forceRequestEncoding;
private boolean forceResponseEncoding;

public CharacterEncodingFilter() {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
}

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String encoding = this.getEncoding();
if (encoding != null) {
if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}

if (this.isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}

filterChain.doFilter(request, response);
}
}

2、如果需要使用,在web.xml中配置即可。

只能解决post请求,和响应的编码问题。

get请求的编码需要在tomcat中配置解决(server.xml)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--配置springMVC的字符集过滤器-->
<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>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

九、静态资源处理

静态资源访问404:

image-20210923172759707

1、使用tomcat缺省Servlet

1
2
3
4
5
6
7
8
<!--  tomcat缺省servlet-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.txt</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.png</url-pattern>
</servlet-mapping>

image-20210924095419965

2、交给tomcat处理

记得开启mvc注解驱动

1
2
<!--    静态资源处理:交给tomcat处理-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>

image-20210924095443738

3、指定访问目录

记得开启mvc注解驱动

1
2
<!--    静态资源处理:到指定目录下找-->
<mvc:resources mapping="/html/**" location="/html/"></mvc:resources>

image-20210924095457014

十、前后端分离开发

1、只响应数据,不响应视图

2、注解@ResponseBody

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.yan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {

@RequestMapping("/json/test")
@ResponseBody
public String test(){
return "heloo,world!";
}

}

3、注解@RestController

1
@RestController=@Controller+@ResponseBody
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.yan.controller;

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;

//@Controller
@RestController
public class Test2Controller {

@RequestMapping("/mvc/test1")
// @ResponseBody
public String test1(){
return "test1";
}

@RequestMapping("/mvc/test2")
// @ResponseBody
public String test2(){
return "test2";
}

}

4、响应json格式数据

四种常用的jsonAPI:jackson,fastjson,Gson,json-lib

导入jackson依赖

1
2
3
4
5
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0-rc2</version>
</dependency>
1
2
<!--    mvc注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>

(1)json对象

1
2
3
4
5
6
7
8
9
10
@GetMapping("/json/test1")
public User test1(){
User user=new User();
user.setUid(1001);
user.setName("zhangsan");
user.setPasswd("1234");
user.setTel("110");
user.setUsername("aaa");
return user;
}

(2)json数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@GetMapping("/json/test2")
public List<User> test2(){

List<User> userList=new ArrayList<>();
User user=new User();
user.setUid(1001);
user.setName("zhangsan");
user.setPasswd("1234");
user.setTel("110");
user.setUsername("aaa");

User user2=new User();
user2.setUid(1002);
user2.setName("zhangsan2");
user2.setPasswd("12342");
user2.setTel("1102");
user2.setUsername("aaa22");

userList.add(user);
userList.add(user2);
return userList;
}

十一、数据类型转换器

1、类型转换器

(1)作用

遵循 http 协议的 servletreqeust 传输的参数都是 String 类型,但是我们在控制层组件得到的参数都是我们制定或者我们需要的类型,比如 int,double,Object。

img

(2)springMVC提供的类型转换器

1)标量转换器

名称 作用
StringToBooleanConverter String 到 boolean 类型转换
ObjectToStringConverter Object 到 String 转换,调用 toString 方法转换
StringToNumberConverterFactory String 到数字转换(例如 Integer、Long 等)
NumberToNumberConverterFactory 数字子类型(基本类型)到数字类型(包装类型)转换
StringToCharacterConverter String 到 Character 转换,取字符串中的第一个字符
NumberToCharacterConverter 数字子类型到 Character 转换
CharacterToNumberFactory Character 到数字子类型转换
StringToEnumConverterFactory String 到枚举类型转换,通过 Enum.valueOf 将字符串转换为需要的枚举类型
EnumToStringConverter 枚举类型到 String 转换,返回枚举对象的 name 值
StringToLocaleConverter String 到 java.util.Locale 转换
PropertiesToStringConverter java.util.Properties 到 String 转换,默认通过 ISO-8859-1 解码
StringToPropertiesConverter String 到 java.util.Properties 转换,默认使用 ISO-8859-1 编码
2)集合、数组相关转换器

名称 作用
ArrayToCollectionConverter 任意数组到任意集合(List、Set)转换
CollectionToArrayConverter 任意集合到任意数组转换
ArrayToArrayConverter 任意数组到任意数组转换
CollectionToCollectionConverter 集合之间的类型转换
MapToMapConverter Map之间的类型转换
ArrayToStringConverter 任意数组到 String 转换
StringToArrayConverter 字符串到数组的转换,默认通过“,”分割,且去除字符串两边的空格(trim)
ArrayToObjectConverter 任意数组到 Object 的转换,如果目标类型和源类型兼容,直接返回源对象;否则返回数组的第一个元素并进行类型转换
ObjectToArrayConverter Object 到单元素数组转换
CollectionToStringConverter 任意集合(List、Set)到 String 转换
StringToCollectionConverter String 到集合(List、Set)转换,默认通过“,”分割,且去除字符串两边的空格(trim)
CollectionToObjectConverter 任意集合到任意 Object 的转换,如果目标类型和源类型兼容,直接返回源对象;否则返回集合的第一个元素并进行类型转换
ObjectToCollectionConverter Object 到单元素集合的类型转换

类型转换是在视图与控制器相互传递数据时发生的。Spring MVC 框架对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换。

(3)自定义类型转换器

第一步,写一个类实现Converter接口,实现converter方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyStringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd");
Date date=null;
try {
date= sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}

第二步,配置类型转换器

1
2
3
4
5
6
7
8
<!--    配置类型转换器-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.yan.util.MyStringToDateConverter"></bean>
</list>
</property>
</bean>
1
2
<!--    mvc注解驱动-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

第三步,测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/24
Time: 15:01
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>

<form action="/test/cv" method="get">
<input type="text" name="birth">
<input type="submit" value="提交">
</form>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.yan.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
public class ConverterController {

@RequestMapping("/test/cv")
public Date testConverter(Date birth){
System.out.println(birth);
return birth;
}


}

2、请求参数:String->Date

1
2
import org.springframework.format.annotation.DateTimeFormat;
@DateTimeFormat
1
2
3
4
5
@RequestMapping("/test/cv")
public Date testConverter(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birth){
System.out.println(birth);
return birth;
}

3、响应json:Date->String

1
2
import com.fasterxml.jackson.annotation.JsonFormat;
@JsonFormat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.yan.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonAppend;

import java.util.Date;

public class Student {
private int sid;
private String sname;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birth;

public int getSid() {
return sid;
}

public void setSid(int sid) {
this.sid = sid;
}

public String getSname() {
return sname;
}

public void setSname(String sname) {
this.sname = sname;
}

public Date getBirth() {
return birth;
}

public void setBirth(Date birth) {
this.birth = birth;
}
}
1
2
3
4
5
6
7
8
9
@RequestMapping("/test/json")
public Student testJsonFormat(){
Student s=new Student();
s.setSid(1001);
s.setSname("zhangsan");
s.setBirth(new Date());

return s;
}

时区问题:

@JsonFormat(pattern = “yyyy-MM-dd”,timezone = “GMT+8”)

十二、上传和下载

1、文件上传

第一步、导入依赖

commons-fileupload-*.jar

commons-io-*.jar

1
2
3
4
5
6
7
8
9
10
11
12
<!--    文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>

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

第二步,配置文件解析器

1
2
3
4
5
6
7
8
9
<!--    配置文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 总文件大小-->
<property name="maxUploadSize" value="10485760"></property>
<!-- 文件编码-->
<property name="defaultEncoding" value="utf-8"></property>
<!-- 临时目录-->
<property name="uploadTempDir" value="/temp"></property>
</bean>

第三步,编写上传页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/24
Time: 16:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>


<form action="/mvc/upload" method="post" enctype="multipart/form-data">

用户名:<input type="text" name="username"><br>
头像:<input type="file" name="tx"><br>

<input type="submit" value="注册">

</form>

</body>
</html>

注意:请求类型必须时POST,请求内容类型必须是”multipart/form-data“

第四步,编写controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.yan.controller;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
public class UploadController {

@RequestMapping("/mvc/upload")
public String upload(String username, MultipartFile tx) throws IOException {
System.out.println(username);

//获取原文件名
String originalFilename = tx.getOriginalFilename();
System.out.println(originalFilename);

//写入文件
File file=new File("d:\\"+originalFilename);
tx.transferTo(file);

return "file upload success";
}

}

2、多文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%--
Created by IntelliJ IDEA.
User: yan
Date: 2021/9/24
Time: 16:07
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>


<form action="/mvc/upload" method="post" enctype="multipart/form-data">

用户名:<input type="text" name="username"><br>
头像:<input type="file" name="tx"><br>
<input type="file" name="tx"><br>
<input type="file" name="tx"><br>
<input type="file" name="tx"><br>

<input type="submit" value="注册">

</form>

</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.yan.controller;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;

@RestController
public class UploadController {

@RequestMapping("/mvc/upload")
public String upload(String username, MultipartFile[] tx) throws IOException {
System.out.println(username);


for (MultipartFile tx1 : tx) {
//获取原文件名
String originalFilename = tx1.getOriginalFilename();
System.out.println(originalFilename);

//写入文件
File file=new File("d:\\"+originalFilename);
tx1.transferTo(file);

}

return "file upload success";
}

}

3、上传重名覆盖问题

需要对上传的文件重新命名,起个唯一的名字。

可以使用uuid。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.yan.controller;


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

@RestController
public class UploadController {

@RequestMapping("/mvc/upload")
public String upload(String username, MultipartFile[] tx) throws IOException {
System.out.println(username);


for (MultipartFile tx1 : tx) {
//获取原文件名
String originalFilename = tx1.getOriginalFilename();
System.out.println(originalFilename);

//写入文件
// 重命名:防止覆盖
String newFileName= UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));
File file=new File("d:\\"+newFileName);
tx1.transferTo(file);

}

return "file upload success";
}

}

4、文件下载

commons-io-*.jar

@RestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
public class DownLoadController {

@RequestMapping("/mvc/download")
public ResponseEntity<byte[]> download(String fileName) throws IOException {
File file=new File("d:\\"+fileName);

//设置响应头
//内容类型是数据流
//attachment附件形式
HttpHeaders headers=new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", fileName);

//数据封装成响应的实体ResponseEntity
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
}


}

十三、restful风格

1、restful

它是http编码风格。

2、相关的概念

  • 资源与URI
  • 统一资源接口
  • 资源的表述
  • 资源的链接
  • 状态的转移

3、资源和URI

要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。

URI既可以看成是资源的地址,也可以看成是资源的名称。

4、统一资源接口

一个资源对应一个唯一的URI。

资源名可以使用单数,也可以使用复数,推荐复数。

URI中只能使用名词表示资源,不能使用动词。

学生资源URI:http://localhost:8080/students

老师资源URI:http://localhost:8080/teachers

员工资源URI:http://localhost:8080/emps

5、资源的表述

我们对资源的操作,转换成请求的方式。

原来:

http://localhost:8080/deleteStudent

http://localhost:8080/addStudent

http://localhost:8080/updateStudent

http://localhost:8080/selectStudent

restful:

查询Get http://localhost:8080/students

添加POST http://localhost:8080/students

修改PUT http://localhost:8080/students

删除DELETE http://localhost:8080/students

6、状态的转移

响应的JSON数据格式:

{

code:操作的状态码,

message:操作的状态描述,

data:展示的数据

}

7、springMVC实现restful编码风格

(1)添加操作

请求方式:POST

1
2
3
4
5
6
7
8
9
10
11
<form  action="/users" method="post">

用户名 <input type="text" name="username"><br>
密码<input type="password" name="passwd"><br>
确认密码<input type="password" name="passwd2"><br>
姓名<input type="text" name="uname"><br>
头像<input type="file" name="tx1"><br>

<input type="submit" value="注册">

</form>
1
2
3
4
5
6
7
//    @RequestMapping(value = "/users",method = RequestMethod.POST)
@PostMapping("/users")
public String add(Users users, MultipartFile tx1){
System.out.println(users);

return "add success";
}

(2)查询所有操作

请求方式:GET

1
<a href="/users"> 查询所有用户</a>
1
2
3
4
5
@GetMapping("/users")
public String findAll(){
System.out.println("查询所有用户");
return "find all";
}

(3)查询部分操作

请求方式:GET

1
<a href="/users/uid/123"> 查询123</a>
1
2
3
4
5
6
//    @GetMapping("/users/uname/{uname}")
@GetMapping("/users/uid/{uid}")
public String findOne(@PathVariable(value = "uid") int uid){
System.out.println(uid);
return "find one";
}

(4)PUT请求和DELETE请求方式的问题

问题:

在Ajax中,采用Restful风格PUT和DELETE请求传递参数无效,传递到后台的参数值为null

原因:
Tomcat会做:
1.将请求体中的数据,封装成一个map
2.request.getParameter(“id”)就会从这个map中取值
3.SpringMvc封装POJO对象的时候,
会进行request.getParamter()操作从map中获取值,然后把值封装到POJO中去。
AJAX发送PUT请求引发的血案:
PUT请求,请求体中的数据,request.getParamter()拿不到
Tomcat一看是PUT请求,就不会把请求体中的key-value封装到map中,只有POST形式的请求会才封装到map中去。

解决方案:

方案一,如果是PUT或DELETE,使用POST请求。

这样tomcat就可以获取请求参数了,但是restful编码风格需要的是PUT或DELETE。

springMVC提供了一个过滤器:在服务器端,根据参数”_method”,将POST再改成PUT或DELETE。

HiddenHttpMethodFilter

必须满足条件:POST,_method,application/x-www-form-urlencoded

image-20210925151530069

方案二,直接发送PUT或DELETE请求。

springMVC提供了一个过滤器:专门解析请求参数,封装map。

HttpPutFormContentFilter

(5)删除操作

1
2
3
4
5
6
7
8
9
<!--  post请求转put或delete-->
<filter>
<filter-name>methodeFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>methodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<button  onclick="delete11();">删除123</button>
<script src="js/jquery-3.6.0.js"></script>
<script type="text/javascript">
function delete11(){
$.ajax({
url:"/users",
type:"post",
data:"uid=123&_method=delete",
success:function(resp){
alert(resp);
}
});
}

</script>
1
2
3
4
5
@DeleteMapping("/users")
public String delete(Users users){
System.out.println(users.getUid());
return "delete one";
}

(6)修改操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<button  onclick="update11();">修改123</button>
<script src="js/jquery-3.6.0.js"></script>
<script type="text/javascript">

function update11(){
$.ajax({
url:"/users",
type:"post",
data:"uid=123&_method=put",
success:function(resp){
alert(resp);
}
});
}
</script>

十四、拦截器

1、拦截器

拦截器是用来拦截请求,对请求进行处理。

和过滤器的作用一样,只是出现的时机不同。

过滤器是tomat提供的一个servlet组件,用于过滤发给web资源的请求(jsp,servlet==)。

拦截器是springMVC提供的一个组件,主要用于拦截发给controller的请求。

image-20210925162530002

2、拦截器使用场景

登录验证

字符集设置

数据校验

权限验证

日志

==

3、自定义拦截器

1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping("/my")
public class TestInterceptorController {

@RequestMapping("/test")
public String test(){
System.out.println("controller");
return "index";
}
}

第一步,实现HandlerInterceptor 接口(或者继承抽象类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.yan.interceptor;

import org.springframework.transaction.jta.WebSphereUowTransactionManager;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor01 implements HandlerInterceptor {
@Override
// preHandle方法在请求交给controller之前执行
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHandle:1111");
return true;
//true,请求交给下一个拦截器或controller
//false,请求不交给下一个拦截器或controller
}

@Override
// postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle:1111");
}

@Override
// afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("afterCompletion:1111");
}
}

第二步,配置拦截器

1
2
3
4
5
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**" />

<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path="" />
1
2
3
4
5
6
7
8
9
<!--    配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/my/**"/>
<bean class="com.yan.interceptor.MyInterceptor01"></bean>
</mvc:interceptor>


</mvc:interceptors>

第三步,开启mvc注解驱动

1
2
<!--    mvc注解驱动-->
<mvc:annotation-driven ></mvc:annotation-driven>

第四步,测试
preHandle:1111
controller
postHandle:1111
afterCompletion:1111

4、拦截器链

我们将拦截同一请求的拦截器放到一个拦截器链中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!--    配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/my/**"/>
<bean class="com.yan.interceptor.MyInterceptor01"></bean>
</mvc:interceptor>

<mvc:interceptor>
<mvc:mapping path="/my/**"/>
<bean class="com.yan.interceptor.MyInterceptor02"></bean>
</mvc:interceptor>


</mvc:interceptors>

测试:

preHandle:1111
preHandle:2222
controller
postHandle:2222
postHandle:1111
afterCompletion:2222
afterCompletion:1111

执行顺序:

image-20210925170222931

十五、异常处理

十六、spring整合springMVC

1、父子上下文

2、整合

赏

老板大气

支付宝
微信
  • spring

扫一扫,分享到微信

微信分享二维码
springMVC源码
计算机网络
  1. 1. springMVC框架
    1. 1.1. 一、spring-web
      1. 1.1.1. 1、spring框架开发Java项目
      2. 1.1.2. 2、spring框架开发web项目
      3. 1.1.3. 3、tomcat接受请求
      4. 1.1.4. 4、父子容器
    2. 1.2. 二、springMVC
      1. 1.2.1. 1、JavaEe的MVC开发模型
      2. 1.2.2. 2、springMVC
        1. 1.2.2.1. (1)springMVC框架是spring框架的一个子框架。
        2. 1.2.2.2. (2)它是一个MVC的框架。
    3. 1.3. 三、springMVC框架的搭建
      1. 1.3.1. 1、导入spring框架的依赖
      2. 1.3.2. 2、导入springMVC框架的依赖
      3. 1.3.3. 3、在web.xml中配置springMVC提供的前端控制器(核心控制器)DispatcherServlet。
      4. 1.3.4. 4、springMVC配置文件
    4. 1.4. 四、HelloWorld编写
      1. 1.4.1. 1、编写controller
      2. 1.4.2. 2、注解扫描
      3. 1.4.3. 3、创建视图
      4. 1.4.4. 4、测试
      5. 1.4.5. 5、简单分析执行流程
    5. 1.5. 五、接受请求参数
      1. 1.5.1. 1、简单类型的请求参数
      2. 1.5.2. 2、实体对象接收
      3. 1.5.3. 3、使用ServletAPI接收请求参数
      4. 1.5.4. 4、请求参数:一键多值
      5. 1.5.5. 5、@RequestBody
    6. 1.6. 六、响应视图和数据
      1. 1.6.1. 1、请求跳转方式
      2. 1.6.2. 2、String和Model
      3. 1.6.3. 3、ModelAndView
      4. 1.6.4. 4、void和ServletAPI
    7. 1.7. 七、视图解析器
      1. 1.7.1. 1、ViewResolver
      2. 1.7.2. 2、springMVC视图解析器
      3. 1.7.3. 3、执行流程
      4. 1.7.4. 4、配置视图解析器
    8. 1.8. 八、字符集过滤器
      1. 1.8.1. 1、springMVC提供了请求和响应的字符集过滤器。
      2. 1.8.2. 2、如果需要使用,在web.xml中配置即可。
    9. 1.9. 九、静态资源处理
    10. 1.10. 十、前后端分离开发
      1. 1.10.1. 1、只响应数据,不响应视图
      2. 1.10.2. 2、注解@ResponseBody
      3. 1.10.3. 3、注解@RestController
      4. 1.10.4. 4、响应json格式数据
        1. 1.10.4.1. (1)json对象
        2. 1.10.4.2. (2)json数组
    11. 1.11. 十一、数据类型转换器
      1. 1.11.1. 1、类型转换器
        1. 1.11.1.1. (1)作用
        2. 1.11.1.2. (2)springMVC提供的类型转换器
        3. 1.11.1.3. (3)自定义类型转换器
      2. 1.11.2. 2、请求参数:String->Date
      3. 1.11.3. 3、响应json:Date->String
    12. 1.12. 十二、上传和下载
      1. 1.12.1. 1、文件上传
      2. 1.12.2. 2、多文件上传
      3. 1.12.3. 3、上传重名覆盖问题
      4. 1.12.4. 4、文件下载
    13. 1.13. 十三、restful风格
      1. 1.13.1. 1、restful
      2. 1.13.2. 2、相关的概念
      3. 1.13.3. 3、资源和URI
      4. 1.13.4. 4、统一资源接口
      5. 1.13.5. 5、资源的表述
      6. 1.13.6. 6、状态的转移
      7. 1.13.7. 7、springMVC实现restful编码风格
    14. 1.14. 十四、拦截器
      1. 1.14.1. 1、拦截器
      2. 1.14.2. 2、拦截器使用场景
      3. 1.14.3. 3、自定义拦截器
        1. 1.14.3.1. 4、拦截器链
    15. 1.15. 十五、异常处理
    16. 1.16. 十六、spring整合springMVC
© 2022 un1queyan
Hexo Theme Yilia by Litten 本站总访问量次
  • 所有文章
  • 友链
  • 关于我

tag:

  • java基础
  • java
  • 随笔
  • Java基础
  • JavaScript
  • mybatis
  • MySQL
  • Nginx
  • spring
  • Shiro
  • django
  • docker
  • elasticsearch
  • 计算机网络
  • linux
  • Linux
  • maven
  • mongodb
  • Django
  • python
  • sqlalchemy
  • redis
  • rabbitMQ
  • 算法练习
  • 设计模式
  • 数据结构
  • jvm
  • 计算机基础

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 友情链接1
  • 友情链接2
  • 友情链接3
  • 友情链接4
  • 友情链接5
  • 友情链接6
很惭愧

只做了一点微小的工作
谢谢大家