1.基于web开发中最原始的jsp+Servlet   图形化理解jsp+servlet结构:

1.从结构上分析jsp+servlet图解原理:

在基于mvc设计模式下的最原始的jsp+Servlet框架,在某种程度上是不能够达到mvc最直观的体现。当客户端发送请求到服务器时,服务器会将从客户端接收到的信息通过封装技术进行解析,在交给web容器,web容器会通过一篇web.xml的配置文件去找与之相匹配的servlet,此时servlet会开启一个线程,只要是符合web.xml中所配置的某一个servlet时,该servelt就会启动,然后servlet在去调用service或者service的接口实现类,service(impl)在去调用dao(impl),dao通过从数据库(Database)那获取到数据,在封装到model实体类中去。Servlet在完成这一系类的动作后,最终将为我们返回一个jsp页面,最后该页面在返回到客户端展示给客户。

2.从web.xml配置上:

 1 <?xml version="1.0"?>
2 <web-app>
3 <servlet>
4 <servlet-name>TextSerevlet</servlet-name>
5 <servlet-class>com.lh.serivlet.UserSerivlet</servlet-class>
6 </servlet>
7 <servlet-mapping>
8 <servlet-name>TextSerevlet</servlet-name>
9 <url-pattern>/accessServlet</url-pattern>
10 </servlet-mapping>
11 </web-app>

注:需要用到的每一篇servlet都要写入它的配置文件。Web.xml的配置量大,繁杂。从性能优异的角度考虑,它的运行性能是最快的,但是开发性能就很有难度。

3.控制器:

Jsp+servlet的控制器是:工程中的每一个xxxServlet就充当一个控制器,但是必须去extends HttpServlet,并重写
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}

4.作用域对象

ServletContext(上下文),也叫全局的作用域对象。

Session(会话)服务器的一次会话中或者服务器超时。

Request(请求)在一次请求的过程中。

Respones(响应)。

5.数据绑定:没有,只能通过数组去获取页面的数据。

6.类型转换:将jsp页面的数据转换为String类型。也可以是基本数据类型。但是要进行强制转换。

7.有效性验证:可以在某一个需要用到Servlet的类中用java代码进行验证。也可以在jsp页面书写ajax代码进行验证或者是定义function()函数,在函数中用正则表达式加以判断。

8.操作业务层对象调业务方法:在某一个XxxServlet中extends HttpServlet并重写doPost()和doGet()方法,我们只需在doGet()或者doPost()中用request.getParameter()方法来得到页面的数据。如果我们要操作到业务层我们只需在当前的这个类中实例化出业务层的类,即XxxService dao = new XxxServiceImpl();然后获取实体Bean对象中的属性。最后在我们需要用到数据访问层的那一个具体的业务实现方法就用实例化出的dao调用所需方法即可。

9.返回:可以返回对象,也可以返回具体要跳转的那个页面。

10.在js页面做显示:EL表达式,JSP脚本表达式

11.标签:HTML标签,JSP自定义标记库,JST L标准标记库。

12.文件上传:页面需要怎样获取?<form action=”file” method=”post” enctype=”multipart/form-data”>

服务器怎么获得?1.必须导入文件上传的jar包。

13.过滤器:我们自己定义的一个类XxxFilter 必须implements Filter接口,并实现它的三个方法,destroy(),doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException ,init(FilterConfig arg0)。在doFilter()中调用chain.doFilter(request, response)方法,表示将请求交给下一个组件。

1.从结构上分析Struts1图解原理:

客户端发送请求到服务器,服务器将收到的信息传给web容器,这时,web容器会通过到web.xml配置文件中去查找那篇符合命名规范的action属性中的*.do,在交给ActionServlet(中央核心控制器),通过该配置,web容器将信息传给具体的某一个XxxAction,该XxxAction会继承Action,并重写它的

1 HttpServletRequest request, HttpServletResponse response)
2 throws Exception {
3 ........
4 }

方法,同时,我们可以在该XxxAction中去调用JavaBean中的实体对象。但是,需要注意的是,在ActionServlet到Action这一过程中,我们是通过Form组件技术来对jsp页面的信息来进行了一次封装,达到了前端页面(jsp)和后台的实体Bean对象之间的一次数据的绑定。最后再是到Struts-config.xml文件中进行进行配置,通过正确的配置找到所需的jsp.

2从web.xml配置上:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
3 <servlet>
4 <servlet-name>action</servlet-name>
5 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
6
7 <!-- 主配置文件,param-name的值为config -->
8 <init-param>
9 <param-name>config</param-name>
10 <param-value>/WEB-INF/struts-lx.xml,/WEB-INF/struts-zh.xml</param-value>
11 </init-param>
12 <!-- 子配置文件,param-name的值只能以config/开头
13 <init-param>
14 <param-name>config/m1</param-name>
15 <param-value>/WEB-INF/struts-zh.xml</param-value>
16 </init-param>
17 -->
18
19 <init-param>
20 <param-name>debug</param-name>
21 <param-value>3</param-value>
22 </init-param>
23 <init-param>
24 <param-name>detail</param-name>
25 <param-value>3</param-value>
26 </init-param>
27 <load-on-startup>0</load-on-startup>
28 </servlet>
29
30 <servlet-mapping>
31 <servlet-name>action</servlet-name>
32 <url-pattern>*.do</url-pattern>
33 </servlet-mapping>
34 <filter>
35 <filter-name>CharsetFilter</filter-name>
36 <filter-class>
37 com.lovo.struts.filter.CharsetFilter
38 </filter-class>
39 <init-param>
40 <param-name>encoding</param-name>
41 <param-value>utf-8</param-value>
42 </init-param>
43 <init-param>
44 <param-name>ignore</param-name>
45 <param-value>true</param-value>
46 </init-param>
47 </filter>
48 <filter-mapping>
49 <filter-name>CharsetFilter</filter-name>
50 <url-pattern>*.do</url-pattern>
51 </filter-mapping>
52 <filter-mapping>
53 <filter-name>CharsetFilter</filter-name>
54 <url-pattern>*.jsp</url-pattern>
55 </filter-mapping>
56 <welcome-file-list>
57 <welcome-file>index.jsp</welcome-file>
58 </welcome-file-list

注:从上面的配置中我们可以看出,servlet的配置是必不可少的。

3.控制器:ActionServlet是struts1的中央核心控制器,它在web.xml中配置成自动启动的Servlet,在启动中央核心控制器时会读取配置文件(struts-config.xml)的配置信息,为struts中不同的模块初始化相应的对象。

6.类型转换:LoginForm loginF = (LoginForm)form;

7.有效性验证:验证框架,不能重写Validate方法。也可以自定义验证规则,但是必须做配置。

9.返回:Action将业务处理的不同结果返回一个目标响应对象给中央核心控制器,或者返回一个页面mapping.findForward("success")

10.在js页面做显示:EL表达式,自定义标签库,直接在jsp页面上写java代码。

11.标签:

 1   <?xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6 <filter>
7 <filter-name>struts2</filter-name>
8 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
9 </filter>
10 <filter-mapping>
11 <filter-name>struts2</filter-name>
12 <url-pattern>/*</url-pattern>
13 </filter-mapping>
14 <welcome-file-list>
15 <welcome-file>index.jsp</welcome-file>
16 </welcome-file-list>
17 </web-app>

3.基于web开发中Struts2框架的结构图:

1.从结构上分析Struts2图解原理:

Struts2的思想是基于POJO(简单的老的Java对象)的一种新思想而产生的。一度影响了重量级的容器。它的实现是靠用简单的javabean对象去完成各种复杂的功能。我们也可以把这一实现的过程称为POJO。

在Struts2中是没有容器的。当客户端发送一个请求时,在服务器上会经过层层过滤器,最后到达FilterDispatcher(Struts2中的中央核心控制器),中央核心控制器在通过层层的拦截器去找相应的Action,最后Action返给我们一个所访问的页面,由于在Struts2中的拦截器是上下文相互环绕的,所以,在当Action中的Resulet返给我们一个页面的同时还会在次进行后期的拦截器处理,就这样一层层的拦截,直到将最终所取得的信息传给HttpServletResponse,在接着就是HttpServletResponse会将得到的信息响应给HttpServletRequest.但在这个响应的过程中也再次经过了过滤器的过滤。直到信息完整的到达HttpServletRequest。

2从web.xml配置上:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6 <filter>
7 <filter-name>struts2</filter-name>
8 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
9 </filter>
10 <filter-mapping>
11 <filter-name>struts2</filter-name>
12 <url-pattern>/*</url-pattern>
13 </filter-mapping>
14 <welcome-file-list>
15 <welcome-file>index.jsp</welcome-file>
16 </welcome-file-list>
17 </web-app>

3.控制器:核心控制器:FilterDispatcher,在web应用中负责拦截所有的用户请求,如果用户的请求以 .ation结尾,则该请求被传入到struts2框架处理。业务控制器: Action(在struts2中起作用的实际上不是用户自定义的Action,而是系统自动生成的action代理,但该代理是以用户自定义的action为目标的)

4.作用域对象:有前面的struts1中我们可以从Action的execute方法中将请求和响应当做参数传递给了Action,但是在Struts2中我们会发现Action的execute方法是没有任何的参数,所以也就无法得到作用域对象。那么,Struts2又是如何得到作用域对象的呢?分析:当Struts2的过滤器启动的时候,首先就会初始化一个叫做ServletActionContext的类。它掌管着所有的作用域对象。代码展示如下:

 1 mport org.apache.struts2.ServletActionContext;
2 public class ContextAction implements Action {
3 public String execute() throws Exception {
4 //获得请求
5 HttpServletRequest request = ServletActionContext.getRequest();
6 //获得会话
7 HttpSession session = request.getSession();
8 //获得上下文对象
9 ServletContext application = ServletActionContext.getServletContext();
10 }
11 }

10.在js页面做显示:OGNL

11.标签:OGNL表达式、EL表达式、Struts2框架自身提供的标签库、html标签。

1.从结构上分析springMVC图解原理:

springMVC的设计思想被评委教科书式的框架,它是最能体现出MVC设计模式中的分离与互用的极致。所以,基于springMVC的原理我们是非常有必要进行掌握并深入理解的。我们必须清楚的了解spring的MVC框架主要由DispatcherServlet、处理器映射、处理器、视图解析器、视图组成。浏览器发送请求到spring容器,spring容器通过在web.xml配置文件中找到中央核心控制器(DispatcherServlet)的url配置,并且在web.xml中还必须要配置一个初始化的加载参数(详见下面2),当DispatcherServlet接收到一个请求后,它会通过请求的HandlerMapping处理映射路径去找到在spring-servlet.xml配置文件中的一个处理器(Controller),该处理器会找到具体的某一个Xxxservlet,Xxxservlet会将所获取到的信息间接的传给DispatcherServlet,在这一个过程中会有一个ModelAndView的对象产生(体现出了springMVC分离的思想)。当DispatcherServlet得到这个ModelAndView后会将信息传给ViewResolver,这时ViewResolver会将符合格式的view返回出来,最后再将符合格式的数据响应到浏览器端。

2从web.xml配置上:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
5 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
6 <servlet>
7 <servlet-name>mySpring</servlet-name>
8 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
9 <init-param>
10 <param-name>contextConfigLocation</param-name>
11 <param-value>/WEB-INF/classes/mySpring-servlet.xml</param-value>
12 </init-param>
13 <load-on-startup>1</load-on-startup>
14 </servlet>
15 <servlet-mapping>
16 <servlet-name>mySpring</servlet-name>
17 <url-pattern>*.spring</url-pattern>
18 </servlet-mapping>
19 <welcome-file-list>
20 <welcome-file>index.jsp</welcome-file>
21 </welcome-file-list>
22 </web-app>
23 注:<init-param>参数的配置是必不可少的。必须是在/WEB-INF目录下的classes子目录下的我们自己定义的
24 哪一篇xxx-servlet.xml文件。

3.控制器:DispatcherServlet,该控制器的作用是将请求转发到相应的应用控制器。

4.作用域对象:在springMVC中不推荐使用。

5.数据绑定:springMVC支持的数据绑定有6种,1.有基本数据类型绑定(String和String[])。2.简单对象类型绑定(类似与struts1中的ActionForm)。3.List类型绑定(必须创建ArrayList对象来进行绑定)。4.Set类型绑定(必须在Set对象中Add相应的数量的模型对象)。5.Map类型绑定(必须依靠Bean对象)。6.复合数据类型绑定(要求在自己定义的Bean对象上的某个属性也必须是一个Bean对象)。

6.类型转换:在springMVC中有两种类型转换的方式.1.属性编辑器(propertyEditor),属性编辑器是我们最传统的做法。我们只需要通过一个@InitBider注解来完成,方法中的参数是WebRequestDateBinder或者WebDateBinder。在这个方法中,我们可以通过重写PropertyEditorSupport中的setAsText()来定义自己的转换规则。

2.类型转换器(Converter),相对于第一种属性编辑器它的功能更大,它可以对任何类型的数据进行转换。我们在编写一个类型转换器时,一定要去implements它的Converter接口。

7.有效性验证:通过注解的形式来注入@pattern和@valid来进行有效性验证,这也是我们常用到的验证注入。

1.导包

2.书写配置springMVC自己提供的文件上传的配置。

<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000">
</property>
</bean>

3.写jsp页面,注意文件上传的<form>表单里面的属性。

    <form action="upload.spring" name="uploadForm"
method="post" enctype="multipart/form-data">
............
</form>

4.书写控制器UploadController在控制器的方法处理中,从作用域中获取file文件,通过path路径和文件名将文件存入到当前工程的文件夹下。

package com.lh.controller;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile; @Controller
public class UploadController {
@RequestMapping("/upload")
public String upload(HttpServletRequest request
,@RequestParam("file")CommonsMultipartFile file){
//从作用域中获取文件的path路径,通过request.getSession().getServletContext().getRealPath("upload")。
String path = request.getSession().getServletContext().getRealPath("upload");
//通过file来获取文件名。
String name = file.getOriginalFilename();
try {
file.getFileItem().write(new File(path+"/"+name));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "upload";
}
return "success";
}
}

5.测试文件是否上传成功。

在springMVC中实现拦截器,调用它的3个方法。:

 1 1.书写拦截器有两种方式:
2 1-1继承HandlerInterceptorAdaptor类,代码展示如下:
3 package com.lh.interceptor;
4 import javax.servlet.http.HttpServletRequest;
5 import javax.servlet.http.HttpServletResponse;
6 import org.springframework.web.servlet.ModelAndView;
7 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
8 public class Interceptor1
9 extends HandlerInterceptorAdapter
10 {
11 //在控制器传递到拦截器将数据交给DisPacheServlet的过程中将资源清理。
12 public void
13 afterCompletion(HttpServletRequest request,
14 HttpServletResponse response, Object handler, Exception ex)
15 throws Exception {
16 System.out.println("The Main of claening....");
17 }
18 //在方法之后
19 public void
20 postHandle(HttpServletRequest request,
21 HttpServletResponse response, Object handler,
22 ModelAndView modelAndView)
23 throws Exception {
24 System.out.println("The Main of after...");
25 }
26 //在方法之前
27 public boolean
28 preHandle(HttpServletRequest request,
29 HttpServletResponse response, Object handler)
30 throws Exception {
31 System.out.println("The Main of Before....");
32 return true;
33 }
34 }

1-2.实现HandlerInterceptor接口 代码展示如下:

 1 package com.lh.interceptor;
2 import javax.servlet.http.HttpServletRequest;
3 import javax.servlet.http.HttpServletResponse;
4 import org.springframework.web.servlet.HandlerInterceptor;
5 import org.springframework.web.servlet.ModelAndView;
6 public class Interceptor2
7 implements HandlerInterceptor
8 {
9 //在控制器传递到拦截器将数据交给DisPacheServlet的过程中将资源清理。
10 public void afterCompletion(HttpServletRequest arg0,
11 HttpServletResponse arg1, Object arg2, Exception arg3)
12 throws Exception {
13 System.out.println("The Mian of cleaning2.....");
14 }
15 //在方法之后
16 public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
17 Object arg2, ModelAndView arg3) throws Exception {
18 System.out.println("The Mian of After...");
19 }
20 //在方法之前
21 public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
22 Object arg2) throws Exception {
23 System.out.println("The Mian of Befor.....");
24 return true;
25 }
26 }

2. 在xml中配置拦截器:

1   <mvc:interceptors>
2 <mvc:interceptor>
3 <mvc:mapping path="/register.spring"></mvc:mapping>
4 <bean class="com.lh.interceptor.Interceptor1"></bean>
5 </mvc:interceptor>
6 </mvc:interceptors>

注:如果有多个拦截器就需要配置拦截器栈(先进后出)。
3.在tomcat服务器上发布,测试拦截效果是否达到。

软件架构设计学习总结(18):MVC三层架构在各框架(jsp+servlet + Struts1+ Struts2+ springMVC)中的特征的更多相关文章

  1. [置顶] MVC三层架构在各框架中的特征

    1.从结构上分析jsp+servlet图解原理: 在基于mvc设计模式下的最原始的jsp+Servlet框架,在某种程度上是不能够达到mvc最直观的体现.当客户端发送请求到服务器时,服务器会将从客户端 ...

  2. MVC三层架构在各框架中的特征

    转一篇写得很棒的文章:https://my.oschina.net/win199176/blog/208171?p=7&temp=1495894148424 1.基于web开发中最原始的jsp ...

  3. Angular JS从入门基础 mvc三层架构 常用指令

    Angular JS从入门基础  mvc模型 常用指令 ★ 最近一直在复习AngularJS,它是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核心 ...

  4. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  5. MVC三层架构编程(Dao、service、servlet 之间的关系)

    木哈哈~先开心一会儿,人生的第一篇博客aaa.我一定好好写.不过之前也没怎么看别人写过,还是有点小激动呢,加油.好好总结,会总结的宝宝才会有提高! 今天想总结一下mvc三层架构模型编程,宝宝学习不怎么 ...

  6. MVC三层架构搭建

    MVC三层架构搭建 项目主要是用三层来搭建项目,三层分为表现层,数据层和业务层.项目用了目前比较流行的IOC架构.目前流行的IoC 框架有AutoFac,Unity,Spring.NET等,项目中选用 ...

  7. 软件架构设计学习总结(3):QQ空间技术架构之详解

    QQ空间作为腾讯海量互联网服务产品,经过近七年的发展,实现了从十万级到亿级同时在线的飞跃.在这个过程中,QQ空间团队遇到了哪些技术挑战?其站点前后台架构随着业务规模的变化又进行了怎样的演进与变迁?成长 ...

  8. 架构(三层架构)、框架(MVC)、设计模式三者异同点

    前言: 本博客主要针对架构.框架和设计模式三者的区别.还有三层和MVC的区别进行讨论.对于这三者一点都不了解的.请点在维基和百度百科上补补课.这里就不发链接了 软件架构(software archit ...

  9. MVC三层架构模式编程思想 JSP-Servlet-JavaBean

    MVC(Mdodel-View-Controller)编程模式.把一个Java应用分成三层:模型层.视图层.控制层,各层分别实现各层的功能,整个过程见下图就一目了然了. watermark/2/tex ...

随机推荐

  1. hdu 1695 GCD 【莫比乌斯函数】

    题目大意:给你 a , b , c , d , k 五个值 (题目说明了 你可以认为 a=c=1)  x 属于 [1,b] ,y属于[1,d]  让你求有多少对这样的 (x,y)满足gcd(x,y)= ...

  2. codeforce864d

    D. Make a Permutation! time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  3. Hadoop读写流程

    写流程 读流程 HDFS写数据流程 HDFS读数据流程 网络拓扑-节点距离计算 节点距离:两个节点到达最近的共同祖先的距离总和

  4. poj2186tarjan算法缩点求出度

    poj2186tarjan算法缩点求出度 自己打一遍第一题,入门啦,入门啦 题目还算简单,多头牛,给你仰慕关系(可传递),问你最后有没有牛被所有的牛仰慕 根据关系可以建图,利用tarjan算法缩点处理 ...

  5. django创建分页

    前台html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  6. Chubby是什么?

    先简单的理解,以后补充: 为了解决hadoop分布式系统的一致性问题 ,有很多人提出很多protocol,其中就有有名的Paxos算法(Latex作者提出,算法需要学习), 但是Chubby并不是一个 ...

  7. Excel 两列单元格合并超级链接的VBA 写法

    Excel 单元格 分两列 (B列存放姓名, C列存放链接) 列如: 姓名 学号 博客地址 1309032022 李汉超 http://www.cnblogs.com/Vpygamalion/ 141 ...

  8. 10 个免费的Bootstrap Admin 主题,模板收集

    In designing websites today, one of the must have frameworks is the twitter bootstrap. To those who ...

  9. WinRAR试用过期决绝方法

    一.WinRAR 试用过期决绝方法 直接去WINRAR官方下个版本装上然后这样 复制以下内容(红色)到记事本,保存为rarreg.key文件(即文件名是rarreg,扩展名是key),把这文件拷贝到W ...

  10. Nanui 教程

    彩票自动投注软件定制-联灬系-\加/Q;2943075966 黑/科/技问/世.详情直接添加咨询.信/誉/文本 最近接到一个项目 是关于构建一套 电脑端会员管理系统    但考虑到个人比较喜欢写Web ...