mvc架构编写顺序(mvc模式)

每个程序员在第一次这个行业时学习的第一个框架应该是ssm其他学习框架都是后期工作,随着业务的不断复杂,在工作中bug不断成长,但最经典的应该是开始ssm框架吧

当时,当我第一次学习这个时候,我觉得好牛,这样我就可以实现一个网站。这群伟大的神是怎么做到的?嘿嘿嘿,我不知道你当时是否有这样的问题,所以今天我会带你去建一个简单的MVC框架,从原理开始,也可以帮助你更好地理解底层源代码

好了,话不多说,我们来看看。

Springmvc流程的基本原理

mvc架构编写顺序(mvc模式)

SpringMvc本质上是对的servlet的封装。

因为创造一个maven项目,然后在pom在文件中增加依赖:

<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <!– 在服务器部署时,不使用此服务器servlet-api 而使用tomcat的–> <scope>provided</scope></dependency>

2,创建DispatcherServlet,并注册到web.xml中

package com.dxh.edu.mvcframework.servlet;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class DxhDispatcherServlet extends HttpServlet { /** * 接收处理请求 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }}

web.xml:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>dxhmvc</servlet-name> <servlet-class>com.dxh.edu.mvcframework.servlet.DxhDispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>springmvc.properties</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dxhmvc</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping></web-app>2,注解开发

因为要使用注释,首先要定制几个注释:

这里就不赘述如何定制注释了。详情请看:https://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

Controller注解:

@Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface DxhController { String value() default "";}

service注解:

@Documented@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface DxhService { String value() default "";}

RequestMapping注解:

@Documented@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface DxhRequestMapping { String value() default "";}

Autowired注解:

@Documented@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface DxhAutowired { String value() default "";}编写测试代码:

我们把测试代码放在同一个项目中com.dxh.demo包中:

package com.dxh.demo.controller;import com.dxh.demo.service.IDemoService;import com.dxh.edu.mvcframework.annotations.DxhAutowired;import com.dxh.edu.mvcframework.annotations.DxhController;import com.dxh.edu.mvcframework.annotations.DxhRequestMapping;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@DxhController@DxhRequestMapping("/demo")public class DemoController { @DxhAutowired private IDemoService demoService; /** * URL:/demo/query */ @DxhRequestMapping("/query") public String query(HttpServletRequest request, HttpServletResponse response, String name){ return demoService.get(name); }}

package com.dxh.demo.service;public interface IDemoService { String get(String name);}

package com.dxh.demo.service.impl;import com.dxh.demo.service.IDemoService;import com.dxh.edu.mvcframework.annotations.DxhService;@DxhService("demoService")public class IDemoServiceImpl implements IDemoService { @Override public String get(String name) { System.out.println("Service实现类中的Name:"+ name); return name; }}目录结构:

mvc架构编写顺序(mvc模式)

三、写自定义DispatcherServlet初始化过程:

在创建好的DxhDispatcherServlet中重写init()方法,并在init初始配置:

加载配置文件 springmvc.properties扫描相关类别-扫描注释初始化Bean对象(实现ioc依靠注入构建容器,基于注释)handleMapping处理器映射器将配置好url和method建立映射关系

@Overridepublic void init(ServletConfig config) throws ServletException { //1. 加载配置文件 springmvc.propertiesn String contextConfigLocation = config.getInitParameter("contextConfigLocation");n doLoadConfig(contextConfigLocation);n //2. 扫描相关的类——扫描注解n doScan("");n //3. 初始化Bean对象(实现IOC容器,基于注解)n doInstance();n //4. 实现依赖注入n doAutoWired();n //5. 构造一个handleMapping处理器映射器,将配置好的url和method建立映射关系n initHandleMapping();n System.out.println("MVC 初始化完成");n //6. 等待请求进入处理请求n}n

以及5个空方法,这篇文章自定义MVC框架其实就是需要对这5个步骤的编写。

//TODO 5,构造一个映射器nprivate void initHandleMapping() {n}n//TODO 4,实现依赖注入nprivate void doAutoWired() {n}n//TODO 3,IOC容器nprivate void doInstance() {n}n//TODO 2,扫描类nprivate void doScan(String scanpackage) {n}n//TODO 1,加载配置文件nprivate void doLoadConfig(String contextConfigLocation) {n}n3.1 加载配置文件首先在resource目录中创建一个配置文件——springmvc.properties表示要扫描com.dxh.demo下的所有注解。然后在web.xml中进行配置:

这样,就可以通过config.getInitParameter("contextConfigLocation")获得这个路径。

mvc架构编写顺序(mvc模式)

在DxhDispatcherServlet中定义一个属性,我们把加载后的配置文件中的信息,存储在Properties 中

private Properties properties = new Properties();;n

//1,加载配置文件nprivate void doLoadConfig(String contextConfigLocation) {n //根据指定路径加载成流:n InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);n try {n properties.load(resourceAsStream);n } catch (IOException e) {n e.printStackTrace();n }n}n3.2 扫描相关的类,扫描注解上一步骤,我们已经把需要扫描的包存在Properties中,所以这里需要取出:

//2. 扫描相关的类——扫描注解ndoScan(properties.getProperty("scanPackage"));n把扫描到的类型的全类名存在一个List中缓存起来,等待使用,在DxhDispatcherServlet中定义一个list:

//缓存扫描到的类的全类名nprivate List<String> classNames = new ArrayList<>();n从配置文件中我们得到了一个需要扫描的包名(com.dxh.demo),我们需要根据classPath+包名,来得到它实际上在磁盘上存的路径,然后递归,直到把所有的该包下(包括子包…)所有的类文件(.class结尾)。然后存在在List classNames中。

//2,扫描类n//scanPackage :com.dxh.demo package—>磁盘的文件夹(File)nprivate void doScan(String scanPackage) {n //1.获得classPath路径n String clasPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();n //2.拼接,得到scanPackage在磁盘上的路径n String scanPackagePath= clasPath + scanPackage.replaceAll("\\.","/");n File pack = new File(scanPackagePath);n File[] files = pack.listFiles();n for (File file : files) {n if (file.isDirectory()){ //子 packagen //递归n doScan(scanPackage+"."+file.getName()); //com.dxh.demo.controllern }else if(file.getName().endsWith(".class")){n String className = scanPackage + "." + file.getName().replace(".class", "");n classNames.add(className);n }n }n}n3.3 初始化Bean对象(实现IOC容器,基于注解)

上一步骤我们把扫描到的类的全类名放到了,list中,那么本次步骤需要遍历整个list:

遍历List,依次得到所有的全类名通过反射得到类对象根据类对象判断有没有注解,并区分controller和servicecontroller,它的id此处不做过多处理,不取value了,用类的首字母小写作为id,保存到IOC容器中。service,service层往往是有接口的,再以接口名为id再存入一份bean到ioc,便于后期根据接口类型注入完成

代码实现:

//IOC容器nprivate Map<String,Object> ioc = new HashMap<>();n

//3,IOC容器n//基于classNames缓存的类的全限定类名,以及反射技术,完成对象创建和管理nprivate void doInstance() {n if (classNames.size()==0) return;n try{n for (int i = 0; i < classNames.size(); i++) {n String className = classNames.get(i); //com.dxh.demo.controller.DemoControllern //反射n Class<?> aClass = Class.forName(className);n //区分controller ,区分servicen if (aClass.isAnnotationPresent(DxhController.class)){n //controller的id此处不做过多处理,不取value了,用类的首字母小写作为id,保存到IOC容器中n String simpleName = aClass.getSimpleName();//DemoControllern String lowerFirstSimpleName = lowerFirst(simpleName); //demoControllern Object bean = aClass.newInstance();n ioc.put(lowerFirstSimpleName,bean);n }else if (aClass.isAnnotationPresent(DxhService.class)){n DxhService annotation = aClass.getAnnotation(DxhService.class);n //获取注解的值n String beanName = annotation.value();n //指定了id就以指定的id为准n if (!"".equals(beanName.trim())){n ioc.put(beanName,aClass.newInstance());n }else{n //没有指定id ,首字母小写n String lowerFirstSimpleName = lowerFirst(aClass.getSimpleName());n ioc.put(lowerFirstSimpleName,aClass.newInstance());n }n //service层往往是有接口的,再以接口名为id再存入一分bean到ioc,便于后期根据接口类型注入n Class<?>[] interfaces = aClass.getInterfaces();n for (Class<?> anInterface : interfaces) {n //以接口的类名作为id放入。n ioc.put(anInterface.getName(),aClass.newInstance());n }n }else {n continue;n }n }n }catch (Exception e){n e.printStackTrace();n }n}n3.4 实现依赖注入:

上一步骤把所有需要加载的bean,存入了ioc Map中,此时,我们就需要遍历这个map然后依次得到每个bean对象,然后判断对象中有没有被@****DxhAutowired修饰的属性。

遍历ioc这个map,得到每个对象获取对象的字段(属性)信息判断字段是否被@DxhAutowired修饰判断@DxhAutowired有没有设置value值有,直接从ioc容器中取出,然后设置属性。无,需要根据当前字段的类型注入(接口注入)

代码实现:

//4,实现依赖注入nprivate void doAutoWired() {n if (ioc.isEmpty()){return;}n //1,判断容器中有没有被@DxhAutowried注解的属性,如果有需要维护依赖注入关系n for (Map.Entry<String,Object> entry: ioc.entrySet()){n //获取bean对象中的字段信息n Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();n for (Field declaredField : declaredFields) {n if (!declaredField.isAnnotationPresent(DxhAutowired.class)){n continue;n }n //有该注解:n DxhAutowired annotation = declaredField.getAnnotation(DxhAutowired.class);n String beanName = annotation.value(); //需要注入的bean的Idn if ("".equals(beanName.trim())){n //没有配置具体的beanId,需要根据当前字段的类型注入(接口注入) IDemoServicen beanName = declaredField.getType().getName();n }n //开启赋值n declaredField.setAccessible(true);n try {n //字段调用,两个参数:(哪个对象的字段,传入什么)n declaredField.set(entry.getValue(),ioc.get(beanName));n } catch (IllegalAccessException e) {n e.printStackTrace();n }n }n }n}n3.5 构造一个handleMapping处理器映射器

构造一个handleMapping处理器映射器,将配置好的url和method建立映射关系****。

手写MVC框架最关键的环节

假设有一个:

mvc架构编写顺序(mvc模式)

那么如何通过/demo/query定位到 DemoController类中的query这个方法 ?

之前我们所有被@DxhController(自定义Controller注解)的类,都存在了ioc 这个map中。我们可以遍历这个map,得到每个bean对象然后判断是否被@DxhController所修饰(排除@DxhService所修饰的bean)然后判断是否被@DxhRequestMapping所修饰,有的话,就取其value值,作为baseUrl然后遍历该bean对象中的所有方法,得到被@DxhRequestMapping修饰的方法。得到其value值,作为methodUrl。baseUrl + methodUrl = url我们把url和当前method绑定起来,存在map中,也就是建立了url和method建立映射关系。代码实现:

//handleMapping ,存储url和method直接的映射关系nprivate Map<String,Object> handleMapping = new HashMap<>();n

//5,构造一个映射器,将url和method进行关联nprivate void initHandleMapping() {n if (ioc.isEmpty()){return;}n for (Map.Entry<String,Object> entry: ioc.entrySet()){n //获取ioc中当前遍历对象的class类型n Class<?> aClass = entry.getValue().getClass();n //排除非controller层的类n if (!aClass.isAnnotationPresent(DxhController.class)){n continue;n }n String baseUrl = "";n if (aClass.isAnnotationPresent(DxhRequestMapping.class)){n //Controller层 类上 注解@DxhRequestMapping中的value值n baseUrl = aClass.getAnnotation(DxhRequestMapping.class).value();n }n //获取方法n Method[] methods = aClass.getMethods();n for (Method method : methods) {n //排除没有@DxhRequestMapping注解的方法n if (!method.isAnnotationPresent(DxhRequestMapping.class)){continue;}n //Controller层 类中方法上 注解@DxhRequestMapping中的value值n String methodUrl = method.getAnnotation(DxhRequestMapping.class).value();n String url = baseUrl+methodUrl;n //建立url和method之间的映射关系,用map缓存起来n handleMapping.put(url,method);n }n }n}n4,测试一下:

到目前位置,还没有完全写完,但是不妨碍我们测试一下看看刚才写的那部分内容有没有什么问题:

完整的pom文件:

<?xml version="1.0" encoding="UTF-8"?>n<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"n xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">n <modelVersion>4.0.0</modelVersion>n <groupId>com.dxh.edu</groupId>n <artifactId>mvc</artifactId>n <version>1.0-SNAPSHOT</version>n <packaging>war</packaging>n <name>mvc Maven Webapp</name>n <url>http://www.example.com</url>n <properties>n <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>n <maven.compiler.source>11</maven.compiler.source>n <maven.compiler.target>11</maven.compiler.target>n </properties>n <dependencies>n <dependency>n <groupId>junit</groupId>n <artifactId>junit</artifactId>n <version>4.12</version>n <scope>test</scope>n </dependency>n <dependency>n <groupId>javax.servlet</groupId>n <artifactId>servlet-api</artifactId>n <version>2.5</version>n <!– 部署在服务器时,不使用这个servlet-api 而使用tomcat的–>n <scope>provided</scope>n </dependency>n </dependencies>n <build>n <plugins>n <plugins>n <!– 编译插件定义编译细节–>n <plugin>n <groupId>org.apache.maven.plugins</groupId>n <artifactId>maven-compiler-plugin</artifactId>n <version>3.2</version>n <configuration>n <source>11</source>n <target>11</target>n <encoding>utf-8</encoding>n <!– 告诉编译器,编译的时候记录下形参的真实名称–>n <compilerArgs>n <arg>-parameters</arg>n </compilerArgs>n </configuration>n </plugin> n <plugin>n <groupId>org.apache.tomcat.maven</groupId>n <artifactId>tomcat7-maven-plugin</artifactId>n <version>2.2</version>n <configuration>n <port>8080</port>n <path>/</path>n </configuration>n </plugin>n </plugins>n </build>n</project>n

pom文件中加入了一个tomcat插件,并设置端口为8080,因此我们通过tomcat启动项目:

mvc架构编写顺序(mvc模式)

启动完成后,打开浏览器url中输入:

http://localhost:8080/demo/query

mvc架构编写顺序(mvc模式)

mvc架构编写顺序(mvc模式)

浏览器中什么都没返回(我们的代码还没真正的完成,尚未编写处理请求步骤),同时控制台中打印了MVC初始化完成,可以认为,目前的代码没有明显的缺陷。 我们继续~~~~~

5,改造initHandleMapping()5.1 为什么改造?

mvc架构编写顺序(mvc模式)

DxhDispatcherServlet这个类继承了HttpServlet,并重写了doGet和doPost方法,在doGet中调用了doPost方法,当我们使用反射调用方法时(method.invoke(……))发现少了一部分参数:

mvc架构编写顺序(mvc模式)

因此我们要改造initHandleMapping(),修改url和method的映射关系(不简简单单的存入map中)。

5.2 新建Handler类

package com.dxh.edu.mvcframework.pojo;nimport java.lang.reflect.Method;nimport java.util.HashMap;nimport java.util.Map;nimport java.util.regex.Pattern;npublic class Handler {n //method.invoke(obj,)需要n private Object controller;n private Method method;n //spring中url支持正则n private Pattern pattern;n //参数的顺序,为了进行参数绑定 ,Key 参数名, Value 代表第几个参数n private Map<String,Integer> paramIndexMapping;n public Handler(Object controller, Method method, Pattern pattern) {n this.controller = controller;n this.method = method;n this.pattern = pattern;n this.paramIndexMapping = new HashMap<>();n }n //getset方法这里省略,实际代码中需要…n}n

在Handler类中编写了4个属性:

private Object controller:method.invoke(obj,)需要private Method method:与url绑定的方法private Pattern pattern:可以通过正则匹配,也可以直接写String url。private Map<String,Integer> paramIndexMapping:参数的顺序,为了进行参数绑定 ,Key 参数名, Value 代表第几个参数5.3 修改initHandleMapping()

首先,就不能直接通过Map<url,Method>的得方式进行关系映射了,使用一个list,泛型是刚才创建的Handler。

//handleMapping ,存储url和method直接的映射关系n// private Map<String,Method> handleMapping = new HashMap<>();n private List<Handler> handlerMapping = new ArrayList<>();n

改动前,改动后代码对比:

mvc架构编写顺序(mvc模式)

改动后的initHandleMapping():

//5,构造一个映射器,将url和method进行关联nprivate void initHandleMapping() {n if (ioc.isEmpty()){return;}n for (Map.Entry<String,Object> entry: ioc.entrySet()){n //获取ioc中当前遍历对象的class类型n Class<?> aClass = entry.getValue().getClass();n //排除非controller层的类n if (!aClass.isAnnotationPresent(DxhController.class)){n continue;n }n String baseUrl = "";n if (aClass.isAnnotationPresent(DxhRequestMapping.class)){n //Controller层 类上 注解@DxhRequestMapping中的value值n baseUrl = aClass.getAnnotation(DxhRequestMapping.class).value();n }n //获取方法n Method[] methods = aClass.getMethods();n for (Method method : methods) {n //排除没有@DxhRequestMapping注解的方法n if (!method.isAnnotationPresent(DxhRequestMapping.class)){continue;}n //Controller层 类中方法上 注解@DxhRequestMapping中的value值n String methodUrl = method.getAnnotation(DxhRequestMapping.class).value();n String url = baseUrl+methodUrl;n //把method所有信息以及url封装为Handlern Handler handler = new Handler(entry.getValue(),method, Pattern.compile(url));n //处理计算方法的参数位置信息n Parameter[] parameters = method.getParameters();n for (int i = 0; i < parameters.length; i++) {n Parameter parameter = parameters[i];n //不做太多的参数类型判断,只做:HttpServletRequest request, HttpServletResponse response和基本类型参数n if (parameter.getType()==HttpServletRequest.class||parameter.getType()==HttpServletResponse.class){n //如果时request和response对象,那么参数名称存 HttpServletRequest 和 HttpServletResponsen handler.getParamIndexMapping().put(parameter.getType().getSimpleName(),i);n }else{n handler.getParamIndexMapping().put(parameter.getName(),i);n }n }n handlerMapping.add(handler);n }n }n}n6, 请求处理开发 doPost():

上一步骤,我们配置了 uri和method的映射关系,并封装到了Handler中存入list,那么接下来,就要通过HttpServletRequest,取出uri,然后找到具体的Handler:

通过HttpServletRequest取出uri找到具体的Handler得到将调用方法的参数的数组根据上述数组长度创建一个新的数组(参数数组,传入反射调用的)通过req.getParameterMap()得到前台传来的参数parameterMap遍历parameterMap通过StringUtils.join方法把name=1&name=2格式的参数变为name[1,2] (需要commons-lang依赖)参数匹配并设置

private Handler getHandler(HttpServletRequest req) {n if (handlerMapping.isEmpty()){return null;}n String url = req.getRequestURI();n //遍历 handlerMappingn for (Handler handler : handlerMapping) {n Matcher matcher = handler.getPattern().matcher(url);n if (!matcher.matches()){continue;}n return handler;n }n return null;n}n

@Overriden protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {n //根据uri获取到能够处理当前请求的Handler(从handlerMapping中(list))n Handler handler = getHandler(req);n if (handler==null){n resp.getWriter().write("404 not found");n return;n }n //参数绑定n //该方法所有参数得类型数组n Class<?>[] parameterTypes = handler.getMethod().getParameterTypes();n //根据上述数组长度创建一个新的数组(参数数组,传入反射调用的)n Object[] paramValues = new Object[parameterTypes.length];n //以下就是为了向参数数组中设值,而且还得保证参数得顺序和方法中形参顺序一致。n Map<String,String[]> parameterMap = req.getParameterMap();n //遍历request中所有的参数 ,(填充除了request、response之外的参数)n for (Map.Entry<String,String[]> entry: parameterMap.entrySet()){n //name=1&name=2 name[1,2]n String value = StringUtils.join(entry.getValue(), ",");// 如同 1,2n //如果参数和方法中的参数匹配上了,填充数据n if (!handler.getParamIndexMapping().containsKey(entry.getKey())){continue;}n //方法形参确实有该参数,找到它得索引位置,对应得把参数值放入paramValuesn Integer index = handler.getParamIndexMapping().get(entry.getKey());n //把前台传递过来的参数值,填充到对应得位置去n paramValues[index] = value;n }n Integer requestIndex = handler.getParamIndexMapping().get(HttpServletRequest.class.getSimpleName());n paramValues[requestIndex] = req;n Integer responseIndex = handler.getParamIndexMapping().get(HttpServletResponse.class.getSimpleName());n paramValues[responseIndex] = resp;n //最终调用handler得method属性n try {n Object invoke = handler.getMethod().invoke(handler.getController(), paramValues);n//简单操作,把方法返回的数据以字符串的形式写出nresp.getWriter().write(invoke.toString());n } catch (IllegalAccessException e) {n e.printStackTrace();n } catch (InvocationTargetException e) {n e.printStackTrace();n }n }n7,测试:

打开浏览器,url中输入:http://localhost:8080/demo/query?name=lisi

返回:

mvc架构编写顺序(mvc模式)

控制台中打印出:

mvc架构编写顺序(mvc模式)

OK完成~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至827202335@qq.com 举报,一经查实,本站将立刻删除。文章链接:https://www.eztwang.com/dongtai/55541.html

(0)
打赏 微信扫一扫 微信扫一扫
上一篇 2023年1月5日 10:52
下一篇 2023年1月5日 10:55

相关推荐

  • 找手工活在哪个平台上找比较真实可靠(外发加工接单平台)

    关于手工活代加工你知道多少?前两天跟一个朋友聊天,他跟我聊起来这个话题,我对这方面不懂,然后就听他给我讲。 大概去年三月份时候,他在1688上面找了一个手工活代加工的,当时说的很好很好,还给他看了他们的营业执照和签订合同,想着营业执照什么都看了应该没什么事。当时他就激情澎湃了,脑子一热当时就让他们发了第一批货。 第一批货到了,是需要快递到付,付了四百多块,是…

    2024年3月25日
    1800
  • 拼多多开店要钱吗(网上开店铺需要什么流程)

    拼多多作为中国的电商平台之一,吸引了越来越多的商家入驻。本文将详细介绍在拼多多开店的流程以及所需的费用。 一、拼多多开店流程1. 注册账号首先需要在拼多多官网上注册一个账号,填写正确的手机号码,并设置密码。平台会通过短信验证码的方式验证手机号是否正确,并完成账号的注册。2. 完善店铺信息在注册账号后,需要填写店铺的基本信息,包括店铺名称、店铺LOGO、经营类…

    2024年3月24日
    1000
  • 兼职拿我身份证开淘宝网店(别人拿我的身份证开网店)

    遥想当年,电商刚开始发力的阶段,身边经常有人借身份证开淘宝店铺。究其原因,主要就是平台规定一人一店,所以为了多开店铺提高成功率,“七大姨八大姑”借了个遍,甚至村里的留守老人都不放过。时至今日,还不乏这样的人存在。 再说几年前,不少之前的电商创业者成了大老板,事业飞黄腾达,开了公司,买了奔驰。虽然小日子越过越滋润,但也遇到烦心事。 “啥事呢”? “不能大声说的…

    2024年3月24日
    1500
  • 闲鱼一键转卖怎么赚钱(闲鱼的一键转卖是赚佣金吗)

    “现在去闲鱼上买东西,刷好几屏都是职业卖家,真正卖闲置物品的个人越来越少了。”有网友吐槽。 知乎、百度等平台上也充斥着闲鱼赚钱攻略:“去1688、拼多多、义乌购、微商手里找货源找文案,自己不要的东西,低于均价快速卖出刷好评,提升闲鱼账号的成交量,带动流量和活跃度,权重也会变高。” 就像闲鱼的Slogan所说的,闲鱼本身是一个“卖闲置,淘二手”的平台,因其只需…

    2024年3月24日
    2100
  • 不小心把收款码发给别人了怎么办(如何重置微信收款二维码)

    众所周知,微信付款二维码不能随便发给人。但是,收款二维码能不能随便发给别人呢,会不会存在什么风险呢?事实上,还是存在一定风险的。下面简单分析一下: 1、财务风险 我们都知道,收款码是我们向别人收钱的二维码。如果发给别人,别人扫码了,我们也只是进账资金,财务上不可能会造成损失,反而是赚了钱。但是,如果正当的钱,我们可以收。如果进账的是不正当的钱,那就会给自己带…

    2024年3月24日
    78000
  • 闲鱼到付安全吗(闲鱼卖家顺丰到付对谁有利)

    贩卖二手商品,可以直接把家中闲置物品换成真金白银,把不常用的、或者根本不用的东西变卖后,购入更加常用、更加心仪的产品。对比在各大电子平台开店售卖的方式,二手交易平台是更加合理的选择。 闲鱼平台是小编用着最好的闲置物品贩卖平台,下面我所教的基本内容也是适合个人“开店”的方法。此文为经验交流,并不是教授论文,希望各位看官摆平姿态,吸收干货。 第一,取得开门红。 …

    2024年3月24日
    1000
  • 1688开店铺需要多少钱(入驻1688一年要多少钱)

    阿里巴巴国际站-重庆 阿里巴巴国际站有22年的建站历史,目前已经成为全球最大的做外贸B2B(批发)网站,主要招商对象是中国商家,买家分布在200多个海外国家和地区。国际站俗称“1688海外版/英文版”,其实国际站除了有1688相似的找批发买家流量提供之外,还提供了出口、报关退税、出口物流,还有现如今最受关注的收外汇等多项国际贸易辅助业务。 先来说说入驻费用:…

    2024年3月24日
    1000
  • 抖音商城怎么开店(怎样在抖音上开店铺卖商品)

    抖音上怎么开店,目前在抖音很多用户都在推销自己的视频时候,都附带了很多商店的连接,其中的流量可想而知,对于很多刷抖音的人来说这里是最好的推销地方,那么如何在抖音上开店呢?开店铺需要什么条件?下面就跟小编一起来看看抖音开店教程步骤! 抖音开店教程步骤 1.首先你要有自己的抖音号,注册一个并且登录,在“我”这个页面右上角有三条整齐的横线“三”点开,底下有个“设置…

    2024年3月24日
    500
  • 淘宝中评对卖家的影响(淘宝中评多久显示)

    淘宝的评价系统规定只有在商家购买了商品之后才能对其进行评价,一般来说,买家购买的商品只要不和商家描述的有太大出入的话,那么买家是不会恶意给中评的,除了恶评师。店铺很可能会因为顾客的一个差评或者一个中评而对店铺的权重产生影响,从而使店铺的销量下降和声誉受损。那么一个淘宝店铺被给于中评,会对其产生什么影响?以下是关于淘宝的评价系统的介绍。 一、淘宝店被中评有啥影…

    2024年3月24日
    1300
  • 女生学美甲赚钱吗(女孩子做美甲行业好吗)

    有很多人问我当美甲师一个月能挣多少钱?我告诉你挣不了多少钱。很多女孩喜欢去做美甲,美甲师看似很挣钱,不过挣的也是辛苦钱。美甲师的月收入一般有两种:一种是有底薪的,一种是底薪加提成。在一般城市的美甲师底薪不超过3000,另一种底薪不高,一般提成在20%-30%左右,是一项多劳多得的技术。 美甲师的工资还和很多因素有关: ·1.所在地消费水平不同。消费水平高的城…

    2024年3月23日
    2800
  • 速卖通是b2c还是c2c(速卖通跨境电商)

    今天,我们将探索的是“速卖通”——被誉为“国际版淘宝”的跨境电商平台! 速卖通作为阿里巴巴旗下的跨境电商平台,在中国,它是最大的跨境出口B2C平台之一。同时,速卖通也在俄罗斯、西班牙等国家排名榜首,站点覆盖超过200个国家,广受欢迎。 平台费用与平台物流 速卖通的费用模式相对灵活,只需要支付佣金,佣金范围为3%到8%,并且享有无月租费优势。收款方面,买家确认…

    2024年3月23日
    700
  • 一般什么地方招暑假工(暑假临时工招聘网)

    马上就要放暑假了,各位大学生们的暑假工作是不是找好了呢。还没有找到的小伙伴们不要着急,我们现在就来分享一下2022网上找暑假工比较靠谱的软件。看看有没有让你心仪的那一款呢?可以根据以下平台来选择,比较可靠真实: 1. BOSS直聘、58同城、赶集网、智联招聘、前程无忧51Job、拉勾招聘等平台都有海量的优质岗位,可以根据自己的需求选择合适的平台。 2. 探儿…

    2024年3月23日
    600
  • 美甲店一天能挣1000吗(开美甲店会亏钱吗)

    我是一家个人美甲店,每天能赚多少钱呢? 我是一家个人美甲店,位于谷埠街国际商城。今天的收入达到了1200元,其中包括两个指甲的美甲服务、一个美睫和一个眉毛。 ·第一位顾客是通过抖音视频找到我的,她看到我们家有特色的建构养甲项目,毫不犹豫地选择了纯色加建构的服务,价格为49.9元。 ·第二位顾客是我的老顾客,一直对我的技术非常认可。上个月她在我这里做了一个不开…

    2024年3月23日
    1000
  • 开网店卖什么东西好赚钱(网店初学者适合卖什么)

    开网店卖小饰品是一种越来越受欢迎的创业方式。随着人们对个性化产品和定制化服务的需求不断增加,小饰品作为一种简单易行、价格亲民的商品形式,具有很大的市场潜力。 虽然开网店卖小饰品是一种相对容易入门的创业方式,但是赚钱并不是轻松的事情。首先,您需要有一个新颖独特的产品系列,以吸引消费者的吸意力;其次,您需要掌握一些基本的营销技巧,例如拍摄高质量的产品图片,并在社…

    2024年3月23日
    500
  • 电商怎么发货才便宜(拼多多无货源在哪里找货源)

    如今快节奏的生活环境下,人们对于生活质量的要求和物质享受的追求也是逐步的提高,单单的吃饱穿暖已经不太符合如今的生活的追求。 创业项目,副业项目,现在已经成为了年轻人们的新选择,尤其是目前互联网创业前景广阔,正适合年轻人大展拳脚。 但同样,经常有人会说十个创业九个死,虽然机会多,但竞争也更大,在潮流中倒下的创业者同样是一波接着一波。 随着拼多多的快速崛起和发展…

    2024年3月23日
    800
  • 初中学历的宝妈适合考什么证(四十多岁还能考什么证)

    初中学历可以考多种证书,以下是一些可供参考的证书类型: 会计从业资格证:初中以上学历,年满18周岁即可报名。 电工操作资格证(上岗证):年满18周岁且符合相关工种规定的年龄要求,经医院体检合格且无妨碍从事相应特种作业的疾病和生理缺陷,初中及以上学历,符合相应特种作业需要的其他条件。 计算机等级证书:考生不受年龄、职业、学历等背景的限制,均可根据自己学习情况和…

    2024年3月23日
    700
  • 什么工作可以在手机上做(手机上的兼职有哪些)

    1.网上问卷调查 网上问卷调查是一个简单的赚钱方法,只需要你花费一些时间填写一些调查问卷,就可以获得一些报酬。一些市场调研公司和在线调查平台,经常需要人们填写一些问卷来帮助他们更好地了解市场和消费者需求。你可以去一些问卷调查网站注册,填写一些问卷调查,一般每份问卷的报酬是2-5元不等,根据问卷的难度不同而有所区别。如果你愿意花费更多时间填写问卷,你可以得到更…

    2024年3月23日
    1900
  • 1688一件代发利润大概在多少(免费一件代发正规平台)

    肯定能啊!不然不赚钱为啥有这么多人去做! 但是也不是说你做了就能赚钱,就跟做生意一个道理,能不能赚钱看的是个人能力! 但是相对来说,一件代发是非常简单的了,机会也比较大,投入和产出的回报比也比较高! 至于题主说的一些费用,很多都没有必要,如果想尝试我建议的是以最小的投资来做。 先简单说说一件代发: “一件代发”顾名思义,就是你作为卖家,哪怕你只卖出一件产品,…

    2024年3月21日
    900
  • 暑假工干什么比较好(暑假工一般找什么工作)

    给你几点建议,希望能帮到你。 01 如果你去电子厂或者机械厂打工,要防止招你的人是不是中介,干多久可以离职,根据我的经验,一般厂里是干三个月才能走,如果你干两个月,到最后离开会很困难,可能到时候干了中介会不断拖你工资。 另外还有一点要注意,在一些APP上找工作,一般招聘者都是中介公司。当你面试之后,不可能马上入职。 就例如我和我同学在58同城找工作去了之后才…

    2024年3月21日
    1000
  • 品牌折扣店的货是真是假(折扣店的东西为什么便宜)

    你在网上看到那些价格很便宜的品牌折扣网站,比如唯品会,会不会想:“这么便宜,质量能保证吗?”今儿我们就讲讲,他们怎么做到比传统的零售商卖的便宜,还是真货。大概四个原因。 第一、品牌折扣平台一般卖的都是品牌的过季产品或者库存产品,品牌商需要清理库存,愿意以很低的价格把产品出掉。 第二,品牌折扣品牌所在的品类一般都是服装和家居产品,这类产品的定价策略一般都是按照…

    2024年3月21日
    700

发表回复

登录后才能评论

联系我们

18312384410

在线咨询: QQ交谈

邮件:827202335@qq.com

添加微信