SpringMVC对网页发来的数据请求处理和转发

目录

一、MVC的基本流程

二、请求路径支持通配符(匹配各种不明确的请求路径),占位符(通过@PathVariable注解加在参数前取出请求路径)。

三、限制请求参数为什么或不为什么,违反则出异常。

四、设置方法接收的请求方式

五、接收REST请求方式:即使用GET、POST、PUT、DELETE方式请求URL实现查、增、更、删操作

六、使用Serlvet的内置对象(直接在方法参数定义内置对象即可)

六、映射Cookie(Cookie是以键值对方式存储在客户端里的数据,使用@CookieValue("键名")加在方法参数前获取传来的Cookie)

七、映射基本类型请求参数( 使用@RequestParam("请求参数名")加在方法参数前映射请求参数)

八、映射Bean类型请求参数(直接在方法参数列表定义Bean即可)

九、将数据存入转发页面的request域(使用Map类直接加在参数列表,或者ModelAndView类加在参数列表的同时返回值需要是ModelAndView类型,原返回值传入ModelAndView的构造参数)

十、将数据存入转发页面的session域(@SessionAttributes("Map里的键名或ModelAndView里的键名")注解加在类前)

十一、存入转发页面request域或session域前对数据的处理:使用@ModelAttribute直接加在方法前

十二、请求转发与重定向:跳至相应方法或页面

十三、通过URL能直接访问WEB-INF里的JSP文件,让JSP页面能使用静态资源

十四、数据处理(form表单字段映射到Bean对象属性限制某个属性不绑定处理) 

十五、数据映射(form表单的String字段映射到Bean对象的时间属性(Date)、基本类型包装属性(如:Float、Integer))

十六、数据约束(类似数据库约束来约束Bean类,使用Hibernate Validator来实现限制form表单的字段,不符合要求则报错。)

十七、以JSON格式将Bean对象传送至网页



一、MVC的基本流程

          https://blog.csdn.net/qq_38487155/article/details/89385100

          补充:MVC的注解默认属性都是value

二、请求路径支持通配符(匹配各种不明确的请求路径),占位符(通过@PathVariable注解加在参数前取出请求路径)。

	//@RequestMapping映射的请求URL支持通配符
	/*
	 ?:匹配文件名中的一个字符 –
	 *:匹配文件名中的任意字符 –
	 **: 匹配多层路径
	 */
	@RequestMapping("/**/testPath")
	public String testPath() {
		System.out.println("请求成功!");
		return "success";
	}
	/*
	 * @RequestMapping映射的请求URL支持路径占位符,在方法参数列表里使用@PathVariable("占位id")取出路径占位参数
	 */
	@RequestMapping("/testPathVariable/{id}")
	public String testPathVariable(@PathVariable("id") Integer id) {
		System.out.println("请求成功:"+id);
		return "success";
	}

三、限制请求参数为什么或不为什么,违反则出异常。

	//@RequestMapping的params:限制请求URL参数为什么,或不为为什么 headers:限制请求头为什么或不为什么
	//以下表示请求参数username必须为admin、请求参数password不能为admin、不能有请求参数age
	@RequestMapping(value="testPH",params= {"username=admin","password!=admin","!age"})
	public String testPH() {
		System.out.println("请求成功!");
		return "success";
	}

四、设置方法接收的请求方式

	//@RequestMapping的value:设置请求URL,method:设置请求方式,method=RequestMethod.POST设置为post请求
	@RequestMapping(value="/testPost",method=RequestMethod.POST)
	public String testPost() {
		System.out.println("Post方式!");
		return "success";
	}

五、接收REST请求方式:即使用GET、POST、PUT、DELETE方式请求URL实现查、增、更、删操作

 1、在web.xml文件里添加HiddenHttpMethodFilter过滤器,将POST 请求转为DELETE或PUT 请求 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    id="WebApp_ID"
     version="3.0">
    <!-- 配置 org.springframework.web.filter.HiddenHttpMethodFilter: 用来将 POST 请求转为 DELETE 或 PUT 请求 -->
	<filter>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>HiddenHttpMethodFilter</filter-name>
		<!-- 设置过滤范围:即可以转化的文件路径范围 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 配置DispatcherServlet -->
	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 配置DispatcherServlet的初始化参数,此处配置springXMl文件ID和文件路径 -->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<!-- 以下表示解析器文件路径在类路径下的springmvc文件 -->
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Map all requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<!-- 在这配置哪些请求可以给到Servlet -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

 2、在@RequestMapping注解里设置method属性,method=RequestMethod.DELETE

	@RequestMapping(value="/testRest/{id}",method=RequestMethod.GET)
	public String testRest(@PathVariable("id") Integer id) {
		System.out.println("GET请求成功:"+id);
		return "success";
	}
	@RequestMapping(value="/testRest",method=RequestMethod.POST)
	public String testRest() {
		System.out.println("POST请求成功!!");
		return "success";
	}
	@RequestMapping(value="/testRest",method=RequestMethod.PUT)
	public String testRestPUT() {
		System.out.println("PUT请求成功!!");
		return "success";
	}
	@RequestMapping(value="/testRest",method=RequestMethod.DELETE)
	public String testRestDelete() {
		System.out.println("DELETE请求成功!!");
		return "success";
	}

 3、在发送POST请求里加入隐藏参数_method,值为 DELETE 或 PUT(即<form>的method属性仍设置为post,在<form>里包含隐藏参数 <input type="hidden" name="_method" value="PUT">)

	<a href="HelloWorld/testRest/1">GET请求</a>
	<br/>
	<form action="HelloWorld/testRest" method="post">
		<button>POST请求</button>
	</form>
	<form action="HelloWorld/testRest" method="post">
		<button>PUT请求</button>
		<input type="hidden" name="_method" value="PUT">
	</form>
	<form action="HelloWorld/testRest" method="post">
		<button>DELETE请求</button>
		<input type="hidden" name="_method" value="delete">
	</form>

六、使用Serlvet的内置对象(直接在方法参数定义内置对象即可)

	/*
	 * MVC可以使用Servlet的内置对象,只需要在方法参数里定义即可。
	 * 可使用的内置对象:HttpServletRequest 
						 HttpServletResponse 
						 HttpSession
						 java.security.Principal
						 Locale
						 InputStream
						 OutputStream
						 Reader 
						 Writer
	 */
	@RequestMapping("/testServletAPI")
	public String testServletAPI(HttpServletRequest request,HttpServletResponse response,Reader reader) {
		System.out.println(request+""+response);
		System.out.println(reader);
		return "success";
	}

六、映射Cookie(Cookie是以键值对方式存储在客户端里的数据,使用@CookieValue("键名")加在方法参数前获取传来的Cookie)

	/*
	 * 使用@CookieValue映射Cookie
	 * value:映射的Cookie键名
	 */
	@RequestMapping("/testCookieValue")
	public String testCookieValue(@CookieValue("data")String data) {
		System.out.println(data);
		return "success";
	}

七、映射基本类型请求参数( 使用@RequestParam("请求参数名")加在方法参数前映射请求参数)

	/*
	 * 使用@RequestParam映射请求参数
	 * value:映射的参数名
	 * required:是否必须包含该参数
	 * defaultValue:该参数时的默认值,在映射类型为基本类型(如int)非包装类型(Integer)时,该属性是必须的。
	 */
	@RequestMapping("/testRequestParams")
	public String testRequestParams(@RequestParam("username")String username,@RequestParam(value="age",
	                                 required=false,defaultValue="0")int age) {
		System.out.println(username+"、"+age);
		return "success";
	}

八、映射Bean类型请求参数(直接在方法参数列表定义Bean即可)

	/*
	 *	MVC会根据属性请求参数名自动匹配Bean对象属性名,并映射至方法参数。支持级联属性(即当前类包含其它类属性)
	 */
	@RequestMapping(value="/testBean",method=RequestMethod.POST)
	public String testBean(User user) {
		System.out.println(user);
		return "success";
	}
	/*
	 * 测试不用@RequestParam会自动映射Get请求方式的Bean
	 */
	@RequestMapping(value="/testBeanGET")
	public String testBeanGET(User user) {
		System.out.println(user);
		return "success";
	}

九、将数据存入转发页面的request域(使用Map类直接加在参数列表,或者ModelAndView类加在参数列表的同时返回值需要是ModelAndView类型,原返回值传入ModelAndView的构造参数)

	/*
	 * 使用ModelAndView类将数据存入转发页面request域,返回值需要设置成ModelAndView类型。同时将转发页面返回值
	 * 传入ModelAndView构造方法,ModelAndView提供了addObject方法(以键值对方式)来存入数据,方便在JSP页面使
	 * 用EL表达式取出
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView(ModelAndView modelAndView) {
		modelAndView=new ModelAndView("success");
		modelAndView.addObject("time",new Date());
		return modelAndView;
	}
	/*
	 * 使用Map类将数据存入转发页面request域,使用Map无法获取网页传来的数据,即Map参数只起转发作用
	 * Map类不需要设置成返回值,只需要传入参数即可。
	 */
	@RequestMapping("/testMap")
	public String testMap(Map<String,Object> map) {
		map.put("user", Arrays.asList("小米","小明","小红"));
		return "success";
	}
	/*
	 * 使用Map作为参数无法获取用户请求传来的数据,只能用Bean作为参数获取,或者当参数列表里有Bean参数时,Map也会有参数
	 */
	@RequestMapping("/testMap2")
	public String testMap2(Map<String,Object> map,User user) {
		System.out.println(map.get("user"));
		System.out.println(user);
		return "success";
	}

   转发页面取出数据使用EL表达式:    ${requestScope.time}、    ${requestScope.user} 

十、将数据存入转发页面的session域(@SessionAttributes("Map里的键名或ModelAndView里的键名")注解加在类前)

@SessionAttributes(value= {"user1","user2"},types= {String.class,Integer.class})
@RequestMapping("/HelloWorld")
@Controller
public class HelloWorld {
    ...
}
	/*
	 * 使用@SessionAttributes注解将数据存入Session域,@SessionAttributes注解加在处理请求类(@Controller类)前
	 * value:默认属性,通过属性名指定Map里的键名或者ModelAndView里的键名来确定哪些数据进入Session域
	 * type:通过类的class属性确定哪种类的所有对象进入Session域
	 */
	@RequestMapping("/testSession")
	public String testSession(User user,Map<String,Object> map) {
		map.put("user1", new User("A", "123", "139@qq.com", 12, new Address("广东","汕头")));
		map.put("user2", new User("B", "456", "298@qq.com", 18, new Address("湖北","武汉")));
		map.put("school", "武汉生物工程学院");
		map.put("age", 21);
		return "success";
	}

十一、存入转发页面request域或session域前对数据的处理:使用@ModelAttribute直接加在方法前

	/*
	 * 方法前@ModelAttribute作用:会在MVC将网页传来Bean对象封装数据前(即调用testModelAttribute方法前)执行,
	 *                            可以防止Bean某个属性没有传值时使用数据库对象默认值,注意:当属性有值,数据
	 *                            库对象属性也有值时保持数据库对象属性值优先。
	 * 运行流程:
	 * 1. 执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中. 键为: user(类名小写)
	 * 2. SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性.
	 * 3. SpringMVC 把上述对象传入目标方法的参数. 
	 * 
	 * 注意: 1、在 @ModelAttribute 修饰的方法中, 放入到 Map 时的键需要和请求方法入参类型的第一个字母小写的字符串一致!
	 *          不一致时请求方法只有参数为Bean时才能获取到@ModelAttribute 修饰的方法存入的数据,且需要在请求方法参数前
	 *          加@ModelAttribute(" @ModelAttribute 修饰的方法中Map存入的键名"),
	 *          不一致时转发页面获取存入Map的Bean对象时同样需要修改为${requestScope.Map键名} 
	 *       2、在 @ModelAttribute 修饰的方法中, 如果参数为Bean类型且没有map参数时,无法将从数据库取出Bean对象存入request域,
	 *          会导致Bean属性没有传值时不会使用数据库对象属性值,即仍为空。所以此时需要添加一个map参数
	 *          总结:@ModelAttribute 修饰的方法一定要有map参数。
	 *       3、请求方法使用map作为参数和Bean对象作为参数都会自动传入request域。
	 *       4、@ModelAttribute 修饰的方法返回值设不设置都行,设置的话一般要与请求方法返回值一致。
	 */
	@ModelAttribute
	public void getData(Map<String, Object> map) {
		//模拟从数据库取出的数据Bean对象,并存入map
		map.put("abc",  new User("A", "123", "139@qq.com", 12, new Address("广东","汕头")));	//传入map相应的Bean对象,键为类名首字母小写
	}
	/*@ModelAttribute
	public void getData2(User user,Map<String, Object> map) {
		//模拟从数据库取出的数据Bean对象,并存入map
		user= new User("A", "123", "139@qq.com", 12, new Address("广东","汕头"));
		map.put("user",user);
	}*/
	@RequestMapping("/testModelAttribute")
	public String testModelAttribute(Map<String, Object> map) {
		System.out.println("修改:"+map.get("user"));
		return "success";
	}
	@RequestMapping("/testModelAttribute2")
	public String testModelAttribute2(@ModelAttribute("abc")User user) {
		System.out.println("修改:"+user);
		return "success";
	}

十二、请求转发与重定向:跳至相应方法或页面

	/*
	 * 请求转发和重定向:在返回值前添加使用forward:/或redirect:即可完成转发或重定向。
	 * 重定向与请求转发区别:
    		> 请求转发请求服务器一次,即当前请求转发至另一请求(地址url不变);重定向请求服务器俩次,即重新发送请求。
				<> 需要地址栏发生变化,那么必须使用重定向!
      		<> 需要在下一个Servlet中获取request域中的数据,必须要使用转发。
				<> 请求转发的第二次请求方法可以获取第一次请求用户发来的数据,重定向是用户分别俩次向服务器发起俩个独立请求,
				   即重定向的第二次请求方法无法获取第一次请求用户发来的数据。
	  
	  	除了在WEB-INF外面的index页面可以使用拼接URL,其它在WEB-INF页面无法通过URL直接访问,只能通过Handler中转
	    除非配置<mvc:view-controller>
	    
	  	重定向到页面:redirect:/<mvc:view-controller>的view-name属性值
	  	重定向到Handler里的方法:redirect:/@RequestMapping类注解value值/@RequestMapping方法注解value值
	  	
	  	注意:POST和DELETE请求方法的无法转发请求被<mvc:view-controller>配置的页面,重定向可能会导致request域
		 	  的数据丢失页面无法正常显示,此处推荐使用原有视图解析器(即返回页面文件名通过视图解析器解析为url地址)。

	  	总结:尽量使用默认视图解析来返回页面,请求转发与重定向来跳转执行方法,优先使用重定向(转发在用户刷新页面时可能出现不一致操作)
	 */
	@RequestMapping("/testFR")
	public String testFR() {
		/*System.out.println("您已转发");
		return "forward:/index.jsp";*/
		System.out.println("您已重定向");
		//return "redirect:/index.jsp";
		//return "redirect:/views/success";
		return "redirect:/HelloWorld/testView";
	}

十三、通过URL能直接访问WEB-INF里的JSP文件,让JSP页面能使用静态资源

	<!-- 配置<mvc:view-controller>作用:WEB_INF里的JSP文件无法直接通过URL访问,配置使得可以直接通过url访问页面,
	                                    会导致不执行handler方法(即当前handler方法的数据处理和页面转发会失效),
         								若想让handler方法继续执行:配置<mvc:annotation-driven>
		 		path:设置转发页面的访问路径,不能带文件后缀,以WEB_INF为初始路径
		 		view-name:设置转发页面的文件名,需要与路径最后文件名一致
		 		
		 		注意:该页面(此处配置的是views/success页面)无法被POST和DELETE方法的返回值使用请求转发访问,重定向可能会导致request域
		 		      的数据丢失页面无法正常显示,此处推荐使用原有视图解析器(即返回页面文件名通过视图解析器解析为url地址)转发/重定向
		 		      到相应的方法。
		 
	-->
	<mvc:view-controller path="views/success" view-name="success"/>
	<!-- 在实际开发中通常都需配置 mvc:annotation-driven 标签让handler方法继续执行
		 俩种使用情况:
		        1、直接访问JSP文件资源时需要调用请求方法使用,默认<mvc:view-controller>会跳过@RequestMapping注解方法
		        2、使用静态资源时需要调用请求方法使用,默认<mvc:default-servlet-handler/>会跳过@RequestMapping注解方法
	 -->
	<mvc:annotation-driven></mvc:annotation-driven> 
	
	<!--静态资源指:WebContent下的文件,不包括WEB-INF下的文件。如scripts文件 
		配置允许访问静态资源的标签: 将在 SpringMVC 上下文中定义一个DefaultServletHttpRequestHandler,
		它会对进入 DispatcherServlet 的请求进行筛查, 如果发现是没有经过映射的请求(即不进入Handler方法的请求), 就将该请求交由
		 WEB 应用服务器默认的Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理

		一般 WEB 应用服务器默认的 Servlet 的名称都是 default.
		若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定 -->
	<mvc:default-servlet-handler/>

十四、数据处理(form表单字段映射到Bean对象属性限制某个属性不绑定处理) 

	/* 数据绑定限制(form表单字段映射到Bean对象属性的绑定处理)
	 *   1、方法前添加@InitBinder注解,表明这是一个设置绑定方法
	 *   2、方法参数列表添加WebDataBinder对象,WebDataBinder用来完成表单字段映射到Bean对象属性
	 */
	@InitBinder
	public void initBinder(WebDataBinder dataBinder) {
		dataBinder.setDisallowedFields("lastName");	//设置不绑定lastName属性
	}

十五、数据映射(form表单的String字段映射到Bean对象的时间属性(Date)、基本类型包装属性(如:Float、Integer))

        / * 注意:如果类型不一致(如int映射到Float,float映射到Integer),将使得Employee与form表单对象无法一一对应,会发生错误同时如果不满足 @DateTimeFormat注解和@NumberFormat注解的格式,也会报错
     
      1、在springmvc文件里添加<mvc:annotation-driven></mvc:annotation-driven>
      2、在Bean类的属性前添加相应的注解
            @DateTimeFormat:可对java.util.Date、java.util.Calendar、java.long.Long 时间类型进行注解:
                    pattern 属性:自定义时间类型格式 –如:"yyyy-MM-dd hh:mm:ss"
                    iso 属性:系统给定的时间类型格式,包括四种:
                                 ISO.NONE:默认值、不需要设置时间输入项
                                 ISO.DATE :yyyy-MM-dd
                                 ISO.TIME:hh:mm:ss.SSSZ
                                 ISO.DATE_TIME:yyyy-MM-dd hh:mm:ss.SSSZ
              @NumberFormat:可对类似数字类型的属性进行注解,它拥有两个互斥的属性:
                    pattern 属性:定义样式(String值),如patter="#,###";#代表位数,只要位数符合即可
                    style:类型为 NumberFormat.Style。用于指定– 样式类型,包括三种:Style.NUMBER(正常数字类型)、Style.CURRENCY(货币类型)、 Style.PERCENT(百分数类型)
        */

	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birth;
	
	@NumberFormat(pattern="#,###,###.#")
	private Float salary;

十六、数据约束(类似数据库约束来约束Bean类,使用Hibernate Validator来实现限制form表单的字段,不符合要求则报错。)

        1、加入 hibernate validator 验证框架的 jar 包:
                           hibernate-validator-5.0.0.CR2.jar
                           hibernate-validator-annotation-processor-5.0.0.CR2.jar
                           classmate-0.8.0.jar
                           jboss-logging-3.1.1.GA.jar
                           validation-api-1.1.0.CR1.jar
        2、在springmvc文件里添加<mvc:annotation-driven></mvc:annotation-driven>
        3、在Bean类的属性前添加验证限制
                @Null:该属性必须为空
                @NotNull:该属性不能为空
                @Email:该属性必须为邮箱格式
                @AssertTrue:该属性必须为true
                @AssertFalse:该属性必须为false
                @Min(value):该属性必须为数字,且不小于value
                @Max(value):该属性必须为数字,且不大于value
                @Size(max,min):该属性必须为数字,且在指定范围
                @Past:该属性必须为一个过去的日期
                @Future:该属性必须为一个未来的日期
                @Pattern(表达式):该属性必须符合正则表达式
                @Length:该属性字符串大小需要在指定范围内
                @Range:该属性需要在合适范围内
        4、在请求方法的Bean参数前加上 @Valid 注解

	@RequestMapping(value="emp",method=RequestMethod.POST)
	public String save(@Valid Employee employee,Map<String, Object>map) {
		employeeDao.save(employee);
		System.out.println("添加成功!"+employee);
		
		
		/*map.put("employees", employeeDao.getAll());
		return "redirect:/views/list";*/		//使用重定向到页面会导致重新发起第二次请求,该请求的request域没有任何Employee
		
		return "redirect:/emps";				//使用重定向到方法,该方法返回值使用的是视图解析器(不是转发或重定向),request域中仍有数据。
		
		/*map.put("employees", employeeDao.getAll());
		return "forward:/views/list";	*/		//使用转发原因:因为有使用同一request域,否则看不出增加了一个Employee效果
		 
	}
	@NotEmpty
	private String lastName;

	@Email
	private String email;
	//1 male, 0 female
	private Integer gender;
	
	private Department department;
	
	@Past
	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birth;
	
	@NumberFormat(pattern="#,###,###.#")
	private Float salary;

十七、以JSON格式将Bean对象传送至网页

	/*
	 * 以JSON格式将Bean对象传送至网页
	 * 1、加入jar包:jackson-annotations-2.1.5.jar、jackson-core-2.1.5.jar、jackson-databind-2.1.5.jar
	 * 2、在方法前加@ResponseBody注解:该注解会将方法返回值通过适当的HttpMessageConverter
	 *                                 转换为指定格式后,写入到Response对象的body数据区,即返回值会直接作为数据传至网页
	 * 附加知识->在方法参数前加@RequestBody注解:获取网页请求体(请求参数),包含请求头等。
	 */
	@ResponseBody
	@RequestMapping("getEmployees")
	public Collection<Employee> getEmployees(){
		return employeeDao.getAll();
	}
	@ResponseBody
	@RequestMapping(value="testRequestBody",method=RequestMethod.POST)
	public String testRequestBody(@RequestBody byte[] bytes) {
		System.out.println(new String(bytes));
		IOFile.getFile(bytes, "D:/", "myFile.txt");
		return "Return Time:"+new Date();
		
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值