13、springmvc

1、概念
1.SpringMVC:接收浏览器的请求响应,对数据进行处理,然后返回页面进行显示
2.三层架构:分层分工,相互独立,协同工作的架构模式,
  • ​ m(模型层);v(视图层);c(控制层)
  • ​ dao持久化层(数据库);service业务层(逻辑运算);controller控制层(输入输出)
2、使用
1.导包
    <dependencies>
       <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.9.8</version>
        </dependency>
    </dependencies>
    <build>
        <!--在build中配置resources来防止资源导出失败的问题-->
        <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>
2.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">
         <!--
    需确保version="4.0"是最先的版本,不是则网上找下最新的。
    先新建空项目,再添加框架支持Web,也可保证version是最新的
    -->
    <!-- 配置SpringMVC的核心控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 加载SpringMVC配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
            <!--springmvc.xml是springmvc的配置文件-->
        </init-param>
        <!--启动级别-1-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- servlet标签中的name与servlet-mapping标签中name的需一致 -->
        <!-- /只匹配请求   /*jsp页面也匹配-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
3.新建springmvc-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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/mvc
		http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 扫描注解类 -->
    <context:component-scan base-package="com.jiang.controller"/>
    <!-- 让springmvc不处理静态资源 .css .js .html .mp3 .mp4等 -->
    <mvc:default-servlet-handler/>
    <!-- 使SpringMVC注解生效 :会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 配置视图解析器 -->
    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"></property><!--jsp是我自己加的文件夹,没有时写/WEB-INF/就行-->
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>
4、创建ControllerTest2
package com.jiang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("T1")
public class ControllerTest2 {
    @RequestMapping("Test1")
    public String Test1(Model model){
        System.out.println("马上跳转");
        model.addAttribute("msg","两小无猜终无情");//前台用${requestScope.msg}(可简写为${name})取值
        return "test";//逻辑路径,test是在/WEB-INF/jsp/目录下,以.jsp结尾,所以/WEB-INF/jsp/test.jsp需写为test
        /*
        return "forward:login7";//请求转发(一般用于同一服务器,同一类里或不同类的跳转)
        return "redirect:/login7";//重定向(主要用于跨服务器的跳转)
        return "/index.jsp";//物理路径,也是转发过去的
        */
    }
}

5、在jsp创建hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
<br/>

<%-- 表单格式样例 --%>
<form method="get" action="login2">
用户:<input name="name" type="text">
年龄:<input name="age" type="text">
<input type="submit" value="提交">
</form>
<form action="login3" method="post">
<h1>数组类型传递</h1>
抽烟<input type="checkbox" name="hobby" value="抽烟"><br/>
喝酒<input type="checkbox" name="hobby" value="喝酒"><br/>
烫头<input type="checkbox" name="hobby" value="烫头"><br/>
<input type="submit" value="提交"><br/>
</form>
<a href="login4?name=1111&password=222">超链接传值</a>

</body>
</html>

6、测试

访问:http://localhost:8080/项目名//T1/Test1 进行测试

3、resuful风格(http://localhost:8080/SSM/commit/root/123456)
1.好处:url更加简洁、传参数更加安全
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RestFulController {
   //映射访问路径,前端通过【http://localhost:8080/SSM/commit/7/“我是password” 】这种进行访问
   @RequestMapping("/commit/{p1}/{p2}")
   public String index(@PathVariable int p1, @PathVariable string p2, Model model,HttpSession session){
       int result = p1+p2;
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "结果:"+result);//前台用${requestScope.msg}(可简写为${name})取值
       //session.setAttribute("name","小江");//前台用${sessionScope.name}取值
       //返回视图位置
       return "test";      
  }
    //映射访问路径,必须是POST请求   value:url的值,method:提交方式  produces:指定响应体返回类型和编码
    @RequestMapping(value = "/hello",method = {RequestMethod.POST})
    public String index2(Model model){
       model.addAttribute("msg", "hello!");
       return "test";
    }
}
2.提交方式
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
4、前端=传值=后端
@Controller
public class Usercontroller {
@RequestMapping("login")
//当前端为name,后端为username时用@RequestParam("name")String username来解决
public String login(@RequestParam("name")String username,String password) {
	System.out.println("登录"+"用戶名:"+username+"密碼:"+password);//通过字段名传值,
	return "NewFile.jsp";
}

@RequestMapping("login1")
public String login(User user) {
	System.out.println(user);//通过对象传值,需保证User类中的字段名与前端的字段名一致,才能传值成功
	return "NewFile.jsp";
}

@RequestMapping("login2")
public String login(String[] a) {
	for (int i = 0; i < a.length; i++) {//通过数组传值,也需保证字段名称一致
		System.out.println(a[i]);
	}
	return "NewFile.jsp";
}

@RequestMapping("login3")
public String login3(String name,String password) {
	System.out.println("登录"+"用戶名:"+name+"密碼:"+password);
	return "NewFile";
}
}

<form action="login1" method="post">
		用户名:<input type="text" name="name" /><br /> 
		密码:<input type="text" name="password" /><br /> 
		<input type="submit" value="提交" />
	</form>
	***************************************
	<form action="login2" method="post">
	爱好:<input type="checkbox" name="a" value="跳高"/>跳高<br /> 
		<input type="checkbox" name="a" value="休息"/>休息<br /> 
		<input type="checkbox" name="a" value="看着办"/>看着办<br /> 
			<input type="submit" value="提交" />
	</form>

***************************************<br /> 
	
	<a href="login3?name=江西&password=123">超链接</a>
5、后端=传值=前端(Model session)
从主页面进入login

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping("login")
public String login3(Model m,HttpSession s) {
	m.addAttribute("username", "江溪");
	s.setAttribute("password", "123456");
	return "NewFile";
}


<body>
新页面<br/>
${username}<br/>
${sessionScope.password}<br/>
</body>
6、传值时中文乱码处理

web.xml中添加字符集过滤器

<!-- 处理请求或者响应的字符集过滤器(用于处理中文乱码的问题的) -->
    <filter>
        <filter-name>characterEncodingFilter</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>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
7、JSON格式
1.js中JSON格式转换
<!--新建一个test.html-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        //编写一个javascript对象
        var User={
            name:"小江",
            age:4,
            sex:"男"
        };
        console.log(User);//F12-控制台查看打印信息
        console.log("==========================================");
        //将js对象 转换成 json对象,str={"name":"小江","age":4,"sex":"男"}
        var str=JSON.stringify(User);
        console.log(str);
        console.log("==========================================");
        //将json对象 转换成 js对象
        var json=JSON.parse(str);
        console.log(json);
    </script>
</head>
<body>

</body>
</html>
2.jackson的使用
<!-- 1、导入jackson包 -->
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.9.8</version>
</dependency>

<!-- 2、写pojo类 -->
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
    private String sex;

}

3.web.xml中添加

    <!--jackson处理返回给前端的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>

4.编写UserController,并进行测试

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.jiang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController//等同于@Controller+@ResponseBody
//指定响应体返回类型和编码可在springmvc-servlet.xml进行统一配置
//@RequestMapping(produces = "application/json;charset=utf-8")
public class UserControler {
    @RequestMapping("Test11")
    public String Test11() throws JsonProcessingException {
        //创建一个jackson的对象映射器,用来解析数据
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user = new User("小江", 18, "男");
        //将我们的对象解析成为json格式
        String str = mapper.writeValueAsString(user);
        //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
        return str;
    }
    @RequestMapping("Test12")
    public String Test12() throws JsonProcessingException {
        //创建一个List,填充一些对象
        List<User> list = new ArrayList<User>();
        User user = new User("小江", 18, "男");
        User user1 = new User("小江1", 18, "男");
        User user2 = new User("小江2", 18, "男");
        list.add(user);
        list.add(user1);
        list.add(user2);
        //创建一个jackson的对象映射器,将我们的List解析成为json格式,直接返回
        return new ObjectMapper().writeValueAsString(list);
    }

    @RequestMapping("Test13")
    public String Test13() throws JsonProcessingException {
        //创建一个List,填充一些对象
        ObjectMapper mapper = new ObjectMapper();
        //不使用时间戳的方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //自定义日期格式对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //指定日期格式
        mapper.setDateFormat(sdf);
        //打印当前时间
        System.out.println(new Date().toString());
        //将我们的当前时间解析成为json格式,直接返回
        return mapper.writeValueAsString(new Date());
    }
}
3.fastjson2的使用

1.导包

<!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.20</version>
</dependency>

2.编写测试类

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.jiang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController//等同于@Controller+@ResponseBody
//指定响应体返回类型和编码可在springmvc-servlet.xml进行统一配置
//@RequestMapping(produces = "application/json;charset=utf-8")
public class UserControler {
    @RequestMapping("Test14")
    public String Test14() throws JsonProcessingException {
        //创建一个List,填充一些对象
        List<User> list = new ArrayList<User>();
        User user = new User("小江", 18, "男");
        User user1 = new User("小江1", 18, "男");
        User user2 = new User("小江2", 18, "男");
        list.add(user);
        list.add(user1);
        list.add(user2);

        System.out.println("*******Java对象 转 JSON字符串*******");
        System.out.println("JSON.toJSONString(list)==>"+JSON.toJSONString(list));//返回数据给前端时用
        System.out.println("JSON.toJSONString(user1)==>"+JSON.toJSONString(user1));//返回数据给前端时用

        System.out.println("\n****** JSON字符串 转 Java对象*******");
        String str2 = JSON.toJSONString(user1);
        System.out.println("JSON.parseObject(str2,User.class)==>"+JSON.parseObject(str2,User.class));//处理前端数据时用

        System.out.println("\n****** Java对象 转 JSON对象 ******");
        JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
        System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.toJSONString());

        System.out.println("\n****** JSON对象 转 Java对象 ******");
        System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+JSON.toJavaObject(jsonObject1, User.class));
        return "ssss";
    }
}

3.fastjson2的所有方法

// 把JSON文本parse转为JSONObject或者JSONArray 
public static final Object parse(String text); 
// 把JSON文本parse转成JSONObject    
public static final JSONObject parseObject(String text)// 把JSON文本parse转为JavaBean 
public static final <T> T parseObject(String text, Class<T> clazz); 
// 把JSON文本parse转成JSONArray 
public static final JSONArray parseArray(String text); 
//把JSON文本parse转成JavaBean集合 
public static final <T> List<T> parseArray(String text, Class<T> clazz); 
 // 将JavaBean序列化为JSON文本 
public static final String toJSONString(Object object);
// 将JavaBean序列化为带格式的JSON文本 
public static final String toJSONString(Object object, boolean prettyFormat); 
//将JavaBean转换为JSONObject或者JSONArray
public static final Object toJSON(Object javaObject); 
8、拦截器(AOP思想的应用)
1.编写实现HandlerInterceptor接口的自定义拦截器
package com.jiang.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //做登录拦截时,可放行登录jsp。再判断用户是否登录,未登录跳转至登录页面,已登录放行
        System.out.println("拦截前");
        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("清理");
    }
}
2.配置文件applicationContext.xml中新增内容
<!--关于拦截器的配置-->    
<mvc:interceptors>
    <mvc:interceptor>
        <!--/** 包括路径及其子路径-->
        <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
        <!--/admin/** 拦截的是/admin/下的所有-->
        <mvc:mapping path="/**"/>
        <!--bean配置的就是拦截器,是手写的实现HandlerInterceptor接口的类,类里定义拦截的内容-->
        <bean class="com.jiang.config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>
3.编写MyTestController

访问http://localhost:8080/test测试

package com.jiang.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyTestController {
    @RequestMapping("test")
    public String test(){
        System.out.println("我是test");
        return "小江很OK";
    }
}
9、文件上传下载
1.导包
<dependencies>
    <!--文件上传-->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>
    <!--servlet-api导入高版本的-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>
</dependencies>
2.配置文件applicationContext.xml中新增内容
	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
		<!--上传文件的最大大小 -->
		<property value="17367648787" name="maxUploadSize"/>
		<!-- 上传文件的编码 -->
		<property value="UTF-8" name="defaultEncoding"/>
	</bean>
3.写jsp
<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2022/12/2/002
  Time: 21:14
  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>
  <a href="${pageContext.request.contextPath}/test">test</a>
  <h1>文件上传</h1>
  <form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="upload">
  </form>
  <h1>文件下载</h1>
  <a href="${pageContext.request.contextPath}/download">点击下载</a>
  </body>
</html>
4.写FileController
package com.jiang.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

@RestController
public class FileController {
    @RequestMapping("test")
    public String test(){
        System.out.println("test");
        return "test";
    }
    @RequestMapping("upload")
    public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()) {
            realPath.mkdir();
        }
        //上传文件地址
        System.out.println("上传文件保存地址:" + realPath);

        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));

        return "redirect:/index.jsp";
    }
    @RequestMapping("download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String  path = request.getServletContext().getRealPath("/upload");
        String  fileName = "1.webp";

        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));

        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();

        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值