spring4.1+springmvc4.1+mybatis3.2.8+spring-security3.2.5集成环境搭建

19 篇文章 0 订阅
12 篇文章 0 订阅

最近项目中用到了ssi+spring-security 的结构,自己在家搭建了一下这套环境。仅作记录。


项目结构:

类文件:                                                                                                             配置文件:                                                                                


视图:


使用的maven作为依赖管理,

以下为pom文件,包含所有项目所需jar 文件:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>archgroup</groupId>  
  5.     <artifactId>archbase</artifactId>  
  6.     <packaging>war</packaging>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <name>archbase Maven Webapp</name>  
  9.     <url>http://maven.apache.org</url>  
  10.     <repositories>  
  11.         <repository>  
  12.             <id>spring-milestones</id>  
  13.             <name>Spring Milestones</name>  
  14.             <url>http://repo.spring.io/milestone</url>  
  15.             <snapshots>  
  16.                 <enabled>false</enabled>  
  17.             </snapshots>  
  18.         </repository>  
  19.     </repositories>  
  20.     <properties>  
  21.         <org.springframework-version>4.1.0.RELEASE</org.springframework-version>  
  22.         <org.mabatis-version>3.2.8</org.mabatis-version>  
  23.         <org.springframework.security-version>3.2.5.RELEASE</org.springframework.security-version>  
  24.         <org.aspectj-version>1.8.1</org.aspectj-version>  
  25.         <org.slf4j-version>1.6.1</org.slf4j-version>  
  26.     </properties>  
  27.     <dependencies>  
  28.         <!-- Spring -->  
  29.         <dependency>  
  30.             <groupId>org.springframework</groupId>  
  31.             <artifactId>spring-context</artifactId>  
  32.             <version>${org.springframework-version}</version>  
  33.             <exclusions>  
  34.                 <!-- Exclude Commons Logging in favor of SLF4j -->  
  35.                 <exclusion>  
  36.                     <groupId>commons-logging</groupId>  
  37.                     <artifactId>commons-logging</artifactId>  
  38.                 </exclusion>  
  39.             </exclusions>  
  40.         </dependency>  
  41.         <dependency>  
  42.             <groupId>org.springframework</groupId>  
  43.             <artifactId>spring-jdbc</artifactId>  
  44.             <version>${org.springframework-version}</version>  
  45.         </dependency>  
  46.         <dependency>  
  47.             <groupId>org.springframework</groupId>  
  48.             <artifactId>spring-webmvc</artifactId>  
  49.             <version>${org.springframework-version}</version>  
  50.         </dependency>  
  51.         <!-- AspectJ -->  
  52.         <dependency>  
  53.             <groupId>org.aspectj</groupId>  
  54.             <artifactId>aspectjrt</artifactId>  
  55.             <version>${org.aspectj-version}</version>  
  56.         </dependency>  
  57.         <dependency>  
  58.             <groupId>org.aspectj</groupId>  
  59.             <artifactId>aspectjweaver</artifactId>  
  60.             <version>1.8.4</version>  
  61.         </dependency>  
  62.         <!-- Logging -->  
  63.         <dependency>  
  64.             <groupId>org.slf4j</groupId>  
  65.             <artifactId>slf4j-api</artifactId>  
  66.             <version>${org.slf4j-version}</version>  
  67.         </dependency>  
  68.         <dependency>  
  69.             <groupId>org.slf4j</groupId>  
  70.             <artifactId>jcl-over-slf4j</artifactId>  
  71.             <version>${org.slf4j-version}</version>  
  72.             <scope>runtime</scope>  
  73.         </dependency>  
  74.         <dependency>  
  75.             <groupId>org.slf4j</groupId>  
  76.             <artifactId>slf4j-log4j12</artifactId>  
  77.             <version>${org.slf4j-version}</version>  
  78.             <scope>runtime</scope>  
  79.         </dependency>  
  80.         <dependency>  
  81.             <groupId>log4j</groupId>  
  82.             <artifactId>log4j</artifactId>  
  83.             <version>1.2.16</version>  
  84.             <scope>runtime</scope>  
  85.         </dependency>  
  86.   
  87.         <!-- @Inject -->  
  88.         <dependency>  
  89.             <groupId>javax.inject</groupId>  
  90.             <artifactId>javax.inject</artifactId>  
  91.             <version>1</version>  
  92.         </dependency>  
  93.   
  94.         <dependency>  
  95.             <groupId>mysql</groupId>  
  96.             <artifactId>mysql-connector-java</artifactId>  
  97.             <version>5.1.34</version>  
  98.         </dependency>  
  99.         <dependency>  
  100.             <groupId>org.mybatis</groupId>  
  101.             <artifactId>mybatis</artifactId>  
  102.             <version>${org.mabatis-version}</version>  
  103.         </dependency>  
  104.         <dependency>  
  105.             <groupId>org.mybatis</groupId>  
  106.             <artifactId>mybatis-spring</artifactId>  
  107.             <version>1.2.2</version>  
  108.         </dependency>  
  109.         <dependency>  
  110.             <groupId>commons-dbcp</groupId>  
  111.             <artifactId>commons-dbcp</artifactId>  
  112.             <version>1.4</version>  
  113.         </dependency>  
  114.         <dependency>  
  115.             <groupId>javax.servlet</groupId>  
  116.             <artifactId>jstl</artifactId>  
  117.             <version>1.2</version>  
  118.         </dependency>  
  119.   
  120.         <!-- Servlet -->  
  121. <!--         <dependency>  
  122.             <groupId>org.apache.tomcat</groupId>  
  123.             <artifactId>tomcat-servlet-api</artifactId>  
  124.             <version>7.0.30</version>  
  125.             <scope>provided</scope>  
  126.         </dependency>  
  127.         <dependency>  
  128.             <groupId>javax.servlet.jsp</groupId>  
  129.             <artifactId>jsp-api</artifactId>  
  130.             <version>2.1</version>  
  131.             <scope>provided</scope>  
  132.         </dependency>  
  133.         <dependency>  
  134.             <groupId>javax.servlet.jsp.jstl</groupId>  
  135.             <artifactId>jstl-api</artifactId>  
  136.             <version>1.2</version>  
  137.             <exclusions>  
  138.                 <exclusion>  
  139.                     <groupId>javax.servlet</groupId>  
  140.                     <artifactId>servlet-api</artifactId>  
  141.                 </exclusion>  
  142.             </exclusions>  
  143.         </dependency>  
  144.         <dependency>  
  145.             <groupId>org.glassfish.web</groupId>  
  146.             <artifactId>jstl-impl</artifactId>  
  147.             <version>1.2</version>  
  148.             <exclusions>  
  149.                 <exclusion>  
  150.                     <groupId>javax.servlet</groupId>  
  151.                     <artifactId>servlet-api</artifactId>  
  152.                 </exclusion>  
  153.             </exclusions>  
  154.         </dependency> -->  
  155.   
  156.         <!-- File Upload -->  
  157.         <dependency>  
  158.             <groupId>commons-fileupload</groupId>  
  159.             <artifactId>commons-fileupload</artifactId>  
  160.             <version>1.2.2</version>  
  161.         </dependency>  
  162.         <dependency>  
  163.             <groupId>commons-io</groupId>  
  164.             <artifactId>commons-io</artifactId>  
  165.             <version>2.0.1</version>  
  166.         </dependency>  
  167.   
  168.         <!-- Security -->  
  169.         <dependency>  
  170.             <groupId>org.springframework.security</groupId>  
  171.             <artifactId>spring-security-web</artifactId>  
  172.             <version>${org.springframework.security-version}</version>  
  173.         </dependency>  
  174.         <dependency>  
  175.             <groupId>org.springframework.security</groupId>  
  176.             <artifactId>spring-security-config</artifactId>  
  177.             <version>${org.springframework.security-version}</version>  
  178.         </dependency>  
  179.         <!-- Test -->  
  180.         <dependency>  
  181.             <groupId>junit</groupId>  
  182.             <artifactId>junit</artifactId>  
  183.             <version>3.8.1</version>  
  184.             <scope>test</scope>  
  185.         </dependency>  
  186.     </dependencies>  
  187.     <build>  
  188.         <finalName>archbase</finalName>  
  189.     </build>  
  190. </project>  

spring 与mybatis 集成主要配置数据源、事务管理、sqlSessionFactory 以及sqlSession

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.      xmlns:tx="http://www.springframework.org/schema/tx"  
  6.      xmlns:aop="http://www.springframework.org/schema/aop"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd  
  9.           http://www.springframework.org/schema/tx  
  10.         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
  11.          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
  12.     ">  
  13.       
  14.     <context:property-placeholder location="classpath:system-config.properties"/>  
  15.     <!-- 数据源  -->  
  16.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
  17.         <property name="driverClassName" value="${driver}"></property>  
  18.         <property name="url" value="${url}"></property>  
  19.         <property name="username" value="${username}"></property>  
  20.         <property name="password" value="${password}"></property>  
  21.     </bean>  
  22.       
  23.     <!--  事务管理配置 -->  
  24.     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  25.         <property name="dataSource" ref="dataSource"></property>  
  26.     </bean>  
  27.       
  28.     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
  29.         <tx:attributes >  
  30.             <tx:method name="query*" propagation="REQUIRED" />  
  31.             <tx:method name="insert*" propagation="REQUIRED" />  
  32.             <tx:method name="update*" propagation="REQUIRED" />  
  33.         </tx:attributes>  
  34.     </tx:advice>  
  35.       
  36.     <aop:config >  
  37.         <aop:pointcut expression="execution(* com.arch.service.*.*(..))" id="service"/>  
  38.         <aop:advisor advice-ref="txAdvice" pointcut-ref="service"/>  
  39.     </aop:config>  
  40.       
  41.     <!-- 与mybatis集成  -->  
  42.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  43.         <property name="dataSource" ref="dataSource"></property>  
  44.         <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>  
  45.         <!-- mybatis配置文件自动扫描路径  -->  
  46.         <property name="mapperLocations" value="classpath:com/arch/dao/*/*.xml"></property>  
  47.     </bean>  
  48.       
  49.     <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">  
  50.         <constructor-arg index="0" name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>  
  51.           
  52.     </bean>  
  53.       
  54.     <!-- dao -->  
  55.     <bean id="commonDao" class="com.arch.dao.CommonDao">  
  56.         <property name="sqlSession" ref="sqlSession"></property>  
  57.     </bean>  
  58.       
  59.       
  60. </beans>  


springmvc使用注解,所以只需要配置扫描路径,视图处理器

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <!-- Maps '/' requests to the 'home' view -->  
  2. <mvc:view-controller path="/" view-name="index"/>  
  3.   
  4. <context:component-scan base-package="com.arch.view" />  

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <!-- Enables the Spring MVC @Controller programming model -->  
  2. <mvc:annotation-driven/>  
  3.   
  4. <resources mapping="/views/**" location="/views/" />  
  5.   
  6. <!-- Resolves views selected for rendering by @Controllers to .jsp resources   
  7.     in the /views directory -->  
  8. <beans:bean  
  9.     class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  10.     <beans:property name="prefix" value="/views/" />  
  11.     <beans:property name="suffix" value=".jsp" />  
  12. </beans:bean>  
  13.   
  14. <!-- Only needed because we require fileupload in the org.springframework.samples.mvc.fileupload   
  15.     package -->  
  16. <beans:bean id="multipartResolver"  
  17.     class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />  
  18.   
  19. <!-- Imports user-defined @Controller beans that process client requests -->  
  20. <beans:import resource="controllers.xml" />  
  21.   
  22. <task:annotation-driven />  


spring security 使用了自定义的user-service 以及csrf过滤器:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <beans:beans xmlns="http://www.springframework.org/schema/security"  
  2.     xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  4.            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  5.            http://www.springframework.org/schema/security  
  6.            http://www.springframework.org/schema/security/spring-security.xsd">  
  7.     <!-- 登录界面不使用权限过滤 -->  
  8.     <http security="none" pattern="/login*"></http>  
  9.     <http>  
  10.         <http-basic />  
  11.         <intercept-url pattern="/**" access="ROLE_USER" />  
  12.   
  13.         <!-- 登录界面 -->  
  14.         <form-login login-page="/login" default-target-url="/index"  
  15.             always-use-default-target="true" />  
  16.         <logout />  
  17.         <csrf />  
  18.     </http>  
  19.   
  20.     <!-- 自定义user-service -->  
  21.     <beans:bean id="userDetailService" class="com.arch.security.UserDetailService"></beans:bean>  
  22.   
  23.     <!-- 自定义权限管理,使用自己的user-service -->  
  24.     <authentication-manager>  
  25.         <authentication-provider user-service-ref="userDetailService"></authentication-provider>  
  26.     </authentication-manager>  
  27.   
  28.     <!-- CSRF protection. Here we only include the CsrfFilter instead of all   
  29.         of Spring Security. See http://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/#csrf   
  30.         for more information on Spring Security's CSRF protection -->  
  31.     <beans:bean id="csrfFilter" class="org.springframework.security.web.csrf.CsrfFilter">  
  32.         <beans:constructor-arg>  
  33.             <beans:bean  
  34.                 class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository" />  
  35.         </beans:constructor-arg>  
  36.     </beans:bean>  
  37.     <!-- Provides automatic CSRF token inclusion when using Spring MVC Form   
  38.         tags or Thymeleaf. -->  
  39.     <beans:bean id="requestDataValueProcessor"  
  40.         class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor" />  
  41. </beans:beans>   

然后就是web.xml文件了,spring 所需要的contextLoaderListener,spring-mvc需要的dispatchServlet 以及 spring-security和csrf所需要的两个过滤器

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
  5.     id="WebApp_ID" version="3.0">  
  6.   <display-name>Archetype Created Web Application</display-name>  
  7.   <context-param>  
  8.         <param-name>contextConfigLocation</param-name>  
  9.         <param-value>/WEB-INF/classes/spring/root-context.xml</param-value>  
  10.     </context-param>  
  11.   
  12.     <!-- Creates the Spring Container shared by all Servlets and Filters -->  
  13.     <listener>  
  14.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  15.     </listener>  
  16.     <filter>  
  17.         <filter-name>springSecurityFilterChain</filter-name>  
  18.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  19.     </filter>  
  20.     <filter-mapping>  
  21.         <filter-name>springSecurityFilterChain</filter-name>  
  22.         <url-pattern>/*</url-pattern>  
  23.     </filter-mapping>  
  24.   
  25.     <filter>  
  26.         <filter-name>csrfFilter</filter-name>  
  27.         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  28.         <async-supported>true</async-supported>  
  29.     </filter>  
  30.     <filter-mapping>  
  31.         <filter-name>csrfFilter</filter-name>  
  32.         <url-pattern>/*</url-pattern>  
  33.     </filter-mapping>  
  34.   
  35.     <!-- Processes application requests -->  
  36.     <servlet>  
  37.         <servlet-name>appServlet</servlet-name>  
  38.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  39.         <init-param>  
  40.             <param-name>contextConfigLocation</param-name>  
  41.             <param-value>/WEB-INF/classes/springweb/servlet-context.xml</param-value>  
  42.         </init-param>  
  43.         <load-on-startup>1</load-on-startup>  
  44.         <async-supported>true</async-supported>  
  45.     </servlet>  
  46.   
  47.     <servlet-mapping>  
  48.         <servlet-name>appServlet</servlet-name>  
  49.         <url-pattern>/</url-pattern>  
  50.     </servlet-mapping>  
  51. </web-app>  

然后就是mybatis的mapper文件:

userMapping.xml

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8" ?>    
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">   
  3. <mapper namespace="user.mapper">  
  4.     <select id="countAll" resultType="int">  <!-- 查询表中记录总数 -->  
  5.         select count(*) c from tb_user;  
  6.     </select>  
  7.       
  8.     <select id="selectAll" resultType="com.arch.domain.UserInfoVo">    <!-- 查询表中的所有用户 -->  
  9.         select * from tb_user order by username asc  
  10.     </select>  
  11.       
  12.     <insert id="insert" parameterType="com.arch.domain.UserInfoVo">    <!-- 向数据库中插入用户 -->  
  13.         insert into tb_user(id,username,password) values(#{id},#{username},#{password})  
  14.     </insert>  
  15.       
  16.     <update id="update" parameterType="com.arch.domain.UserInfoVo">     <!-- 更新库中的用户 -->  
  17.         update tb_user set username=#{username},password=#{password} where username=#{username}  
  18.     </update>  
  19.       
  20.     <delete id="delete" parameterType="String">    <!-- 删除用户 -->  
  21.         delete from tb_user where username=#{username}  
  22.     </delete>  
  23.       
  24.     <select id="findByUserName" parameterType="String" resultType="com.arch.domain.UserInfoVo"> <!-- 根据用户名查找用户 -->  
  25.         select * from tb_user where username=#{username}  
  26.     </select>  
  27. </mapper>  



配置到这里就已经完成了,然后就是类文件:

CommonDao:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public class CommonDao {  
  2.       
  3.     private SqlSession sqlSession;  
  4.       
  5.     public void setSqlSession(SqlSession sqlSession) {  
  6.         this.sqlSession = sqlSession;  
  7.     }  
  8.   
  9.     public List selectList(String statement, Object parameter ){  
  10.         return sqlSession.selectList(statement, parameter);  
  11.     }  
  12.       
  13.     public int insert(String statement, Object parameter){  
  14.         return sqlSession.insert(statement, parameter);  
  15.     }  
  16.   
  17. }  

UserInfoVo

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Repository  
  2. public class UserInfoVo implements UserDetails{  
  3.     private static final long serialVersionUID = -739110967197874283L;  
  4.     private String id;  
  5.     private String username;  
  6.     private String password;  
  7.     public String getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(String id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getUsername() {  
  14.         return username;  
  15.     }  
  16.     public void setUsername(String username) {  
  17.         this.username = username;  
  18.     }  
  19.     public String getPassword() {  
  20.         return password;  
  21.     }  
  22.     public void setPassword(String password) {  
  23.         this.password = password;  
  24.     }  
  25.     @Override  
  26.     public String toString() {  
  27.         return "UserInfoVo [username=" + username + ", password=" + password  
  28.                 + "]";  
  29.     }  
  30.     public Collection<? extends GrantedAuthority> getAuthorities() {  
  31.         /** 
  32.          * 测试,写死了角色 
  33.          */  
  34.         List<SimpleGrantedAuthority> authos = new ArrayList<>();  
  35.         SimpleGrantedAuthority sim = new SimpleGrantedAuthority("ROLE_USER");  
  36.         authos.add(sim);  
  37.         return authos;  
  38.     }  
  39.     public boolean isAccountNonExpired() {  
  40.         return true;  
  41.     }  
  42.     public boolean isAccountNonLocked() {  
  43.         return true;  
  44.     }  
  45.     public boolean isCredentialsNonExpired() {  
  46.         return true;  
  47.     }  
  48.     public boolean isEnabled() {  
  49.         return true;  
  50.     }  
  51.   
  52. }  

UserDetailService:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 这里传过来用户名,需要在此作验证,并返回实现了UserDetails接口的用户VO 
  3.  */  
  4. @Override  
  5. public UserDetails loadUserByUsername(String username){  
  6.     UserInfoVo user = new UserInfoVo();  
  7.     System.out.println(user);  
  8.     user.setUsername(username);  
  9.     user.setPassword("admin");  
  10.     return user;  
  11. }  

userServiceImpl:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Service("userService")  
  2. public class UserServiceImpl implements UserService {  
  3.       
  4.     @Autowired  
  5.     private CommonDao dao;  
  6.       
  7.     public List<UserInfoVo> listAll(UserInfoVo user) {  
  8.         List<UserInfoVo> users = dao.selectList("user.mapper.selectAll", user);  
  9.         return users;  
  10.     }  
  11.   
  12.     public int insert(UserInfoVo user) {  
  13.         int i = dao.insert("user.mapper.insert", user);  
  14.         return i;  
  15.     }  
  16. }  



LoginController:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @Controller  
  2. public class LoginController {  
  3.   
  4.     @Inject  
  5.     private UserService userService;  
  6.     @RequestMapping("index")  
  7.     public String index(){  
  8.         List<UserInfoVo> users = userService.listAll(new UserInfoVo());  
  9.         for(UserInfoVo u : users){  
  10.             System.out.println(u);  
  11.         }  
  12.         return "index";  
  13.     }  
  14.       
  15.     @RequestMapping("login")  
  16.     public String login(){  
  17.           
  18.         return "login";  
  19.     }  
  20. }  


以上。


下载地址:点击进入下载


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值