5.WEB及远程操作

1.Spring MVC总结

1.1 Spring MVC 框架请求处理流程

在这里插入图片描述
(1)整个过程始于客户端发出一个HTTP请求,Web应用服务器接收到这个请求。如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),则Web容器将该请求转交给DispatcherServlet处理。
(2) DispatcherServlet 接收到这个请求后,将根据请求的信息(包括URL、HTTP方法、请求报文头、请求参数、Cookie 等)及HandlerMapping的配置找到处理请求的处理器(Handler)。 可将HandlerMapping看作路由控制器,将Handler看作目标主机。
值得注意的是,在Spring MVC中并没有定义-一个Handler接口,实际上,任何一个Object都可以成为请求处理器。
(3) 当DispatcherServlet根据HandlerMapping得到对应当前请求的Handler后,通过HandlerAdapter对Handler 进行封装,再以统一的适配器接口调用Handler。HandlerAdapter是Spring MVC的框架级接口,顾名思义,HandlerAdapter是一个适配器,它用统一的接口对各种Handler方法进行调用。
(4)处理器完成业务逻辑的处理后将返回一个ModelAndView给DispatcherServlet,ModelAndView包含了视图逻辑名和模型数据信息。
(5 ) ModelAndView 中包含的是“逻辑视图名”而非真正的视图对象,DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作。
(6)当得到真实的视图对象View 后,DispatcherServlet 就使用这个View 对象对ModelAndView中的模型数据进行视图渲染。
(7)最终客户端得到的响应消息可能是-一个普通的HTML页面,也可能是一个XML或JSON串,甚至是一-张图片或-一个PDF文档等不同的媒体形式。

1.2 Spring MVC框架包含内容

注解驱动控制器、请求及响应的信息处理、视图解析、本地化解析、上传文件解析、异常处理及表单标签绑定等内容。
Spring MVC定义了一套默认的组件实现类,即使在Spring容器中没有显式定义组件Bean, DispatcherServlet也会装配好一套可用的默认组件。在spring webmvc-4.x.jar包的org/springframework/web/servlet 类路径下拥有一个DispatcherServlet.properties配置文件,该文件指定了DispatcherServlet 所使用的默认组件。如视图解析器、异常处理器等。

1.3 Spring MVC 核心

1.3.1 DispatcherServlet

DispatcherServlet是Spring MVC的“灵魂”和“心脏”,它负责接收HTTP请求并协调Spring MVC的各个组件完成请求处理的工作。和任何Servlet 一样,用户必须在web.xml中配置好DispatcherServlet。

1.3.2 WebApplicationContext与ApplicationContext

1.3.2.1 BeanFactory

BeanFactory:Spring的IoC容器。是Spring创建并管理各类的对象的类工厂,是Spring框架的核心。
Spring通过一个配置文件描述Bean及Bean之间的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IoC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean 实例代理、事件发布、资源装载等高级服务。

1.3.2.2 ApplicationContext

ApplicationContext:应用上下文。应用上下文(com.springframework.context.ApplicationContext) 建立在BeanFactory基础之上,提供了更多面向应用的功能,它提供了国际化支持和框架事件体系,更易于创建实际应用。我们一般称BeanFactory为loC容器,而称ApplicationContext为应用上
下文。但有时为了行文方便,我们也将ApplicationContext称为Spring容器。
对于二者的用途,我们可以进行简单的划分: BeanFactory 是Spring框架的基础设施,面向Spring本身; ApplicationContext 面向使用Spring框架的开发者,几乎所有的应用场合都可以直接使用ApplicationContext而非底层的BeanFactory。
ApplicationContext的主要实现类是ClassPathXmlApplicationContext 和FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。

1.3.2.3 WebApplicationContext

WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便Web应用环境可以访问Spring 应用上下文。Spring 专门为此提供了一个工具类WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc)方法,可以从ServletContext中获取WebApplicationContext实例。
在非Web应用的环境下,Bean只有singleton和prototype两种作用域。WebApplicationContext为Bean添加了三个新的作用域: request、ssion和global session。
WebApplicationContext的初始化方式和BeanFactory、ApplicationContext 有所区别,因为WebApplicationContext需要ServletContext实例,也就是说,它必须在拥有Web容器的前提下才能完成启动工作。通过在web.xml中配置自启动的Servlet 或定义Web容器监听器( ServletContextListener),借助二者中的任何一个,就可以完成启动Spring Web应用上下文的工作。

1.4 Spring MVC开发流程

Spring MVC应用开发一般包括以下几个步骤。
(1)配置web.xml, 指定业务层对应的Spring配置文件,定义DispatcherServlet。
(2)编写处理请求的控制器(处理器)。
(3)编写视图对象,如JSP、HTML文件等。
(4)配置Spring MVC的配置文件,使控制器、视图解析器等生效。

1.5 驱动注解控制器

@Controller

在POJO类定义处标注@Controller,再通过context:component-scan/扫描相应的类包,即可使POJO成为一一个能处理HTTP请求的控制器。

@RequestMapping

    在控制器的类定义及方法定义处都可以标注@RequestMapping,类定义处的@RequestMapping提供初步的请求映射信息,方法定义处的@RequestMapping提供进一
步的细分映射信息。DispatcherServlet 截获请求后,就通过控制器上@RequestMapping提供的映射信息确定诸求所对应的外理方法。
    @RequestMapping不但支持标准的URL,还支持Ant 风格(?、*和**字符,和带{xxx}占位符的URL。如

  1. /user/*/createUser: 匹配/user/a/createUser. /user/bbb/createUser 等URL。
  2. /user/**/createUser:匹配/user/createUser、 /user/abbb/createUser 等URL。
  3. /user/createUser??: 匹配/user/createUseraa、 /user/createUserbb 等URL。
  4. /user/ {userld}:匹配user/123、user/456 等URL。
  5. /user/**/{userld}:匹配userlaabbb/123、user/aa/456 等URL。
  6. company/{companyld}/user/ {userId}/detail:匹配company/123/user/456/detail 等
    URL。

通过@PathVariable可以将URL中的占位符参数绑定到控制器处理方法的入参中。
    @RequestMapping的value、method、 params 及headers 分别表示请求URL、请求方法、请求参数及报文头的映射条件,它们之间是与的关系,联合使用多个条件项可让请求映射更加精确化。
    params和headers分别通过请求参数及报文头属性进行映射,它们支持简单的映射
表达式。下面以 params表达式为例进行说明,headers 可以参照params来理解。

  1. “paraml”: 表示请求须包含名为paraml的请求参数。
  2. “!paraml”: 表示请求不能包含名为paraml的请求参数。
  3. “paraml!=valuel”: 表示请求包含名为paraml的请求参数,但其值不能为valuel.
  4. {“param1=value1”,“param2”}: 表示请求必须包含名为paraml和param2的两个请求参数,且param1参数的值必须为value1.

其他请求处理方法签名注解

@RequestBody

用于方法签名中,将请求报文体转换为字符串绑定到requestBody标注的入参中。
Spring MVC根据requestBody的类型查找匹配的HttpMessageConverter,如果入参类型为String,由于StringHtpMessageConverter 的泛型类型对应String, 所以StringHtpMessageConverter将被SpringMVC选中,用它将请求体信息进行转换并将结果绑定到requestBody入参上。

@RequestMapping (path = "/hand1e41")
public String handle41(@RequestBody String requestBody){
	System.out.println(requestBody);
	return "success";
}
@ResponseBody

用于标注请求方法。将return返回的对象输出到客户端。当方法返回值类型为byte[],Spring MVC根据类型匹配的查找规则将使用ByteArrayHtpMessageConverter对返回值进行处理,即将byte[]内数据流输出到客户端。

@ResponseBody
@RequestMapping (path = "/handle42/{imageId}")
public byte[] handle42 (@PathVariable("imageId") String imageId) throws IOException{
	System.out.println("load image of "+imageId) ;
	Resource res = new ClassPathResource ("/image.jpg") ;
	byte[] fileData = FileCopyUtils.copyToByteArray(res.getInputStream());
	return fileData;
}
@RequestParam

用于方法签名中,绑定请求参数值。

  1. value: 参数名。
  2. required: 是否必需,默认为true, 表示请求中必须包含对应的参数名,如果不存在则抛出异常。
@RequestMapping(path = "/hand1e11")
public String handle11(
@RequestParam(value = "userName", required = false) String userName,
@RequestParam("age") int age){
    ...
}
@CookieValue

使用@CookieValue可让处理方法入参绑定某个Cookie的值,它和@RequestParam拥有3个- -样的参数。来看一个使用@CookieValue的实例,代码如下:

@RequestMapping (path = "/handle12")
public String handle12 (
@CookieValue (value =”sessionId",required false) String sessionId,
@RequestParam("age") int age){
...
)
@RequestHeader

@RequestHeader可将报文头属性值绑定到处理方法的入参中

@RequestMapping (path = " /handle13")
public String handle13 (@RequestHeader("Accept -Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
    ....
}
使用命令/表单对象绑定请求参数值

SpringMVC会按请求参数名和命令/表单对象属性名匹配的方式,自动为该对象填充属性值。支持级联的属性名,如dept.deptld、dept.address.tel 等。

@RequestMapping (path = "/handle14")
public String handle14 (User user) {
}
使用Servlet API对象作为入参

在Spring MVC中,控制器类可以不依赖任何Servlet API对象,但是Spring MVC并不能阻止我们使用Servlet API的类作为处理方法的入参。以下处理方法都可以正确地工作。

@RequestMapping (path = "/handle21")
public void handle21 (HttpServ1etRequest request , HttpServletResponse response) {
    String userName = Webutils.findParameterValue(request, "userName");
    response.addCookie(new Cookie ("userName", userName));
}
使用I/0对象作为入参

    Servlet的ServletRequest拥有getInputStream()和getReader(方法,可以通过它们读取请求的信息。相应的,Servlet 的ServletResponse拥有getOutputStream()和getWriter()方法,可以通过它们输出响应信息。
 Spring MVC允许控制器的处理方法使用java.io.InputStream/java.io.Reader 及
java.io.OutputStream/java.io.Writer作为方法的入参,Spring MVC将获取ServletRequest
的InputStream/Reader或ServletResponse 的OutputStream/Writer,然后传递给控制器的
处理方法。

@RequestMapping (path = "/handle31")
public void handle31 (OutputStream os) throws IOException{
    Resource res = new ClassPathResource ("/image. jpg");//读取类路径下的图片文件
    FileCopyutils.copy (res.getInputStream(), os);//将图片写到输出流中
}

传参到视图的方法

    对于MVC框架来说,模型数据是最重要的,因为控制(C)是为了产生模型数据(M),而视图(V)则是为了渲染模型数据。
    Spring MVC通过@RequestMapping将请求引导到处理方法上,使用合适的方法签名将请求消息绑定到入参中,根据入参执行相应的逻辑,产生模型数据,导向到特定视图中。将模型数据暴露给视图是SpringMVC框架的一项重要工作。SpringMVC提供了多种途径输出模型数据,介绍如下。

  1. ModelAndView:当处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据。
  2. @ModelAttribute:在方法入参标注该注解后,入参的对象就会放到数据模型中。
  3. Map及Model:如果方法入参为org. springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map,则当处理方法返回时,Map中的数据会自动添加到模型中。
  4. @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求
    之间可以共享这个属性。
@RequestMapping("testModel1")
    public ModelAndView testModel1(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("freemarkTest");
        mv.addObject("name", "海粟");
        return mv;
    }

    @RequestMapping("testModel2")
    public String testModel2(@ModelAttribute("name") String name){
        return "freemarkTest";
    }

    //在访问TestController中的任何一个请求处理方法前,SpringMVC先执行getUser方法,并将返回值以user为键添加到模型中
    //然后,模型数据会赋给User的入参,然后再根据HTTP请求消息进一步填充覆盖user对象
    @RequestMapping("testModel3")
    public String testModel3(@ModelAttribute("user") HashMap user){
        return "freemarkTest";
    }

    @ModelAttribute("user")
    public HashMap getUser(){
        HashMap map = new HashMap();
        map.put("name", "name3");
        map.put("age", "21");
        return map;
    }

    @RequestMapping("testModel4")
    public String testModel4(Map map){
        map.put("name", "name4");
        map.put("age", "22");
        return "freemarkTest";
    }

    @RequestMapping("testModel5")
    public String testModel5(Model model){
        model.addAttribute("name", "name5");
        model.addAttribute("age", "24");
        return "freemarkTest";
    }

    @RequestMapping("testModel6")
    public String testModel6(ModelMap modelMap){
        modelMap.put("name", "name6");
        modelMap.put("age", "23");
        return "freemarkTest";
    }

1.6 视图和视图解析器

     请求处理方法执行完成后,最终返回-一个ModelAndView对象。对于那些返回String、View或ModelMap等类型的处理方法,SpringMVC也会在内部将它们装配成一个ModelAndView对象,该对象包含了视图逻辑名和模型对象的信息。
     Spring MVC借助视图解析器( ViewResolver)得到最终的视图对象(View), 这可能是我们常见的JSP视图,也可能是-一个基于FreeMarker、Velocity 模板技术的视图,还可能是PDF、Excel、 XML、JSON等各种形式的视图。
     对于最终究竟采取何种视图对象对模型数据进行渲染,处理器并不关心,处理器的工作重点聚焦在生产模型数据的工作.上,从而实现MVC的充分解耦。

1.6.1 视图

     视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。视图对象可以是常见的JSP,还可以是Excel或PDF等形式不一的媒体形式。为了实现视图模型和具体实现技术的解耦,Spring 在org.springframework.web.servlet包中定义了一个高度抽象的View接口,不同类型的视图实现技术对应不同的View实现类,这些视图实现类都位于org.springframework.web.servlet.view包中。
     视图对象是一个Bean, 通常情况下,视图对象由视图解析器负责实例化。由于视图Bean是无状态的,所以它们不会有线程安全的问题。

大类视图类型说明
URL资源视图InternalResourceView将JSP或其他资源封装成一个视图,这是InternalResourceViewResolver默认使用的视图实现类
URL资源视图JstlView如果JSP文件中使用了JSTL国际化标签的功能,则需要使用该视图类,而非IntermalResourceView视图类
文档视图AbstractExcelViewExcel文档视图的抽象类,开发者可以通过该抽象类实现自己的Excel文档视图。该视图实现类基于POI构造Excel文档
文档视图AbstractPdfViewPDF文档视图的抽象类,可以通过该抽象类实现自己的PDF文档视图。该视图实现类基于iText构造PDF文档
模板视图FreeMarkerView使用FreeMarker模板引擎的视图
XML视图MarshallingView通过oxm的Marshaller 技术将模型数据以XML方式输出
JSON视图MappingJackson2JsonView将模型数据通过Jackson 开源框架的ObjectMapper以JSON方式输出

1.6.2 视图解析器

     Spring MVC为逻辑视图名的解析提供了不同的策略,可以在Spring Web上下文中配置一种或多种解析策略,并指定它们之间的先后顺序。每种解析策略对应一个具体的视图解析器实现类。视图解析器的工作比较单一, 即将逻辑视图名解析为一个具体的视图对象。所有视图解析器都实现了ViewResolver 接口,该接口仅有一个方法。resolveViewName()方法的签名清楚地向我们传达了视图解析器工作的内涵:根据逻辑视图名和本地化对象得到一个视图对象。

View resolveViewName (String viewName, Locale locale)

     用户可以选择一种视图解析器或混用多种视图解析器,每个视图解析器都实现了Ordered接口并开放出 一个orderNo属性,可以通过该属性指定解析器的优先顺序,值越小优先级越高。有些视图解析器默认为最高优先级(如ContentNegotiatingViewResolver),
而有些视图解析器默认为最低优先级(如IntermalResourceViewResolver、 XsItViewResolver
等),具体请参考API文档。
     Spring MVC会按照视图解析器的优先级顺序对逻辑视图名进行解析,直到解析成功并返回视图对象,否则将抛出ServletException异常。

视图解析器类型说 明
解析为Bean名字BeanNameViewResolver将逻辑视图名解析为一个Bean, Bean 的id等于逻辑视图名和BeanNameViewResolver类似,只不过目标视图Bean对象
解析为Bean名字XmlViewResolver定义在一个独立的XML文件中,而非定义在DispatcherServlet上下文的主配置文件中
国际化解析ResourceBundleViewResolver在国际化资源文件中定义视图实现类及相关的信息。使用该视图解析器可以为不同的本地化类型提供不同的解析结果
解析为URL文件IntemalResourceViewResolver将视图名解析为一个URL文件,一般使用该解析器将视图名映射为保存在WEB-INF目录中的程序文件(如JSP)
解析为URL文件XsItViewResolver将视图名解析为-一个指定XSLT样式表的URL文件
解析为URL文件JasperReportsViewResolverJasperReports是-一个基于Java的开源报表工具,该解析器将视图名解析为报表文件所对应的URL
模板文件视图FreeMarkerViewResolver解析为基于FreeMarker模板技术的模板文件
模板文件视图VelocityViewResolver解析为基于Velocity模板技术的模板文件
模板文件视图VelocityLayoutViewResolver解析为基于Velocity模板技术的模板文件
内容协商ContentNegotiatingViewResolver它不负责具体的视图解析,而是作为一个中间人的角色根据请求所要求的MIME类型,从上下文中选择一个适合的视图解析器,再将视图解析工作委托其负责

1.6.3 视图解析器混用示例

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        ">
    <!--开启注解扫描-->
    <!--开启注解扫描 无此配置也可扫描Controller和RequestMapping,但无法识别单独的统一异常处理类WebExceptionHandle-->
    <mvc:annotation-driven/>
    <!--指定扫描路径-->
    <context:component-scan base-package="com.fxy.spring.mvc"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="100"/>

    <!-- FreeMarker基础设施及视图解析器配置 -->
    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"
            p:templateLoaderPath="/WEB-INF/ftl" p:defaultEncoding="UTF-8">
        <property name="freemarkerSettings">
            <props>
                <prop key="classic_compatible">true</prop>
            </props>
        </property>
    </bean>

    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
            p:order="5" p:suffix=".ftl" p:contentType="text/html; charset=utf-8"/>
</beans>

1.7 文件上传

    Spring MVC为文件上传提供了直接支持,这种支持是通过即插即用的MultipartResolver实现的。Spring使用Jakarta Commons FileUpload技术实现了一个MultipartResolver 实现类: CommonsMultipartResolver。
    在Spring MVC上”下文中默认没有装配MultipartResolver,因此默认情况下不能处理文件的上传工作。如果想使用Spring 的文件上传功能,则需要先在上下文中配置MultipartResolver。

<!-- 文件上传 -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
          p:defaultEncoding="UTF-8"
          p:maxUploadSize="5000000"
          p:uploadTempDir="upload/temp"/>    
@RequestMapping(value = "/upload")
   public String updateThumb(@RequestParam("name") String name,
   		                  @RequestParam("file") MultipartFile file) throws Exception{
   	if (!file.isEmpty()) {
   		file.transferTo(new File("d:/temp/"+file.getOriginalFilename()));
   		return "redirect:success.html";
   	}else{
   		return "redirect:fail.html";
   	}
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
远程连接服务器是通过网络连接到远程服务器的过程,可以使用不同的协议和工具来实现。对于Web开发,常见的远程连接服务器的方式有以下几种: 1. SSH(Secure Shell):SSH是一种网络协议,可以在不安全的网络上为远程登录会话和其他网络服务提供安全性。通过SSH,可以在本地计算机上使用终端或SSH客户端连接到远程服务器,并执行命令、上传文件等操作。这种方式需要在服务器上配置SSH服务,并且需要知道服务器的IP地址、用户名和密码。在终端或SSH客户端中输入相应的命令即可连接到服务器。 2. FTP(File Transfer Protocol):FTP是一种用于在客户端和服务器之间传输文件的协议。可以使用FTP客户端软件如FileZilla等连接到远程服务器,并在本地和服务器之间传输文件。这种方式需要在服务器上配置FTP服务,并且需要知道服务器的IP地址、用户名和密码。 3. SFTP(SSH File Transfer Protocol):SFTP是SSH协议的一部分,用于在客户端和服务器之间进行安全的文件传输。SFTP提供了比FTP更高级的安全性和功能。可以使用SFTP客户端软件如WinSCP等连接到远程服务器,并进行文件传输。这种方式需要在服务器上配置SSH服务,并且需要知道服务器的IP地址、用户名和密码。 4. Web控制台:有些云服务提供商(如AWS、阿里云等)会提供Web控制台,可以通过浏览器直接登录到远程服务器。通过Web控制台,可以执行命令、管理文件、配置服务器等操作。这种方式需要在云服务提供商的平台上创建服务器实例,并通过Web控制台登录。 总之,远程连接服务器的方式取决于服务器的配置和使用需求。根据具体情况选择合适的协议和工具进行远程连接,以方便进行代码编写、文件传输和服务器管理等操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [远程连接服务器](https://blog.csdn.net/Lucky_Lu0/article/details/121768657)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [如何远程连接服务器](https://blog.csdn.net/qq_44689208/article/details/125815820)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值