《CMS项目文档,java,需求分析.docx》由会员分享,可在线阅读,更多相关《CMS项目文档,java,需求分析.docx(27页珍藏版)》请在三一办公上搜索。
1、1用户登录1.1需求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初始化参数配置l.servlet初始化参数配置 仅在该servelt中有效UserServletorg.leadfar.cms.backend.servlet.UserServletisSupportCheckCode0Java程序读取isSupportCheckCode=1.equals(config.
2、getInitParameter(isSupportCheckCode)?true:false;2. 全局应用初始化参数配置在所有的servet和jsp 中均可读取isSupportCheckCode0Java程序读取isSupportCheckCode=1.equals(config.getServletContext().getInitParam eter(isSupportCheckCode)?true:false;1.4Fiter (过滤器)1. Filter 是一个特殊的 Servlet2. Filter是AOP(Oritend Aspected Programming)思想的一种实
3、现,是对原WEB请求路线实施的干预,支持热插拔3. 可以配置多个Filter,执行顺序将根据web.xml中配置顺序4. 定义 Filter只需要定义一个普通的java类,实现 Filter接口public class EncodeFilter implements Filter (private String encode;public void destroy() (/ TODO Auto-generated method stubpublic void doFilter(ServletRequest request, ServletResponse response,FilterChai
4、n chain) throws IOException, ServletException ( request.setCharacterEncoding(encode);response.setCharacterEncoding(encode);/一定要加这一句/System.out.println(before);chain.doFilter(request, response);/System.out.println(after);public void init(FilterConfig config) throws ServletException ( encode=config.ge
5、tInitParameter(encode);5. 配置 FilterParamsFilterorg.leadfar.cms.backend.servlet.EncodeFilterencodeUTF-8ParamsFilter/*6. Url-pattern1. /*表示根路径下及其所有目录下的所有资源2. /backend/*3. *.jsp所有的以jsp为后缀的请求均经过过滤器4. /backend/*.jsp 不允许定义1.5路径问题1.配置servlet的根路径与html中访问资源的根路径含义不一样Servlet的根路径包含应用程序名html中的根路径不含义应用程序名(主机名+端口号
6、)2. 写相对路径,一定要明确相对谁3. 写绝对路径,一定要明确”/”起始于谁4. servlet的url理论上是随意的一个路径,但是请注意一定是绝对路径,且从应用程序根路 径出发的路径.5. 一般forwad写绝对路径,起始于服务器端的根(包含应用程序名)6. 一般redirect写绝对路径,起始于客户端的根(不包含应用程序名),为了不写死,所以要通过request.getContextPath()取得应用程序的路径,如/cms7. 关于base标签,base标签设置页的基准路径,所有的包括链接,action,样式Javascript 的路径均相对于base的设置,默认base定义的路径是包
7、含应用程序名称的路径2. 文章管理2.1需求概述Adi decc |tllle3 I R conffintI IcrieateTlhiit*li update TrnneI I pdAMmeygI sourceI autlux I 零uhwiaiy3p click ScoreyvI I g rsflyCowtI I recOTimendwHI I keWorcfcslichamoisI I 泗2.2sql准备2.2.1MySQL字段类型int整数char(n)定长字符串varchar(n)变长字符串blob二进制文件longtext大字段文本date日期,不包含时间datetime日期和时间t
8、ime时间year年份timestamp毫秒数2.2.2建表语句create table t_article( 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,
9、is_recommend int, is_headline int, user_id int);alter table t_article drop content; alter table t article add content longtext;2.3通用Servlet框架public class BaseServlet extends HttpServlet (Overrideprotected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException,
10、IOException (String method=request.getParameter(method);缺省的采用list方法if(method=null)(method=list;try (Method m=this.getClass().getMethod(method, HttpServletRequest.class,HttpServletResponse.class);m.invoke(this, request,response); catch (SecurityException e) (/ TODO Auto-generated catch block e.printS
11、tackTrace(); catch (NoSuchMethodException e) ( / TODO Auto-generated catch block e.printStackTrace(); catch (IllegalArgumentException e) ( / TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) ( / TODO Auto-generated catch block e.printStackTrace(); catch (Invocatio
12、nTargetException e) ( / TODO Auto-generated catch block e.printStackTrace();public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (public void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOExceptio
13、n (public void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (public void updateInput(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException (public void list(HttpServletRequest request, HttpServletRespon
14、se response) throws ServletException, IOException (2.4表单参数统一接收和处理框架依赖于 apache-common 类库下的 commons-beanutils.jar commons-logging.jarpublic class RequestUtils (/* param clazz目标对象类型* param request request请求* return返回property设完置后的对象 */pUblic static Object copyProperties(Class clazz,HttpServletRequest re
15、quest)(Object o=null;try ( o = clazz.newInstance(); catch (InstantiationException e1) ( / TODO Auto-generated catch block e1.printStackTrace(); catch (IllegalAccessException e1) ( / TODO Auto-generated catch block e1.printStackTrace();Map params=request.getParameterMap();for (Iterator iterator = par
16、ams.entrySet().iterator(); iterator.hasNext();) ( Map.Entry param = (Map.Entry) iterator.next(); String key=(String)param.getKey(); String values=(String)param.getValue();try (BeanUtils. copyProperty (o, key, values0); catch (IllegalAccessException e) ( / TODO Auto-generated catch block e.printStack
17、Trace(); catch (InvocationTargetException e) ( / TODO Auto-generated catch block e.printStackTrace();returno;2.5分页组件1. 分页器对象模型Pager : pageNo ,pageSize ,totalPages, totalRecords,startIndex2. 抽取BaseDao,封装查询总记录数的通用方法*定义参数类型类*定义处理方法 getRecords(String sql,Object params,int ParamTypes)3. 分页导航控制思路1如果当前页号=1
18、首页 上页 下页(a)尾页(a)如果当前页号=totalPages首页(a)上页(a) 下页 尾页其它首页(a) 上页(a) 下页(a) 尾页(a)否则首页上页下页尾页-4. 利用ThreadLocal封装分页参数,减少方法间传递详细理解可参考:5. 基于Form表单提交控制当前页号的分页方案适合于管理信息系统6. 基于URL地址传参的控制分页方案适合于商业网站3. 频道管理3.1sqlcreate table t_channel(id int primary key auto_increment,name varchar(50),description longtext);alter tab
19、le t article add channel id int references t channel(id);3.2程序架构重构统一增加service层,将业务逻辑从Dao层代码中分离,明确职责分工。3.3事务处理之前的程序中没有考虑事务处理,每一个dao的方法都独立创建数据库连接,独立提交, 独立回滚,独立关闭。解决事务最核心的前提是:同一个数据库连接,事务结束后统一提交或回滚,最终关闭。因此可以在service层开启事务,调用相应的一个或多个dao方法之后,统一提交或回 滚,最终关闭,但是由于Dao中需要访问到Connection,为了减少Connection在各个方法 的api中定义
20、,采用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;/生成代理对象returnProxy.newProxylnstance
21、(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中 Con
22、nectionContext.setConn(conn); o=method.invoke(target, args);/后置事务提交 mit();catch(Exception e)(异常事务回滚DB. rollback(conn)finally(最终连接关闭DB.close(conn);/返回方法调用结果3.4.2 CGLib字节码执入技术偷梁换柱对于普通的类实现动态代理3.4.3Jdk1.6 的一个新特性 Compiler API3.5AOPAspected Oritened Programming3.6工厂设计模式3.6.1简单工厂设计模式(静态方法工厂模式)工厂角色:负责实现创建所有
23、实例的内部逻辑,工厂类可以被外界直接调用,创建所需的产 品。抽象产品角色:简单工厂模式所创建的所有对象的父类。它负责描述所有实例所有共有的公 共接口。具体产品角色:所有创建的对象都是充当这个角色的某个具体类的实例。调用者优势和缺陷 在简单工厂模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界 的信息,决定究竟应该创建那个具体类的对象。通过使用工厂类,外界可以从直接创建具体 产品对象的尴尬局面中摆脱出来,仅仅需要负责“消费”对象就可以了,而不必管这些对 象究竟是如何创建以及如何组织的。这样就明确区分了各自的职责和权力,有利于整个软件 体系结构的优化。但如果新增产品,则需要修改
24、工厂类,违反了 OCP原则3.6.2工厂方法设计模式产品角色(Product):定义产品接口真实产品(ConcreteProduct):实现接口 Product的类工厂角色(Creator):声明工厂方法,返回一个产品真实的工厂(ConcreteCreator):实现工厂方法,有客户调用,返回一个产品的实例优势和缺陷基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。她能够是工厂可以自主 确定创建何种产品对象,二如何创建这个对象的细节则完全封装在具体工厂内部。使用工 厂方法模式的另一个优点在于系统在加入新产品的时候无需修改抽象工厂类和抽象产品提 供的接口,无需修改客户端,也无需修改其他的具
25、体工厂和具体产品,而是只要添加一个具 体工厂和具体产品就可以了,这样,系统的可扩展性非常好。3.6.3抽象工厂设计模式抽象工厂模式与工厂方法模式的最大区别在于:工厂方法模式针对的是一个产品等级结 构,而抽象工厂模式则针对的是多个产品等级结构。正应为如此,抽象工厂模式中经常会 用到产品族的概念(Product Family)这一概念,它是指位于不同的产品等级结构中,并且 功能相互关联的产品系列。抽象工厂(AbstractFactory):声明生成抽象产品的方法具体工厂(。oncreteFactory):执行生成抽象产品的方法,生成一个具体的产品抽象产品(AbstractProduct):为一种产
26、品声明接口具体产品(ConcretePorduct):定义一个具体工厂生成的具体抽象的对象,实现产品 接口可以AWT类库设计为例UnixAWTFactory负责各个产品中有关Unix这一族的产品的生产。抽象工厂负责创建不同的有联系的多个产品,不同的抽象工厂创建的产品不同,但产 品之间的关系相同。优势和缺陷:抽象工厂的模式主要优点是隔离了具体类的生成,使得客户部需要知道什么被创建了, 由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中 定义的那些公共接口,因此只须改变具体工厂的实例,就可以再某种程度上改变整个软件 系统的行为。使用抽象工厂模式的最大好处是,当一个产品族
27、中的多个对象被设计成一起工 作时,她能保证客户端只是使用同一个产品族中的对象。3.7Bean工厂的创建3.7.1属性配置文件解读public class PropertiesBeanFactory implements BeanFactory ( private static Properties props=new Properties();static (ClassLoader cl=PropertiesBeanFactory.class.getClassLoader();Inputstream in=cl.getResourceAsStream(beans.properties);try
28、 (props.load(in); catch (IOException e) (/ TODO Auto-generated catch blocke.printStackTrace();public PropertiesBeanFactory()(Overridepublic Object getBean(String beanName) (String className=(String)props.get(beanName);try (return Class.forName(className).newInstance(); catch (InstantiationException
29、e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (ClassNotFoundException e) (/ TODO Auto-generated catch block e.printStackTrace();return null;public static void main(String args) (System.out.pri
30、ntln(newPropertiesBeanFactory().getBean(channelService);3.7.2Jdom解析XML文档public class ClassPathXMLBeanFactory implements BeanFactory (private Map beans=new HashMap(); public ClassPathXMLBeanFactory()(/1.定位Ubeans.xml文件上InputStreamin=this.getClass().getClassLoader().getResourceAsStream(beans.xml);/stre
31、am api for xml SAXBuilder builder=new SAXBuilder();/2.应该是通过jdom解析工具返回一个文档对象模型 Document doc=null;try (doc=builder.build(in); catch (JDOMException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (IOException e) (/ TODO Auto-generated catch block e.printStackTrace();/3.通过文档对象模型取得根元素Ele
32、ment root=doc.getRootElement();/通过对象模型取得所有的孩子beanList elements= root.getChildren(bean);for(int i=0;ielements.size();i+)Element child=(Element)elements.get(i);String id=child.getAttributeValue(id);String clazz=child.getAttributeValue(class);/System.out.println(id+_+clazz);Object o=null;try o=Class.fo
33、rName (clazz).newInstance(); catch (InstantiationException e) / TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) / TODO Auto-generated catch block e.printStackTrace(); catch (ClassNotFoundException e) / TODO Auto-generated catch block e.printStackTrace();beans.pu
34、t(id, o);/看bean下是否还有孩子,有,则取得,List properties=child.getChildren(property);for(int j=0;jproperties.size();j+)Element property=(Element)properties.get(j);String name=property.getAttributeValue(name);String ref=property.getAttributeValue(ref);/形成property的set方法名称String methodName=set+name.substring(0,1).
35、toUpperCase()+name.substring(1);/取得实际参数Object o2=beans.get(ref);/ChannelDaoImpltry (通过实际参数的类型及方法名称得到Method对象Method method=o.getClass().getMethod(methodName, o2.getClass().getInterfaces();method.invoke(o, o2); catch (SecurityException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (
36、NoSuchMethodException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (IllegalArgumentException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) (/ TODO Auto-generated catch block e.printStackTrace(); catch (InvocationTargetException e) (/
37、TODO Auto-generated catch block e.printStackTrace(); Overridepublic Object getBean(String beanName) (return beans.get(beanName); pUblic static void main(String args) (BeanFactory factory=new ClassPathXMLBeanFactory();/System.out.println()factory.getBean(channelService);Channel c=new Channel(); c.set
38、Name(android);(ChannelService)factory.getBean(channelService).add(c);4. 网站前台4.1两种包含静态包含动态包含写法资源路径都是服务器端根路径,包含应用程序名彳称Tomcat解析将被含页面代码复制合并到包含页面 中,不生成被包含页的对应的servlet执行到包含页面时请求转发,生成被 包含页面对应的servlet传参数不可以传参数可以传参数 也可以用传参Servlet 中需要使用 include(request,response)资源应用可以包含html,jspHtml,jsp,servlet应用场景一般对于静态网页,或者不
39、变化的网 页,没有数据访问的网页除静态之外的,由于动态包含效率较 静态低,所有在都可以使用的情况下 优先使用静态包含5. Mybatis 总结Pnmrtive/Siniple (int. String, Date)PrimitiYe/Simpie int, String, Date)Mapper1. 持久化的概念2. mybatis框架的运行机制(主要是基于反射)3. 几个配置文件a. SqlMapConfig配置别名,数据源,引入SqlMapper文件一般位于ClassPath根路径下b. SqlMapperSql语句编写的文件对于一个类(一个表)一般有一个 Mapper4. SqlMapp
40、erSelect Insert Update DeleteParamter :传入参数,如果是对象,则写对象的类型(通常是短名称)单一参数,如int string等Map :主要用于不相关的一些参数传入resultMap结果映射:不匹配问题字段与属性名不能实现自动的注入统一都设置5. 高级映射一对一(多对一)Association propertyname” column=person_id” select=另卜一条 sql 语句”带来N+1问题解决办法:跨表查询,但是映射需要把所有的字段与属性显示对应Association JavaType一对多(多对多)Collenction最核心的是面向
41、对象的关系,数据库表间的关系,其次sql语句熟练6. 动态sqlSql语句块If choose foreach $6. CMS总结6.1登录与登出验证码的应用*Session 的应用 *基本的参数请求方式*基本的参数处理方式*Request.getParameter()Filter *统一判断用户是否登录统一设置请求中的编码配置,使用场景6.2文章管理 CRUD 增删改查搜分修改一般是通过servlet到达jsp页面的(因为需要回显)比增的表单参数多一个id列表展现:Servlet 中通过 request.setAtrribute 设置属性Forwad :jsp页面可以访问到 Redirect
42、 :jsp访问不到 服务器端重定向* 客户端重定向* Request.getAttribute()JstlEL $(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. base href= ” 6.3频道管理*1. service层次的抽取主要是解决了多个dao之间存在着调用的先后关系Servlet-service-dao Dao层提供的方法更接近数据库层面的表示方法 Service层提供的方法更接近业务逻辑表示2. 事务管理