CMS项目文档,java,需求分析

更新时间:2023-12-23 00:38:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1用户登录

1.1需求

: login.jsp1: 输入用户名,密码2: request(username,password)3: 取出username,password4: login(username,password)5: 6: 返回User对象7: 判断User对象的取值8: 如果User不为空9: 如果User为空根据用户名查询数据库中t_user取出相应的记录,取出记录中的密码与传入的密码进行比对 : LoginServlet : LoginDao : main.jsp

1.2sql准备

create table t_user(id int primary key auto_increment ,username varchar(20),password varchar(20),status int ,name varchar(50)); 1.3初始化参数配置

1.servlet初始化参数配置 仅在该servelt中有效

UserServlet org.leadfar.cms.backend.servlet.UserServlet isSupportCheckCode 0 Java程序读取 isSupportCheckCode=\.equals(config. getInitParameter(\))?true:false; 2.全局应用初始化参数配置

在所有的servet和jsp中均可读取

isSupportCheckCode 0 Java程序读取 isSupportCheckCode=\.equals(config.getServletContext().getInitParameter(\))?true:false; 1.4Fiter(过滤器)

1.Filter是一个特殊的Servlet

2.Filter是AOP(Oritend Aspected Programming)思想的一种实现,是对原WEB请求路线实施的干预,支持热插拔

3.可以配置多个Filter,执行顺序将根据web.xml中配置顺序 4.定义Filter只需要定义一个普通的java类,实现Filter接口 public class EncodeFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse FilterChain chain) throws IOException, ServletException { response, } private String encode; public void destroy() { // TODO Auto-generated method stub } } request.setCharacterEncoding(encode); response.setCharacterEncoding(encode); //一定要加这一句 //System.out.println(\ chain.doFilter(request, response); //System.out.println(\ public void init(FilterConfig config) throws ServletException { } encode=config.getInitParameter(\); 5.配置Filter ParamsFilter org.leadfar.cms.backend.servlet.EncodeFilter encode UTF-8 ParamsFilter /* 6.Url-pattern

1./* 表示根路径下及其所有目录下的所有资源 2./backend/*

3.*.jsp 所有的以jsp为后缀的请求均经过过滤器 4./backend/*.jsp 不允许定义

1.5路径问题

1.配置servlet的根路径与html中访问资源的根路径含义不一样

Servlet的根路径包含应用程序名 html中的根路径不含义应用程序名(主机名+端口号) 2.写相对路径 ,一定要明确相对谁 3.写绝对路径,一定要明确”/”起始于谁

4.servlet的url理论上是随意的一个路径,但是请注意一定是绝对路径,且从应用程序根路径出发的路径.

5.一般forwad写绝对路径,起始于服务器端的根 (包含应用程序名)

6.一般redirect写绝对路径,起始于客户端的根(不包含应用程序名),为了不写死,所以要通过request.getContextPath()取得应用程序的路径,如/cms

7.关于标签,base标签设置页的基准路径,所有的包括链接,action,样式,javascript的路径均相对于base的设置,,默认base定义的路径是包含应用程序名称的路径

2.文章管理

2.1需求概述

添加文章后台用户编辑文章发布文章删除文章网站访客浏览文章 left.jsp1: 点击添加文章2: 3: 输入文章相关信息article_add.jspArticleServletArticleDaoarticle_add_success.jsp4: 点击提交(request)5: 获取表单参数,封装为Article对象6: save(Article)7: forward(request,response) 2.2sql准备

2.2.1MySQL字段类型

int char(n) varchar(n) blob 整数 定长字符串 变长字符串 二进制文件

longtext date datetime time year timestamp

大字段文本 日期,不包含时间 日期和时间 时间 年份 毫秒数 2.2.2建表语句

create table t_article( ); alter table t_article drop content; alter table t_article add content longtext; id int primary key auto_increment, title varchar(200), content varchar(4000), create_time datetime, update_time datetime, publish_time datetime, source varchar(200), author varchar(200), summary varchar(200), click_score int , reply_count int, is_recommend int, is_headline int, user_id int 2.3通用Servlet框架

public class BaseServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, String method=request.getParameter(\); //缺省的采用list方法 if(method==null){ } method=\; throws ServletException, IOException { HttpServletResponse response) } try { } Method m=this.getClass().getMethod(method, m.invoke(this, request,response); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); HttpServletRequest.class,HttpServletResponse.class); } catch (SecurityException e) { } catch (NoSuchMethodException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { public void add(HttpServletRequest request, HttpServletResponse } public void update(HttpServletRequest request, HttpServletResponse } public void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response) throws ServletException, IOException { response) throws ServletException, IOException { } public void updateInput(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }

2.4表单参数统一接收和处理框架

依赖于apache-common类库下的commons-beanutils.jar commons-logging.jar

public class RequestUtils { /** * * @param clazz 目标对象类型 * @param request request请求 * @return 返回property设完置后的对象 */ public static Object copyProperties(Class clazz,HttpServletRequest Object o=null; try { } Map params=request.getParameterMap(); for (Iterator iterator = params.entrySet().iterator(); Map.Entry param = (Map.Entry) iterator.next(); String key=(String)param.getKey(); String[] values=(String[])param.getValue(); try { } BeanUtils.copyProperty(o, key, values[0]); // TODO Auto-generated catch block e.printStackTrace(); // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { o = clazz.newInstance(); // TODO Auto-generated catch block e1.printStackTrace(); // TODO Auto-generated catch block e1.printStackTrace(); } catch (InstantiationException e1) { request){ } catch (IllegalAccessException e1) { iterator.hasNext();) { } catch (InvocationTargetException e) { } } } return o; 2.5分页组件

1.分页器对象模型

Pager : pageNo ,pageSize ,totalPages, totalRecords,startIndex 2.抽取BaseDao,封装查询总记录数的通用方法 *定义参数类型类

*定义处理方法 getRecords(String sql,Object[] params,int[] ParamTypes) 3.分页导航控制思路 4.利用ThreadLocal封装分页参数,减少方法间传递 详细理解可参考:http://blog.csdn.net/qjyong/archive/2008/03/08/2158097.aspx 5.基于Form表单提交控制当前页号的分页方案适合于管理信息系统 6.基于URL地址传参的控制分页方案适合于商业网站

3.频道管理

3.1sql

create table t_channel(id int primary key auto_increment,name varchar(50),description longtext); alter table t_article add channel_id int references t_channel(id); 3.2程序架构重构

统一增加service层,将业务逻辑从Dao层代码中分离,明确职责分工。

客户端1: 2: 3: 4: 5: Articlearticle_add.jspArticleServletArticleServiceArticleDao6: 7: 领域模型(domain model) ddd (doman model Driven)充血模型:将状态与行为设计在同一个Bean中贫血模型:将状态与行为分离

3.3事务处理

之前的程序中没有考虑事务处理,每一个dao的方法都独立创建数据库连接,独立提交,独立回滚,独立关闭。

解决事务最核心的前提是:同一个数据库连接,事务结束后统一提交或回滚,最终关闭。 因此可以在service层开启事务,调用相应的一个或多个dao方法之后,统一提交或回滚,最终关闭,但是由于Dao中需要访问到Connection,为了减少Connection在各个方法的api中定义,采用ThreadLocal解决。

每一个service中的方法加入逻辑基本相同,故考虑采用代理设计模式封装。

3.4动态代理

3.4.1JDK动态代理

实现InvocationHandler接口,重写invoke方法 --乾坤大挪移 必须要有接口 代码示例: public class JDBCHandler implements InvocationHandler { //真实对象 private Object target; public Object createProxy(Object target){ this.target=target; //生成代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override /** * p1:是指真实对象(目标对象) * p2:调用方法所指的Method对象 * p3:实际参数 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object o=null; //前置 打开数据库连接 Connection conn=DB.getConn(); try{ //前置 将数据库连接放入到ThreadLocal中 ConnectionContext.setConn(conn); o=method.invoke(target, args); } } } //后置 事务提交 conn.commit(); //异常 事务回滚 DB.rollback(conn); //最终 连接关闭 DB.close(conn); }catch(Exception e){ }finally{ //返回方法调用结果 return o; 3.4.2 CGLib

字节码执入技术 –偷梁换柱 对于普通的类实现动态代理

3.4.3Jdk1.6的一个新特性 Compiler API 3.5AOP

Aspected Oritened Programming

Advice(通知) Before Finish Exception Finally Arround weave Point-cut Aspect(jdbcHandler) Proxy Abstract target 3.6工厂设计模式

3.6.1简单工厂设计模式(静态方法工厂模式)

工厂角色:负责实现创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产品。

抽象产品角色:简单工厂模式所创建的所有对象的父类。它负责描述所有实例所有共有的公共接口。

具体产品角色:所有创建的对象都是充当这个角色的某个具体类的实例。

调用者Factory(具体工厂)抽象产品具体产品1具体产品2

优势和缺陷

在简单工厂模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界的信息,决定究竟应该创建那个具体类的对象。通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面中摆脱出来,仅仅需要负责“消费”对象就可以了,而不 必管这些对象究竟是如何创建以及如何组织的。这样就明确区分了各自的职责和权力,有利于整个软件体系结构的优化。但如果新增产品,则需要修改工厂类,违反了OCP原则

3.6.2工厂方法设计模式

产品角色(Product):定义产品接口

真实产品(ConcreteProduct):实现接口Product的类 工厂角色(Creator):声明工厂方法,返回一个产品

真实的工厂(ConcreteCreator):实现工厂方法,有客户调用,返回一个产品的实例 优势和缺陷

基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。她能够是工厂可以自主确定创建何 种产品对象,二如何创建这个对象的细节则完全封装在具体工厂内部。使用工厂方法模式的另一个优点在于系统在加入新产品的时候无需修改抽象工厂类和抽象产品 提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,而是只要添加一个具体工厂和具体产品就可以了,这样,系统的可扩展性非常好。

3.6.3抽象工厂设计模式

抽象工厂模式与工厂方法模式的最大区别在于:工厂方法模式针对的是一个产品等级结构,而抽象 工厂模式则针对的是多个产品等级结构。正应为如此,抽象工厂模式中经常会用到产品族的概念(Product Family)这一概念,它是指位于不同的产品等级结构中,并且功能相互关联的产品系列。

抽象工厂(AbstractFactory):声明生成抽象产品的方法

具体工厂(ConcreteFactory):执行生成抽象产品的方法,生成一个具体的产品 抽象产品(AbstractProduct):为一种产品声明接口

具体产品(ConcretePorduct):定义一个具体工厂生成的具体抽象的对象,实现产品接口

抽象工厂调用者具体工厂1具体工厂2抽象产品抽象产品2具体产品1具体产品2具体产品3具体产品4

可以AWT类库设计为例

AWTFactoryButtonWinAWTFactoryUnixAWTFactoryWinButtonTextWinTextUnixButtonUnixText

UnixAWTFactory负责各个产品中有关Unix这一族的产品的生产。

抽象工厂负责创建不同的有联系的多个产品,不同的抽象工厂创建的产品不同,但产品之间的关系相同。

优势和缺陷:

5.Mybatis总结

1. 持久化的概念

2. mybatis框架的运行机制(主要是基于反射) 3. 几个配置文件

a. SqlMapConfig

配置别名,数据源,引入SqlMapper文件 一般位于ClassPath根路径下 b. SqlMapper

Sql语句编写的文件

对于一个类(一个表)一般有一个Mapper 4. SqlMapper

Select Insert Update Delete

Paramter:传入参数,如果是对象,则写对象的类型(通常是短名称) 单一参数,如 int string 等

Map:主要用于不相关的一些参数传入 resultMap 结果映射:

不匹配问题 字段与属性名不能实现自动的注入 统一都设置 5. 高级映射

一对一(多对一) Association property=”name” column=”person_id” select=”另外一条sql语句”

带来N+1问题 解决办法:

跨表查询,但是映射需要把所有的字段与属性显示对应 Association JavaType 一对多(多对多) Collenction

最核心的是面向对象的关系,数据库表间的关系,其次sql语句熟练 6. 动态sql Sql语句块

If choose foreach $

6.CMS总结

6.1登录与登出

? ? ? ?

验证码的应用 ** Session的应用 *****

基本的参数请求方式 ***** 基本的参数处理方式 ***** Request.getParameter() ? Filter *****

统一判断用户是否登录 统一设置请求中的编码 配置,使用场景

6.2文章管理

? CRUD

? 增删改查搜分

修改一般是通过servlet到达jsp页面的(因为需要回显) 比增的表单参数多一个id 列表展现:

Servlet中通过request.setAtrribute设置属性

Forwad :jsp页面可以访问到 Redirect :jsp访问不到 服务器端重定向***** 客户端重定向***** Request.getAttribute() Jstl EL

${username}

? 分页 *****

基于URL地址分页方式 基于form表单的分页 Pager_taglib

增加pageno的支持 编码的设置 分页模型 Pager ? ThreadLocal *****

解决了分页参数的传递问题

解决了Connection在Dao层的传递 ? 路径问题 *****

1. 服务器端(servlet)

Forwad: “/” 是相对于WebApp (http://localhost:8080/cms/) Redirect : “/” request.getContextPath()+ 2. 客户端(jsp)

“/”相对于Host(http://localhost:8080/)

3.”>

6.3频道管理 *****

1.service层次的抽取

主要是解决了多个dao之间存在着调用的先后关系 Servlet->service->dao

? Dao层提供的方法更接近数据库层面的表示方法 ? Service层提供的方法更接近业务逻辑表示 2.事务管理 //获得Connection Connection conn=DB.getConn(); channelDao.save(conn); //不要提交 logDao.save(conn);//不要提交 conn.commit(); conn.close(); 3.动态代理 (要有接口 jdk默认的动态代理的实现) JDBCHandler

? 通过目标对象生成代理对象 Proxy

? JDBCHandler实现InvocationHandler接口,重写invoke() //获得Connection service简化后的代码 //Connection conn=DB.getConn(); channelDao.save(conn); //不要提交 logDao.save(conn);//不要提交 //conn.commit(); //conn.close(); JDBCHandler Public void invoke(proxy,method,args){ Try{ Connection conn=DB.getConn(); Object o= Method.invoke(target,args); conn.commit(); }catch(){ //Log4j Conn.rollBack(); }finally{ Conn.close(); } } 3. BeanFactory (DI dependency Injection) InitBeanServlet 初始化bean工厂,并注入所有的依赖对象

4. 关于BaseServlet 中央控制器 前端控制器

6.4网站前台

1.服务器端包含

包含地址是与servlet中forward形式的路径一样,base对其无效 Servlet中被含的调用分发页面采用include 2.文章编辑工具 Ckeditor **

文件上传 **

3.apache-commons类库的使用 *** Commons-fileupload Commons-lang Commons-IO Commons-logging

commons-beanutils servlet中参数接收和转型的封装

6.5 MyBatis *****

1.配置的所有sql语句都需要存在于一个包下,设定id 2.sqlMapperConfig 全局配置文件 配置数据源 配置别名

引入sqlmapper文件

3.sqlMapper

Article_mapper.xml