JavaWeb框架-SSH-真品与“赝品”?
来源:互联网 发布:千手一族 知乎 编辑:程序博客网 时间:2024/06/10 12:27
话说
前一篇博客介绍了SSH框架的整合,今天就用起来。
目标——仿照CSDN个人博客主页面,创造一个它的“双胞胎”
笔者一直想创建一个属于自己的网站,然后把毕生之所学都用在这个网站上,以后的以后,这就是自己的作品,没事就拿出来回味回味,把玩把玩。我虽不定闻名于世,但是我所建立的网站可以永久“基业长青”。
扯远了哈。各位读者,晚上好。这篇博客就是想仿照CSDN的个人博客主页面来写一个玩一下。当然,这个博客今天先发表,后期有变动,再一步步更新。
目录
1、最终效果图
2、整体布局
3、SSH框架搭建
4、核心代码
5、页面
6、总结
7、待完善…
开发环境:
IntelliJ IDEA(2017.2.5)
MySQL
Maven Web项目
1、最终效果图
真品:
“赝品”:
优化之路还长,嘻嘻。见笑了,诸位!
2、整体布局
3、SSH框架搭建
步骤和上一篇一样。这里不再赘述,仅罗列步骤。注意开启声明式事务的时候,要把默认的基于接口的代理变为基于类的代理,否则总报错:找不到bean。其实神马问题也木有。
1、pom.xml
2、struts.xml
3、spring.xml
4、web.xml
5、搞定!庆祝一下(小二,上菜!)
1、pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hmc.ssh</groupId> <artifactId>CSDN_blog</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>CSDN_blog Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--spring jar--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.1.RELEASE</version> </dependency> <!--spring web--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.1.RELEASE</version> </dependency> <!-- Struts2 --> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.5.13</version> </dependency> <!--spring和struts2整合需要一个插件包--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId> <version>2.5.13</version> </dependency> <!--配置Hibernate--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.12.Final</version> </dependency> <!--Mysql驱动包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--配置数据连接池--> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <!--导入 ORM--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.0.1.RELEASE</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>RELEASE</version> </dependency> <!--配置AOP--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.12</version> </dependency> <!--Spring Test--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.1.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>RELEASE</version> </dependency> <!--导入jstl--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <finalName>CSDN_blog</finalName> </build></project>
2、struts.xml
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"><struts> <!--配置struts使其识别bookAction这种默认bean名称--> <constant name="struts.objectFactory" value="spring"/> <!--DMI配置--> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <constant name="struts.devMode" value="true"/> <package name="csdn" extends="struts-default"> <global-allowed-methods>regex:.*</global-allowed-methods> <action name="*_*" class="{1}Action" method="{2}"> <result name="success">/WEB-INF/{1}/{2}.jsp</result> <result name="redirectUrl" type="redirect">${url}</result> </action> </package> <include file="example.xml"/> <!-- Add packages here --></struts>
要是世界上的配置都这么简单就好了。
这个配置最核心的就是DMI——Dynamic Method Invocation
开启动态方法调用:
第一步:写好action _ 这里有一个迷人的笑脸,可惜无法显示;
第二步:配置常量,开启动态方法调用;
第三部:对全局方法用正则表达式全部放行。
第三步如果没有做,就会出现这样的情况:
一个页面可以访问,其他页面访问不了。注意配置的每个细节。
3、spring.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--开启spring 注解--> <context:component-scan base-package="com.hmc.csdn"/> <!--配置数据源--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!--配置url username password--> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost/meice_blog"/> <property name="username" value="root"/> <property name="password" value="119913"/> <!--初始化连接池大小--> <property name="initialSize" value="10"/> </bean> <!--配置sessionFactory--> <bean name="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!--属性注入dataSource--> <property name="dataSource" ref="dataSource"/> <!--扫描加入注解的实体类(基于包)--> <property name="packagesToScan"> <array> <value>com.hmc.csdn.modle</value> </array> </property> <!--配置Hiberante其他属性--> <property name="hibernateProperties"> <!--2种方式多可以--> <!-- <value> hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=update hibernate.show_sql=true </value>--> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> </bean> <!--配置声明式事务--> <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean><!--还要配置基于AOP的事务管理--> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="allMethod" expression="execution(* com.hmc.csdn.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethod"/> </aop:config> <!--配置基于类的代理,如果不配置或者false,就是默认基于接口--> <!--如果没有配置,总是报错,类似:expected to be of type 'com.hmc.csdn.dao.BlogDao' but was actually of type 'com.sun.proxy.$Proxy27'--> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy></beans>
这里和上一篇博客相比,只增加了一点,那就是开启了基于类的代理。
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
所以,上一篇博客的问题,到此就乖乖被摆平啦。
4、web.xml
这个不要忘记配置。所有的一切,都要通过Web来展现。我们和客户的第一次产品交流。
<!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> <!--配置struts2过滤器--> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--配置Spring监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置可以找到spring.xml--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring.xml</param-value> </context-param></web-app>
5、搞定!庆祝一下(小二,上菜!)
4、核心代码
严格按照面向对象、面向接口、面向切面来设计。
1) model
2) dao
3) service
4) controller
1) model
Blog
package com.hmc.csdn.modle;import org.hibernate.annotations.GenericGenerator;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;/** * User:Meice * 2017/11/7 */@Entitypublic class Blog { private int blog_id; private String blog_title; private String blog_content; @Id @GenericGenerator(name = "myid",strategy = "native") @GeneratedValue(generator = "myid") public int getBlog_id() { return blog_id; } public void setBlog_id(int blog_id) { this.blog_id = blog_id; } public String getBlog_title() { return blog_title; } public void setBlog_title(String blog_title) { this.blog_title = blog_title; } public String getBlog_content() { return blog_content; } public void setBlog_content(String blog_content) { this.blog_content = blog_content; } @Override public String toString() { return "Blog{" + "blog_id=" + blog_id + ", blog_title='" + blog_title + '\'' + ", blog_content='" + blog_content + '\'' + '}'; }}
这里为了看效果,先设置了几个简单的字段,后期还会不断完善。
2) dao
IBlogDao
package com.hmc.csdn.dao;import java.util.List;public interface IBlogDao { void save(Object obj); void del(int id); void update(Object obj); List<?> list(); Object listOne(int id);}
BlogDao
package com.hmc.csdn.dao;import com.hmc.csdn.modle.Blog;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate5.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;import javax.annotation.Resource;import java.awt.print.Book;import java.util.List;/** * User:Meice * 2017/11/7 */@Repositorypublic class BlogDao extends HibernateDaoSupport implements IBlogDao{ //继承框架底层封装好的获取sesson的方法,就可以避免在通过sessionFactory获取session了 @Resource(name = "sessionFactory") public void setSuperSessionFactory(SessionFactory sessionFactory) { super.setSessionFactory(sessionFactory); } /** * 新增 */ public void save(Object obj) { getSessionFactory().getCurrentSession().save(obj); } /** * 删除 */ public void del(int id) { System.out.println("删除方法,进来了...."); /*getSessionFactory().getCurrentSession().delete(id);*/ // Integer not a entity! //需要注意,Hibernate删除是直接删除对象,但是根据的是id?所以...需要这么操作. Blog blog = new Blog(); blog.setBlog_id(id); getSessionFactory().getCurrentSession().delete(blog); } /** * 修改 */ public void update(Object obj) { getSessionFactory().getCurrentSession().update(obj); } /** * 查询所有 */ public List<?> list() { List<Blog> list = getSessionFactory().getCurrentSession().createQuery("from Blog blog order by blog.blog_id desc") .list(); return list; } /** * 查询单个对象 */ public Object listOne(int id) { Blog blog =(Blog) getSessionFactory().getCurrentSession().createQuery("from Blog where blog_id = ?") .setParameter(0,id) .uniqueResult(); return blog; } /** * 定义获取分页总条目数count的方法 */ public int countBlogs() { Long countLon =(Long) getSessionFactory().getCurrentSession().createQuery("select count(blog_id) from Blog") .uniqueResult(); int count = countLon.intValue(); return count; } /** * 定义分页查询获取博客列表方法getBlogsPager */ public List<Blog> getBlogsPager(int offset,int pageSize) { List<Blog> blogs = getSessionFactory().getCurrentSession().createQuery("from Blog blog order by blog.blog_id desc") .setFirstResult(offset) .setMaxResults(pageSize) .list(); return blogs; } /** * 运行结果类似: * Hibernate: select blog0_.blog_id as blog_id1_0_, blog0_.blog_content as blog_con2_0_, blog0_.blog_title * as blog_tit3_0_ from Blog blog0_ limit ? */}
3) service
IBlogService
package com.hmc.csdn.service;import java.util.List;public interface IBlogService { void add(Object obj); void del(int id); void update(Object obj); List<?> list(); Object listOne(int id);}
BlogService
package com.hmc.csdn.service;import com.hmc.csdn.dao.BlogDao;import com.hmc.csdn.modle.Blog;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.List;/** * User:Meice * 2017/11/7 */@Servicepublic class BlogService implements IBlogService { private BlogDao blogDao; @Resource(name = "blogDao") public void setBlogDao(BlogDao blogDao) { this.blogDao = blogDao; } /** * 发布博客 */ public void add(Object obj) { blogDao.save(obj); } /** * 删除博客 */ public void del(int id) { blogDao.del(id); } /** * 修改博客 */ public void update(Object obj) { blogDao.update(obj); } /** * 博客列表 * @return */ public List<?> list() { List<Blog> list =(List<Blog>) blogDao.list(); return list; } /** * 单条博客列表 */ public Object listOne(int id) { Blog blog =(Blog) blogDao.listOne(id); return blog; } /** * 调用博客数目方法 */ public int count() { int count = blogDao.countBlogs(); return count; } /** * 调用分页查询数据方法 */ public List<Blog> getBlogsByPager(int offset,int pageSize) { List<Blog> blogs = blogDao.getBlogsPager(offset,pageSize); return blogs; }}
这里的困惑是:定义接口,需要高屋建瓴的能力,否则看得不长远,定义的接口就比较幼稚。
4) controller
blogAction
package com.hmc.csdn.controller;import com.hmc.csdn.modle.Blog;import com.hmc.csdn.service.BlogService;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ModelDriven;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Controller;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.util.List;/** * User:Meice * 2017/11/7 */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:spring.xml")@Controller(value = "blogAction")public class blogAction implements ModelDriven<Blog> { private Blog blog; @Autowired private BlogService blogService; /** * Struts接收参数的第一种方式 * 因为没发实现2个ModelDriven */ private int pageIndex=1;//当前页 private int count;//博客总条目数 private int totalPage;//总页数 private int offset;//偏移量,用于limit private int pageSize=15;//每页显示条目 private List<Blog> blogs ;//存放博客,这样就把分页整体作为blogAction的一个属性 /** * 博客列表 */ public String list() { count = blogService.count(); pageIndex =pageIndex; offset= (pageIndex-1)*pageSize; //执行方法 List<Blog> blogs =(List<Blog>) blogService.getBlogsByPager(offset,pageSize); //传递值 ActionContext.getContext().put("blogs",blogs); return "success"; } /** * 跳转到发布博客界面 */ public String add() { System.out.println("我是blogAction==> 进来了..."); return "success"; } /** * 执行发布博客操作 */ public String doAdd() { //调用方法 blogService.add(blog); //重新跳转到blog_list界面 ActionContext.getContext().put("url","blog_doAdd"); return "redirectUrl"; } /** * 跳转到修改博客界面 * @return */ public String update() { //调用方法 Blog blogOne =(Blog) blogService.listOne(blog.getBlog_id()); //传递值 ActionContext.getContext().put("blog",blogOne); return "success"; } /** * 执行修改操作 */ public String doUpdate() { //调用修改方法 blogService.update(blog); ActionContext.getContext().put("url","blog_list"); return "redirectUrl"; } /** * 删除博客 */ public String del() { //执行方法 blogService.del(blog.getBlog_id()); ActionContext.getContext().put("url","blog_list"); return "redirectUrl"; } //这个很像单例的设计模式 public Blog getModel() { if(blog == null) { blog = new Blog(); } return blog; } public int getPageIndex() { return pageIndex; } public void setPageIndex(int pageIndex) { this.pageIndex = pageIndex; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public int getTotalPage() { totalPage = (int)Math.ceil((double)count/pageSize); return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getOffset() { offset = (pageIndex-1)*pageSize; return offset; } public void setOffset(int offset) { this.offset = offset; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; }}
这里增加了分页的属性。也在BlogDao中增加了分页查询及查询博客总条目数的方法。
这里笔者想不到更好的传参方式,已经实现了一个ModelDriven,其他参数就通过属性方式来传递。应该还有更加简洁的办法,后期发现在优化。
5、页面
暂时只是做了个主页面,还有类别管理、评论管理、回收站等模块,后续陆续实现。
list.jsp——显示博客列表
add.jsp——发布博客
update.jsp——编辑博客
现在阶段,都还很丑陋,稚气未脱的柑橘。后期逐一美化。欢迎评论斧正!
list.jsp——显示博客列表
<%-- User: Meice Date: 2017/11/7 Time: 10:11--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html><head> <title>Meice_blog</title> <%--这里路径使用基于工程的绝对路径--%> <link type="text/css" rel="stylesheet" href="/CSDN_blog/css/blog.css"> <style type="text/css"> </style> <script src="/js/jquery-3.2.1.jar" type="text/javascript"></script> <script type="text/javascript"> </script></head><body> <div id="toolbar"> <h2 align="center" style="color: green">Meice_CSDN博客</h2> </div> <div id="blog_whole"> <div id="blog_head"> </div> <div id="tabs_head"> <h2 id="test"></h2> <ul id="ul_tab"> <li> <span> <a href="#">文章管理</a> </span> </li> <li> <span> <a href="#">类别管理</a> </span> </li> <li> <span> <a href="#">评论管理</a> </span> </li> <li> <span> <a href="#">回收站</a> </span> </li> <li> <span style="background-color: #a1ee08"> <a href="blog_add">写新文章</a> </span> </li> </ul> </div> <div id="sel_div"> <ul> <li>类别: </li> <li> <select style="width: 80px;height: 25px " > <option selected="selected">全部</option> <option>前言</option> <option>Java</option> </select> </li> <li> 类型: </li> <li> <select style="width: 80px;height: 25px"> <option selected="selected">全部</option> <option>原创</option> <option>转载</option> <option>翻译</option> </select> </li> </ul> </div> <div id="list_bog"> <table width="98%" align="center" border="1"> <caption></caption> <thead> <tr> <th>序号</th> <th>标题</th> <th>状态</th> <th>阅读</th> <th>评论</th> <th>评论权限</th> <th>操作</th> </tr> </thead> <tbody> <c:forEach var="blogs" items="${blogs}"> <tr> <td align="center">${blogs.blog_id}</td> <td>${blogs.blog_title}</td> <td align="center">审核中</td> <td></td> <td align="center">0</td> <td align="center"> <a href="#">禁止评论</a> </td> <td align="center"> <a href="blog_update?blog_id=${blogs.blog_id}">编辑</a> | <a href="#">置顶</a> | <a href="blog_del?blog_id=${blogs.blog_id}" onclick="return confirm('真的忍心删除么?')">删除</a> | <a href="#">分类</a> | </td> </tr> </c:forEach> <tr> <td colspan="7" align="center"> <c:if test="${pageIndex>1}"> <a href="blog_list?pageIndex=1">首页</a> <a href="blog_list?pageIndex=${pageIndex-1}">上一页</a> </c:if> <c:forEach var="x" begin="${pageIndex}" end="${pageIndex+9}"> <a href="blog_list?pageIndex=${x}">${x}</a> </c:forEach> <c:if test="${pageIndex<totalPage}"> <a href="blog_list?pageIndex=${pageIndex+1}">下一页</a> <a href="blog_list?pageIndex=${totalPage}">末页</a> </c:if> ${pageIndex}/${totalPage} </td> </tr> </tbody> <tfoot></tfoot> </table> </div> </div> <div id="pub_info"></div> <div></div> <div></div></body></html>
add.jsp——发布博客
<%-- User: Meice Date: 2017/11/7 Time: 16:22--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><html><head> <title>Meice_发布博客</title></head><body> <form action="blog_doAdd" method="post"> 标题:<input type="text" name="blog_title"><br/> <textarea name="blog_content" cols="50" rows="10"> </textarea><br/> <input type="submit" value="发布"> </form></body></html>
update.jsp——编辑博客
<%-- User: Meice Date: 2017/11/7 Time: 17:21--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><html><head> <title>Meice_修改博客</title></head><body> <form action="blog_doUpdate" method="post"> 标题:<input type="text" name="blog_title" value="${blog.blog_title}"><br/> <textarea name="blog_content" cols="50" rows="10" > ${blog.blog_content} </textarea><br/> <input type="submit" value="修改"> </form></body></html>
6、总结
1、解决问题不重要,重要的是解决问题的思路可以复用。比如总是报错,找不到bean,这个时候,就要耐心分析;
不是配置流程有问题,就是哪里写错了。
2、文本域鼠标开始定位没有在开头,下一次实现定位开头,不用回删;
3、如果博客内容过长,数据库字段是Hibernate自动生成的varchar(255),会报错如下:
Data truncation: Data too long for column 'blog_content' at row 1?
待处理;
4、为方便分页,笔者采用页面重定向,反复生成大量数据。发现一个很有意思的现象,那就是重定向访问过多,谷歌、火狐、360浏览器都会自动停止,只有IE还在那里傻乎乎的运行。所以一下生成了1000多条数据,不过也好,分页起来更有“浩瀚”之美!
5、设计接口的工作,有点像企业创始人,他们到达一定阶段,也许、大概、或者就是做类似设计接口之类的事吧。设计接口,要有高瞻远瞩的能力呢,否则定义的接口,不是不完善就是不好用。
7、待完善…
革命尚未成功,同志仍需努力!
小朋友们,下期再会!
- JavaWeb框架-SSH-真品与“赝品”?
- JavaWeb-ssh框架搭建
- SSH框架介绍(JavaWeb Develop)
- JavaWeb框架-SSH-整合流程!
- 真品篮球鞋与仿真鞋的分别
- javaweb三大框架SSH解读
- JavaWeb框架-基于SSH架构-01
- javaweb三大框架SSH解读
- javaweb三大框架SSH解读
- JavaWeb日记——浅析SSH框架
- javaweb三大框架(ssh)知识点总结
- javaweb三大框架SSH解读
- 《SSH框架》---SSH框架与框架
- 基于Struts、Spring、Hibernate的JavaWeb开发SSH框架配置
- JavaWeb面试题(一)---SSH框架面试题总结
- jbpm与ssh框架集成
- SSH框架与DWR整合
- jbpm与ssh框架集成
- 51talk-1 My birthday is coming
- 互斥锁和条件变量实现读写锁
- MyEclipse下安装MyBatis Generator代码反向生成工具
- JAVA获取日期属于当年第几周
- 自定义控件---图层,画布和canvas
- JavaWeb框架-SSH-真品与“赝品”?
- C# 打开指定目录并定位到文件
- java中的控制语句
- 数据结构简答题
- 剑指offer---斐波那契数列
- 欢迎使用CSDN-markdown编辑器
- POJ-1213 k层for的sum
- POJ 2186 Popular Cows (强连通分量)
- RabbitMQ RPC