博客系统

博客系统

登录业务逻辑

web层

public String login(){
        //登录业务逻辑
        User resUser = loginService.login(user);
        if (resUser == null){
            //错误信息回显
            this.addActionError("用户名或密码错");
            //结果页跳转
            return LOGIN;
        }else {
            //保存用户信息
            ActionContext.getContext().getSession().put("curUser",resUser);
            return SUCCESS;
        }
    }

注入service

<bean id="loginAction" class="com.le.web.LoginAction" scope="prototype">
        <property name="loginService" ref="loginService"/>
</bean>

配置结果页

<action name="loginAciton_*" class="loginAction" method="{1}">
    <result name="success">/WEB-INF/mgr/mgr_index.jsp</result>
    <result name="login_out" type="redirect">/mgr_login.jsp</result>
    <allowed-methods>login,loginout</allowed-methods>
</action>

页面结果显示

登录成功展示用户
<%@ taglib uri="/struts-tags" prefix="s"%>
<div class="h_top_right">
    <span style="margin-right: 50px"><s:property value="#session.curUser.username"/></span>
    <span>
        <a href="${pageContext.request.contextPath}/loginAciton_loginout.action" style="color:lightseagreen" target="_parent">退出</a>
    </span>
</div>
登录失败错误信息展示

<%@ taglib uri="/struts-tags" prefix="s"%>
<div class="login">博客后台管理系统
    <span style="color:red"><s:actionerror/></span>
</div>

service层

@Transactional
public class LoginServiceImpl implements LoginService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public User login(User user) {
        //调用dao 查询 用户
        User resUser = userDao.getUser(user.getUsername(), user.getPassword());
        return resUser;
    }
}
注入dao

<bean id="loginService" class="com.le.service.impl.LoginServiceImpl">
    <property name="userDao" ref="userDao"/>
</bean>

dao层

public class UserDaoImpl extends HibernateDaoSupport implements UserDao {

    @Override
    public User getUser(String username, String password) {
        //到数据库当中查询
        //设置到哪个表当中去查
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);
        //设置条件
        detachedCriteria.add(Restrictions.eq("username",username));
        detachedCriteria.add(Restrictions.eq("password",password));

        List<User> list = (List<User>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
        System.out.println(list);
        if (list.size()>0){
            return list.get(0);
        }
        return null;
    }
}

建立对应domain,与映射文件并引入
<!-- 设置映射文件 -->
<property name="mappingResources">
    <list>
        <value>com/le/domian/User.hbm.xml</value>
        <value>com/le/domian/Article.hbm.xml</value>
        <value>com/le/domian/Category.hbm.xml</value>
    </list>
</property>

注入sessionFactory

<bean id="userDao" class="com.le.dao.impl.UserDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

退出业务逻辑

点击退出按钮

<span>
    <a href="${pageContext.request.contextPath}/loginAciton_loginout.action" style="color:lightseagreen" target="_parent">退出</a>
</span>

处理action业务逻辑

struts.xml

<action name="loginAciton_*" class="loginAction" method="{1}">
    <result name="success">/WEB-INF/mgr/mgr_index.jsp</result>
    <result name="login_out" type="redirect">/mgr_login.jsp</result>
    <allowed-methods>login,loginout</allowed-methods>
</action>

LoginAction类

public String loginout(){
    /*清空当前的用户session*/
    ActionContext.getContext().getSession().remove("curUser");
    return "login_out";
}

分类

添加

页面按钮点击

<div class="item1" >
    <div>
        <span>parentid:</span>
        <input type="text" class="am-form-field" id="parentid" >&nbsp;&nbsp;
        <br/>
        <span>分类名称:</span>
        <input type="text" class="am-form-field" id="cname" >&nbsp;&nbsp;
        <br/>
        <button class="am-btn am-btn-default" type="button" id="addcategory">添加</button>
    </div>
</div>

/*监听添加按钮点击*/
$("#addcategory").click(function () {
    /*获取文本框的内容*/
    var parentid = $("#parentid").val();
    var cname = $("#cname").val();
    alert(parentid+cname);
    /*发送请求*/
    $(window).attr('location','${pageContext.request.contextPath}/category_add.action?parentid='+parentid+'&cname='+cname);
});
web层接收请求
public class CategoryAction extends ActionSupport implements ModelDriven<Category> {
    private Category category = new Category();
    @Override
    public Category getModel() {
        return category;
    }

    //注入service
    @Setter
    private CategoryService categoryService;
    /*添加分类*/
    public String add(){
        //调用业务层
        categoryService.save(category);
        return "listAction";
    }
}       
配置struts2路径
<!--分类 action-->
<action name="category_*" class="categoryAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_category.jsp</result>
    <result name="listAction" type="redirectAction">category_list.action</result>
    <allowed-methods>add,list,updateUI,update,delete</allowed-methods>
</action>

注入service

<bean  id="categoryAction" class="com.le.web.CategoryAction" scope="prototype">
    <property name="categoryService" ref="categoryService"/>
</bean>

处理业务
@Transactional
public class CategoryServiceImpl implements CategoryService {
    @Setter
    private CategoryDao categoryDao;
    @Override
    public void save(Category category) {
        /*调用dao*/
        System.out.println("调用service");
        categoryDao.save(category);
    }
}

注入dao

<bean id="categoryService" class="com.le.service.impl.CategoryServiceImpl">
    <property name="categoryDao" ref="categoryDao"/>
</bean>

dao添加

public class CategoryDaoImpl extends HibernateDaoSupport implements CategoryDao {
    /*保存分类*/
    @Override
    public void save(Category category) {
        this.getHibernateTemplate().save(category);
    }
}    

注入工厂

<bean id="categoryDao" class="com.le.dao.impl.CategoryDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

查询所有

左侧分类链接点击发送请求
<ul>
    <li><a href="${pageContext.request.contextPath}/category_list.action" target="mainFrame"><i></i>
        分类管理</a></li>
    <li><a href="${pageContext.request.contextPath}/article_pageList.action" target="mainFrame"><i></i>文章管理</a></li>
    <li></i><a href="${pageContext.request.contextPath}/location_account.action" target="mainFrame"><i></i>用户管理</a></li>
</ul>

配置接收请求

<!--分类 action-->
<action name="category_*" class="categoryAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_category.jsp</result>
    <result name="listAction" type="redirectAction">category_list.action</result>
    <allowed-methods>add,list,updateUI,update,delete</allowed-methods>
</action>

<bean  id="categoryAction" class="com.le.web.CategoryAction" scope="prototype">
    <property name="categoryService" ref="categoryService"/>
</bean>

action处理

    public String list(){
        //调用业务层 查询所有分类
        List<Category> list =  categoryService.getAllCategory();
        System.out.println(list);
        //把数据存到值栈当中
        ActionContext.getContext().getValueStack().set("categorylist",list);
        return "list";
    }
页面展示数据

<ul class="title_ul">
    <li>parentid</li>
    <li>分类名称</li>
    <li>修改分类</li>
    <li>删除分类</li>
</ul>
<s:iterator value="categorylist" var="category">
    <ul class="list_goods_ul">
        <li><s:property value="#category.parentid"/> </li>
        <li><s:property value="#category.cname"/></li>
        <li>
            <a href="#" class="updatebtn" data-id="<s:property value="#category.cid"/>">
                 <img class="img_icon" src="../../images/edit_icon.png" alt="">
             </a>
        </li>
        <li>
            <a href="${pageContext.request.contextPath}/category_delete.action?cid=<s:property value="#category.cid"/>">
                <img class="img_icon" src="../../images/delete_icon.png" alt="">
             </a>
        </li>
    </ul>
</s:iterator>

调用业务层

@Transactional
public class CategoryServiceImpl implements CategoryService {
    @Setter
    private CategoryDao categoryDao;
    @Override
    public void save(Category category) {
        /*调用dao*/
        categoryDao.save(category);
    }

    @Override
    public List<Category> getAllCategory() {
        //调用dao层查询所有分类
        List<Category> list = categoryDao.getAllCategory();
        return list;
    }
}

调用dao层

public class CategoryDaoImpl extends HibernateDaoSupport implements CategoryDao {
    /*保存分类*/
    @Override
    public void save(Category category) {
        this.getHibernateTemplate().save(category);
    }
    /*获取所有分类信息*/
    @Override
    public List<Category> getAllCategory() {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Category.class);
        List<Category> list = (List<Category>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
        return list;
    }
}

修改
界面准备
结构
<div id="modal_content2" style="height: 250px; display: none">
    <div id="close2"><img src="images/delete_icon.png" alt=""></div>
    <div class="edit_content">

        <div class="item1">
            <div>
                <span>添加分类:</span>
            </div>
        </div>
        <div class="item1" >
            <div>
                <span>parentid:</span>
                <input type="text" class="am-form-field" id="parentid2" >&nbsp;&nbsp;
                <br/>
                <span>分类名称:</span>
                <input type="text" class="am-form-field" id="cname2" >&nbsp;&nbsp;
                <br/>
                <input type="hidden" id="cid2">
                <button class="am-btn am-btn-default" type="button" id="updatebtn">修改</button>
            </div>
        </div>
    </div>
</div>
样式
<style>
    #modal_content2{
        padding: 30px 20px;
        width: 400px;
        height: 200px;
        background: white;
        position: fixed;
        left: 50%;
        top: 50%;
        margin-left: -200px;
        margin-top: -100px;
        display: none;
    }
    #close2{
        position: absolute;
        right: 10px;
        top: 10px;
    }
</style>
监听修改按钮
<li>
    <a href="#" class="updatebtn" data-id="<s:property value="#category.cid"/>">
        <img class="img_icon" src="../../images/edit_icon.png" alt="">
    </a>
</li>

异步发送请求
/*监听修改按钮点击*/
$(".updatebtn").click(function () {
    /*1.当前点的是哪一条数据*/
    var cid = $(this).data("id");
      /*取出对应id的数据,到数据库当中查询当前记录
       * 返回给页面
       * 展示到页面当中.
       * 发送请求的时候,不需要页面的跳转 Ajax(前端技术)   能够取当前返回数据  展示到界面
       * */
        $.post("${pageContext.request.contextPath}/category_updateUI.action",{"cid":cid},function (data) {
                console.log("-------json------");
                console.log(data);
                /*把json数据展示到文本框 */
                $("#parentid2").val(data[0].parentid);
                $("#cname2").val(data[0].cname);
                $("#cid2").val(data[0].cid);
        },"json");

    /*2.把修改界面弹出*/
    $("#modal_view").fadeIn();
    $("#modal_content2").fadeIn();
});

服务器接收请求;web层接收到数据后,以json形式返回;页面接收到返回的json进行展示

/*修改数据展示*/
public String updateUI() throws IOException {
    //调用业务层
    Category category2 = categoryService.getOneCategory(category.getCid());
    //把数据给页面
    //以json(数据格式) 响应给页面
    JSONArray jsonArray = JSONArray.fromObject(category2, new JsonConfig());
    //响应给页面
    ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");
    ServletActionContext.getResponse().getWriter().println(jsonArray.toString());
    return null;
}

调用服务层

@Override
public Category getOneCategory(Integer cid) {
    //调用dao层
    return categoryDao.getOneCategory(cid);
}

调用dao层
@Override
public Category getOneCategory(Integer cid) {
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Category.class);
    //设置条件
    detachedCriteria.add(Restrictions.eq("cid",cid));
    List<Category> list = (List<Category>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
    if(list.size() > 0){
        return list.get(0);
    }
    return null;
}

修改按钮点击处理

<div class="item1" >
    <div>
        <span>parentid:</span>
        <input type="text" class="am-form-field" id="parentid2" >&nbsp;&nbsp;
        <br/>
        <span>分类名称:</span>
        <input type="text" class="am-form-field" id="cname2" >&nbsp;&nbsp;
        <br/>
        <input type="hidden" id="cid2">
        <button class="am-btn am-btn-default" type="button" id="updatebtn">修改</button>
    </div>
</div>
监听修改按钮
$("#updatebtn").click(function () {
    /*1.获取文本框值*/
    var parentid2 = $("#parentid2").val();
    var cname2 = $("#cname2").val();
    var cid2 = $("#cid2").val();
    /*2.发送请求*/
    $(window).attr('location','${pageContext.request.contextPath}/category_update.action?parentid='+parentid2+'&cname='+cname2+'&cid='+cid2);
});

修改web层业务处理
public String update(){
    //调用业务层
    categoryService.update(category);
    return "listAction";
}
跳转回列表页面
<!--分类 action-->
<action name="category_*" class="categoryAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_category.jsp</result>
    <result name="listAction" type="redirectAction">category_list.action</result>
    <allowed-methods>add,list,updateUI,update,delete</allowed-methods>
</action>

业务层

@Override
public void update(Category category) {
    //调用dao
    categoryDao.update(category);
}
dao层
@Override
public void update(Category category) {
    this.getHibernateTemplate().update(category);
}

删除
监听删除按钮点击

<li>
    <a href="${pageContext.request.contextPath}/category_delete.action?cid=<s:property value="#category.cid"/>">
        <img class="img_icon" src="../../images/delete_icon.png" alt="">
     </a>
</li>
web接收
public String delete(){
    categoryService.delete(category);
    return "listAction";
}
业务层处理
@Override
public void delete(Category category) {
    categoryDao.delete(category);
}
dao层处理
@Override
public void delete(Category category) {
    this.getHibernateTemplate().delete(category);
}
转发到列表页
<!--分类 action-->
<action name="category_*" class="categoryAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_category.jsp</result>
    <result name="listAction" type="redirectAction">category_list.action</result>
    <allowed-methods>add,list,updateUI,update,delete</allowed-methods>
</action>

同步请求与异常请求
同步请求
  • 发送请求时,后面的标签都会等待请求结束(可能会出现后面标签空白,没有加载出来的暂时现象)
  • 请求结束后,后续标签才会继续加载
异步请求
  • 会另开一条线单独去发送请求
  • 后续标签会继续加载.
  • 请求完毕后, 会通知请求结束.

文章列表

创建表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for article
-- ----------------------------
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article`  (
  `article_id` int(11) NOT NULL AUTO_INCREMENT,
  `article_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `article_time` bigint(11) NULL DEFAULT NULL,
  `article_content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
  `article_pic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `article_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `article_cid` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`article_id`) USING BTREE,
  INDEX `fk_article_category`(`article_cid`) USING BTREE,
  CONSTRAINT `fk_article_category` FOREIGN KEY (`article_cid`) REFERENCES `category` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of article
-- ----------------------------
INSERT INTO `article` VALUES (1, '文章1', NULL, '内容1', '05ae5bc3292c4701bbf541bb82709e73.png', NULL, 1);
INSERT INTO `article` VALUES (2, '文章2', NULL, '内容2', '05ae5bc3292c4701bbf541bb82709e73.png', NULL, 2);
INSERT INTO `article` VALUES (3, '文章3', NULL, '内容3', '05ae5bc3292c4701bbf541bb82709e73.png', NULL, 3);
INSERT INTO `article` VALUES (4, '文章4  ', NULL, '<p>内容433</p><p>55</p>', '05ae5bc3292c4701bbf541bb82709e73.png', '内容43355...', 4);
INSERT INTO `article` VALUES (5, '文章5  ', 1557920304913, '<p>内容5333</p><p><br/></p>', '2c71fe27368c4100a480e9045dfac258.jpg', '内容5333...', 10);
INSERT INTO `article` VALUES (6, '文章6', NULL, '内容6', '05ae5bc3292c4701bbf541bb82709e73.png', NULL, 5);

-- ----------------------------
-- Table structure for category
-- ----------------------------
DROP TABLE IF EXISTS `category`;
CREATE TABLE `category`  (
  `cid` int(255) NOT NULL AUTO_INCREMENT,
  `cname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `parentid` int(255) NULL DEFAULT NULL,
  PRIMARY KEY (`cid`) USING BTREE,
  INDEX `cid`(`cid`) USING BTREE,
  INDEX `cid_2`(`cid`, `parentid`) USING BTREE,
  INDEX `parentid`(`parentid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 15 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of category
-- ----------------------------
INSERT INTO `category` VALUES (1, 'JAVA', 0);
INSERT INTO `category` VALUES (2, 'Python', 0);
INSERT INTO `category` VALUES (3, '大前端', 0);
INSERT INTO `category` VALUES (4, 'Java Web', 1);
INSERT INTO `category` VALUES (5, 'Hibernate', 1);
INSERT INTO `category` VALUES (6, 'Struts', 1);
INSERT INTO `category` VALUES (7, 'Spring', 1);
INSERT INTO `category` VALUES (8, '机器语言', 2);
INSERT INTO `category` VALUES (9, '爬虫', 2);
INSERT INTO `category` VALUES (10, '画图', 2);
INSERT INTO `category` VALUES (11, '大数据', 2);
INSERT INTO `category` VALUES (12, 'Vue', 3);
INSERT INTO `category` VALUES (13, 'json', 3);

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '1', '1');
INSERT INTO `user` VALUES (2, 'admin', 'admin');

SET FOREIGN_KEY_CHECKS = 1;
建立domain
Article类

package com.le.domian;

import lombok.Getter;
import lombok.Setter;

@Getter@Setter
public class Article {
    private Integer article_id;
    private String article_title;
    private Long article_time;
    private String article_content;
    private String article_pic;
    private String article_desc;
    private Category category;

    @Override
    public String toString() {
        return "Article{" +
                "article_id=" + article_id +
                ", article_title='" + article_title + '\'' +
                ", article_time=" + article_time +
                ", article_content='" + article_content + '\'' +
                ", article_pic='" + article_pic + '\'' +
                ", article_desc='" + article_desc + '\'' +
                ", category=" + category +
                '}';
    }
}
关系映射Article.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.le.domian.Article" table="article" >
        <!--建立类属性哪一个是主键  还要跟数据库当中主键进行对象-->
        <id name="article_id" column="article_id" >
        <generator class="native"/>
    </id>

        <!--建立类中的普通属性与数据库当中字段进行关联-->
        <property name="article_title" column="article_title" />
        <property name="article_content" column="article_content"/>
        <property name="article_time" column="article_time"/>
        <property name="article_pic" column="article_pic"/>
        <property name="article_desc" column="article_desc"/>
        <many-to-one name="category" class="com.le.domian.Category" column="article_cid"/>

    </class>
</hibernate-mapping>

查询文章列表数据

发送请求

<frame src="${pageContext.request.contextPath}/article_list.action" name="mainFrame" >
配置接收请求

public class ArticleAction extends ActionSupport implements ModelDriven<Article> {
    private Article article = new Article();
    @Override
    public Article getModel() {
        return article;
    }
    //注入
    @Setter
    private ArticleService articleService;
    public String list(){
        System.out.println("list---------------");
        //调用业务层
        List<Article> allArticle = articleService.getAllArticle();
        System.out.println(allArticle);
        //把数据存取值栈当中,转发到jsp
        ActionContext.getContext().getValueStack().set("allArticle",allArticle);
        return "list";
    }
}    

<!--文章action-->
<action name="article_*" class="articleAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_main.jsp</result>
    <result name="edit">/WEB-INF/mgr/mgr_edit_article.jsp</result>
    <result name="listres" type="redirectAction">article_list.action</result>
    <allowed-methods>list,pageList,delete,getCategory,add,edit,update</allowed-methods>
</action>
<!--文章-->
<bean id="articleAction" class="com.le.web.ArticleAction" scope="prototype">
    <property name="articleService" ref="ArticleService"/>
</bean>
<bean id="ArticleService" class="com.le.service.impl.ArticleServiceImpl">
    <property name="articleDao" ref="ArticleDao"/>
</bean>
<bean id="ArticleDao" class="com.le.dao.impl.ArticleDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
调用服务层
@Transactional
public class ArticleServiceImpl implements ArticleService {
    //注入
    @Setter
    private ArticleDao articleDao;
    @Override
    public List<Article> getAllArticle() {
        //调用dao
        return articleDao.getAllArticle();
    }
}    
调用dao层
public class ArticleDaoImpl extends HibernateDaoSupport implements ArticleDao {
    @Override
    public List<Article> getAllArticle() {
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
        List<Article> list = (List<Article>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
        return list;
    }
}    
解决no-session延迟加载问题
产生原因
    关联对象默认都是采用延迟加载
    事务都是在业务层开启和提交的
    所以调用完业务层后, 事务已经提交,session已经关闭了
    由于关联的对象延迟加载 当使用关联对象时, session已经不在了, 所以会报no-session异常
解决办法
    1.不使用延迟加载
        效率太低
    2.使用spring提供的解决方案OpenInViewFilter
        提供了一个过滤器
        在web视图层提供session的打开和关闭

web.xml

<!--配置延迟加载-->
<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.action</url-pattern>
</filter-mapping>
展示所有列表
public class ArticleAction extends ActionSupport implements ModelDriven<Article> {
    private Article article = new Article();
    @Override
    public Article getModel() {
        return article;
    }
    //注入
    @Setter
    private ArticleService articleService;
    public String list(){
        //调用业务层
        List<Article> allArticle = articleService.getAllArticle();
        //把数据存取值栈当中,转发到jsp
        ActionContext.getContext().getValueStack().set("allArticle",allArticle);
        return "list";
    }
}    

<s:iterator value="list" var="article">
    <ul class="list_goods_ul">
        <li><s:property value="#article.article_id"/> </li>
        <li><s:property value="#article.article_title"/></li>
        <li><s:property value="#article.category.cname"/></li>
        <li>
            <a href="${ctx}/article_edit.action?article_id=<s:property value="#article.article_id"/>">
                <img class="img_icon" src="${ctx }/images/edit_icon.png" alt="">
            </a>
        </li>
        <li>
            <a href="${ctx }/article_delete.action?article_id=<s:property value="#article.article_id"/>">
                <img class="img_icon" src="${ctx }/images/delete_icon.png" alt="">
            </a>
        </li>
    </ul>
</s:iterator>


分页展示文章

构建pageBean

​ 相关属性
PageBean类

package com.le.domian;

import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Setter@Getter
public class PageBean<T> {
    /*当前页*/
    private Integer currentPage;
    /*一页多少条数据*/
    private Integer pageSize;
    /*当前查询的角标*/
    private Integer index;
    /*总记录数*/
    private Integer totalCount;
    /*总页数*/
    private Integer totalPage;
    /*当前页的数据*/
    private List<T> list;

    /*如果当前页没有设置,默认设置为第1页*/
    public void setCurrentPage(Integer currentPage) {
        if (currentPage == null) {
            currentPage = 1;
        }
        this.currentPage = currentPage;
    }
    /*如果没有设置当前页总记录数据,设置默认记录数为一页5条*/
    public void setPageSize(Integer pageSize) {
        if (pageSize == null) {
            pageSize = 5;
        }
        this.pageSize = pageSize;
    }
    /*计算当前页从数据库当中查询的位置*/
    public Integer getIndex() {
        return (currentPage-1)*pageSize;
    }
    /*计算总页数*/
    public Integer getTotalPage() {
        double ceil = Math.ceil(totalCount * 1.0 / pageSize);
        return (int)ceil;
    }

    @Override
    public String toString() {
        return "PageBean{" +
                "currentPage=" + currentPage +
                ", pageSize=" + pageSize +
                ", index=" + index +
                ", totalCount=" + totalCount +
                ", totalPage=" + totalPage +
                ", list=" + list +
                '}';
    }
}

监听分页点击获取数据
//分页
$("#page").paging({
    pageNo:<s:property value="currentPage"/>,
    totalPage: <s:property value="totalPage"/>,
    totalSize: <s:property value="totalCount"/>,
    callback: function(num) {
        //获取搜索关键字
        var keyWord = $("#input_search").val();
        $(window).attr('location','/article_pageList.action?currPage='+num+"&keyWord="+keyWord);
    }
})
<ul class="title_ul">
    <li>序号</li>
    <li>标题</li>
    <li>分类</li>
    <li>编辑</li>
    <li>删除</li>
</ul>

<s:iterator value="list" var="article">
    <ul class="list_goods_ul">
        <li><s:property value="#article.article_id"/> </li>
        <li><s:property value="#article.article_title"/></li>
        <li><s:property value="#article.category.cname"/></li>
        <li>
            <a href="${ctx}/article_edit.action?article_id=<s:property value="#article.article_id"/>">
                <img class="img_icon" src="${ctx }/images/edit_icon.png" alt="">
            </a>
        </li>
        <li>
            <a href="${ctx }/article_delete.action?article_id=<s:property value="#article.article_id"/>">
                <img class="img_icon" src="${ctx }/images/delete_icon.png" alt="">
            </a>
        </li>
    </ul>
</s:iterator>
web层接收请求
/*获取分页数据*/
@Setter
private Integer currPage = 1;
//搜索的关键字
@Setter
private String keyWord;
public String pageList(){
    //离线查询条件
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
    //设置条件
    if(keyWord != null){
        //添加条件
        detachedCriteria.add(Restrictions.like("article_title","%"+keyWord+"%"));
    }
    //调用业务层
    PageBean pageBean = articleService.getPageData(detachedCriteria,currPage,5);
    //数据存到值栈当中
    ActionContext.getContext().getValueStack().push(pageBean);
    return "list";
}

<!--文章action-->
<action name="article_*" class="articleAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_main.jsp</result>
    <result name="edit">/WEB-INF/mgr/mgr_edit_article.jsp</result>
    <result name="listres" type="redirectAction">article_pageList.action</result>
    <interceptor-ref name="loginInterceptor">
        <param name="excludeMethods">getCategory</param>
    </interceptor-ref>
    <interceptor-ref name="defaultStack"></interceptor-ref>
    <allowed-methods>list,pageList,delete,getCategory,add,edit,update</allowed-methods>
</action>
服务层处理

@Override
public PageBean getPageData(DetachedCriteria detachedCriteria, Integer currPage, int pageSize) {
    PageBean<Article> pageBean = new PageBean<>();
     //设置当前页
    pageBean.setCurrentPage(currPage);
    //设置当前一页有多少条数据
    pageBean.setPageSize(pageSize);
    //获取总记录数
    //从数据库当中查询总记录
    Integer totalCount = articleDao.getTotalCount(detachedCriteria);
    pageBean.setTotalCount(totalCount);
    //设置总页数
    pageBean.setTotalPage(pageBean.getTotalPage());
    //设置数据当前页数据
     //查询数据库
    List<Article> list =  articleDao.getPageData(detachedCriteria,pageBean.getIndex(),pageBean.getPageSize());
     //计算
    pageBean.setList(list);
    return pageBean;
}
dao层处理
@Override
public Integer getTotalCount(DetachedCriteria detachedCriteria) {
    //查询总记录
    detachedCriteria.setProjection(Projections.rowCount());
    List<Long> list = (List<Long>)this.getHibernateTemplate().findByCriteria(detachedCriteria);
    if(list.size() > 0){
        return list.get(0).intValue();
    }
    return 0;
}

@Override
public List<Article> getPageData(DetachedCriteria detachedCriteria, Integer index, Integer pageSize) {
    //清空查询总记录条件
    detachedCriteria.setProjection(null);
    List<Article> list = (List<Article>)this.getHibernateTemplate().findByCriteria(detachedCriteria, index, pageSize);
    return list;
}

搜索文章

点击搜索获取搜索内容发送给服务器
<div class="am-u-sm-12 am-u-md-3">
    <div class="am-input-group am-input-group-sm">
        <input type="text" class="am-form-field" id="input_search" value="<s:property value="#parameters.keyWord"/>">
        <span class="am-input-group-btn">
            <button class="am-btn am-btn-default" type="button" id="input_search_btn">搜索</button>
        </span>
    </div>
</div>

$("#input_search_btn").click(function () {
    //获取搜索关键字
    var keyWord = $("#input_search").val();
    //发送请求
    $(window).attr('location','/article_pageList.action?keyWord='+keyWord);
});

设置查询条件
/*获取分页数据*/
@Setter
private Integer currPage = 1;
//搜索的关键字
@Setter
private String keyWord;
public String pageList(){
    //离线查询条件
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
    //设置条件
    if(keyWord != null){
        //添加条件
        detachedCriteria.add(Restrictions.like("article_title","%"+keyWord+"%"));
    }
    //调用业务层
    PageBean pageBean = articleService.getPageData(detachedCriteria,currPage,5);
    //数据存到值栈当中
    ActionContext.getContext().getValueStack().push(pageBean);
    return "list";
}

删除

获取当前点的文章id发送删除请求

<li>
    <a href="${ctx }/article_delete.action?article_id=<s:property value="#article.article_id"/>">
        <img class="img_icon" src="${ctx }/images/delete_icon.png" alt="">
    </a>
</li>

接收请求
/*删除*/
public String delete(){
    //调用业务层
    Article article2 = new Article();
    article2.setArticle_id(article.getArticle_id());
    articleService.delete(article2);
    return "listres";
}

处理删除业务

@Override
public void delete(Article article) {
    articleDao.delete(article);
}

数据库dao删除文章
@Override
public void delete(Article article) {
    this.getHibernateTemplate().delete(article);
}

返回到文章列表
<!--文章action-->
<action name="article_*" class="articleAction" method="{1}">
    <result name="list">/WEB-INF/mgr/mgr_main.jsp</result>
    <result name="edit">/WEB-INF/mgr/mgr_edit_article.jsp</result>
    <result name="listres" type="redirectAction">article_pageList.action</result>
    <allowed-methods>list,pageList,delete,getCategory,add,edit,update</allowed-methods>
</action>

添加文章

跳转到添加界面
分类列表框
<div class="item1">
    <span>所属分类:</span>
    <select id="category_select" name="category.parentid" style="width: 150px">&nbsp;&nbsp;
    </select>
    <select id="skill_select" name="category.cid" style="width: 150px">&nbsp;&nbsp;
    </select>
</div>
异步请求获取分类数据
//发送请求获取分类的数据
$.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":0},function (data) {
    console.log(data);
    //遍历
    $(data).each(function (i,obj) {
        console.log(obj.cname);
        $("#category_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
    });
    //触发change
    $("#category_select").trigger("change");
},"json");
服务器接收请求处理
@Setter
private Integer parentid;
public  String getCategory() throws IOException {
    //根据parentid查询分类
    List<Category> list = articleService.getCategory(parentid);
    //把查询的结果转成json
    //以json(数据格式) 响应给页面
    JSONArray jsonArray = JSONArray.fromObject(list, new JsonConfig());
    //响应给页面
    ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");
    ServletActionContext.getResponse().getWriter().println(jsonArray.toString());
    return null;
}
监听分类改变事件
//监听分类select改变
$("#category_select").on("change",function () {
    //获取当前选中的id
    var cid =  $("#category_select").val();

    //发送请求获取分类的数据
    $.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":cid},function (data) {
        console.log(data);
        //遍历
        //清空之前标签
        $("#skill_select").empty();
        $(data).each(function (i,obj) {
            console.log(obj.cname);
            $("#skill_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
        });
    },"json");
});

选择图片
上传图片页面
<div class="item1 update_pic" >
    <span>摘要图片:</span>
    <img src="" id="imageview" class="item1_img" style="display: none;" >
    <label for="fileupload" id="label_file">上传文件</label>
    <input type="file" name="upload" id="fileupload"/>
</div>

/*原理是把本地图片路径:"D(盘符):/image/..."转为"http://..."格式路径来进行显示图片*/
$("#fileupload").change(function() {
    var $file = $(this);
    var objUrl = $file[0].files[0];
    //获得一个http格式的url路径:mozilla(firefox)||webkit or chrome
    var windowURL = window.URL || window.webkitURL;
    //createObjectURL创建一个指向该参数对象(图片)的URL
    var dataURL;
    dataURL = windowURL.createObjectURL(objUrl);
    $("#imageview").attr("src",dataURL);
    console.log($('#imageview').attr('style'));
    if($('#imageview').attr('style') === 'display: none;'){
        $('#imageview').attr('style','inline');
        $('#imageview').width("300px");
        $('#imageview').height("180px");
        $('.update_pic').attr('style', 'margin-bottom: 150px;');
    }
});
上传图片

​ 1.form表单enctype设置
​ multipart/form-data
​ 2.服务器提供属性接收

​ 3.上传文件处理

//添加文章
/**
 * 文件上传提供的三个属性:
 */
@Setter
private String uploadFileName; // 文件名称
@Setter
private File upload; // 上传文件
@Setter
private String uploadContentType; // 文件类型
public String add() throws IOException {

    if(upload != null){
        //上传文件
        //随机生成文件名称
        //1.获取文件扩展名  ssh.jpg
        int index = uploadFileName.lastIndexOf(".");
        String etx = uploadFileName.substring(index);
        //2.随机生成文件名  拼接扩展名
        String uuid = UUID.randomUUID().toString();
        String uuidFileName = uuid.replace("-", "") + etx;
        System.out.println(uuidFileName);

        //确定上传的路径
        String path = ServletActionContext.getServletContext().getRealPath("/upload");
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        //拼接新文件路径
        File desFile = new File(path + "/" + uuidFileName);
        //文件上传
        FileUtils.copyFile(upload,desFile);
        //设置图片
        article.setArticle_pic(uuidFileName);
    }
    //设置当前时间
    article.setArticle_time(new Date().getTime());
    //调用业务层,保存到数据库当中
    articleService.save(article);
    return "listres";
}

集成富文本编辑器

umedit下载地址

添加到页面添加
1.引入js
    <script type="text/javascript" charset="utf-8" src="${ctx }/js/umedit/ueditor.config.js"></script>
    <script type="text/javascript" charset="utf-8" src="${ctx }/js/umedit/ueditor.all.min.js"> </script>
    <script type="text/javascript" charset="utf-8" src="${ctx }/js/umedit/lang/zh-cn/zh-cn.js"></script>
2.在页面当中提供div标签供显示内容
    <div id="editor" name="article_content" style="width:900px;height:400px;"></div>
3.在js当中初始化富文本编辑器
    //初始化富文本编程器
    var ue = UE.getEditor('editor');
    ue.ready(function () {
        ue.execCommand("inserthtml",$("#resContent").val());
    });
富文本编辑器文件上传

​ 1.添加uedit相关jar包

commons-codec-1.9.jar
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
json.jar
ueditor-1.1.2.jar

​ 2.配置过滤器

public class MyFilter extends StrutsPrepareAndExecuteFilter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        //获取当前的请求
        HttpServletRequest request = (HttpServletRequest)req;
        //获取请求地址来进行判断
        String requestURI = request.getRequestURI();
        if(requestURI.contains("js/umedit/jsp/controller.jsp")){
            //放行
            chain.doFilter(req,res);
        }else {
            super.doFilter(req,res,chain);
        }
    }
}

​ 3.json文件(js/umedit/jsp/config.json)配置获取图片路径

"imageUrlPrefix": "http://localhost:8080/", /* 图片访问路径前缀 */
"imagePathFormat": "/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */

发布文章
提交表单参数
<div id="editor" name="article_content" style="width:900px;height:400px;"></div>
$("#send").click(function () {
    //设置文本的描述
    //获取富文本正文
    var text = ue.getContentTxt();
    text = text.substring(0,150)+"...";
    //设置描述
    $("#article_desc").val(text);
    //提交表单
    $("#blog_form").submit();
});
服务器接收参数
//添加文章
/**
 * 文件上传提供的三个属性:
 */
@Setter
private String uploadFileName; // 文件名称
@Setter
private File upload; // 上传文件
@Setter
private String uploadContentType; // 文件类型
public String add() throws IOException {
    if(upload != null){
        //上传文件
        //随机生成文件名称
        //1.获取文件扩展名  ssh.jpg
        int index = uploadFileName.lastIndexOf(".");
        String etx = uploadFileName.substring(index);
        //2.随机生成文件名  拼接扩展名
        String uuid = UUID.randomUUID().toString();
        String uuidFileName = uuid.replace("-", "") + etx;
        //确定上传的路径
        String path = ServletActionContext.getServletContext().getRealPath("/upload");
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        //拼接新文件路径
        File desFile = new File(path + "/" + uuidFileName);
        //文件上传
        FileUtils.copyFile(upload,desFile);
        //设置图片
        article.setArticle_pic(uuidFileName);
    }
    //设置当前时间
    article.setArticle_time(new Date().getTime());
    //调用业务层,保存到数据库当中
    articleService.save(article);
    return "listres";
}

@Override
public void save(Article article) {
    articleDao.save(article);
}
@Override
public void save(Article article) {
    this.getHibernateTemplate().save(article);
}

修改文章
跳转更新界面
请求发送
<li>
    <a href="#"><img class="img_icon" src="../../images/edit_icon.png" alt=""></a>
</li>
接收请求获取当前更新数据,写到值栈当中
public String edit(){
    //从数据库当中获取当前的文章
    Article resarticle = articleService.getOneArticle(article.getArticle_id());
    //把查询的数据存放到值栈
    ActionContext.getContext().getValueStack().push(resarticle);
    //跳转到编辑界面
     return  "edit";
}
显示标题
<span>文章标题:</span>
<input type="text" class="am-form-field" name="article_title" style="width: 300px"
value="<s:property value="article_title"/> "
>
获取分类
<div class="item1">
    <span>所属分类:</span>
    <select id="category_select" name="category.parentid" style="width: 150px">&nbsp;&nbsp;
    </select>
    <select id="skill_select" name="category.cid" style="width: 150px">&nbsp;&nbsp;
    </select>
</div>

默认分类选中

//发送请求获取分类的数据
$.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":0},function (data) {
    console.log(data);
    //遍历
    $(data).each(function (i,obj) {
        console.log(obj.cname);
        $("#category_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
    });
    //设置默认分类
    $("#category_select option[value=<s:property value="category.parentid"/>]").prop("selected",true);
},"json");

var parentid = <s:property value="category.parentid"/>
//发送请求获取分类的数据
$.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":parentid},function (data) {
    //遍历
    //清空之前标签
    $("#skill_select").empty();
    $(data).each(function (i,obj) {
        console.log(obj.cname);
        $("#skill_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
    });
    //设置默认分类
    $("#skill_select option[value=<s:property value="category.cid"/>]").prop("selected",true);
},"json");


//监听分类select改变
$("#category_select").on("change",function () {
    //获取当前选中的id
    var cid =  $("#category_select").val();
    //发送请求获取分类的数据
    $.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":cid},function (data) {
        //遍历
        //清空之前标签
        $("#skill_select").empty();
        $(data).each(function (i,obj) {
            console.log(obj.cname);
            $("#skill_select").append("<option value="+obj.cid+">"+obj.cname+"</option>");
        });
    },"json");
});
图片显示

<div class="item1 update_pic" >
    <span>摘要图片:</span>
    <img src="${ctx}/upload/<s:property value="article_pic"/>" id="imageview" class="item1_img">
    <label for="fileupload" id="label_file">上传文件</label>
    <input type="file" name="upload" id="fileupload"/>
</div>

富文本内容显示
<input type="hidden" id="resContent" value="<s:property value="article_content"/>">
<input type="hidden" name="article_id"  value="<s:property value="article_id"/>">
<input type="hidden" name="article_pic" value="<s:property value="article_pic"/>">
//初始化富文本编程器
var ue = UE.getEditor('editor');
ue.ready(function () {
    ue.execCommand("inserthtml",$("#resContent").val());
});

更新文章
发送提交请求
$("#send").click(function () {
    //设置文本的描述
    //获取富文本正文
    var text = ue.getContentTxt();
    text = text.substring(0,150)+"...";
    //设置描述
    $("#article_desc").val(text);
    //提交表单
    $("#blog_form").submit();
});
<div class="item1">
    <div>
        <span>文章标题:</span>
        <input type="text" class="am-form-field" name="article_title" style="width: 300px">&nbsp;&nbsp;
    </div>
</div>

<input type="text" name="article_desc" id="article_desc" style="display: none;">


<div class="item1">
    <span>所属分类:</span>
    <select id="category_select" name="category.parentid" style="width: 150px">&nbsp;&nbsp;

    </select>

    <select id="skill_select" name="category.cid" style="width: 150px">&nbsp;&nbsp;

    </select>

</div>

<div class="item1 update_pic" >
    <span>摘要图片:</span>
    <img src="" id="imageview" class="item1_img" style="display: none;" >
    <label for="fileupload" id="label_file">上传文件</label>
    <input type="file" name="upload" id="fileupload"/>
</div>

<div id="editor" name="article_content" style="width:900px;height:400px;"></div>
<button class="am-btn am-btn-default" type="button" id="send" style="margin-top: 10px;">
    发布
</button>

接收请求

​ 判断是否更新图片,如果更新图片删除原来的图片

//修改
public String update() throws IOException {
    System.out.println(article);
    //判断有没有新上传的图片
    if(upload != null){
        //确定上传的路径
        String path = ServletActionContext.getServletContext().getRealPath("/upload");
        //获取图片名称
        String picname = article.getArticle_pic();
        //删除原有的图片
        if(picname != null || "".equals(picname)){
            File file = new File(path + picname);
            file.delete();
        }
        //上传文件
        //随机生成文件名称
        //1.获取文件扩展名  ssh.jpg
        int index = uploadFileName.lastIndexOf(".");
        String etx = uploadFileName.substring(index);
        //2.随机生成文件名  拼接扩展名
        String uuid = UUID.randomUUID().toString();
        String uuidFileName = uuid.replace("-", "") + etx;
        File file = new File(path);
        if(!file.exists()){
            file.mkdirs();
        }
        //拼接新文件路径
        File desFile = new File(path + "/" + uuidFileName);
        //文件上传
        FileUtils.copyFile(upload,desFile);
        //设置图片
        article.setArticle_pic(uuidFileName);
    }

    //设置时间
    article.setArticle_time(System.currentTimeMillis());

    //调用业务更新文章
    articleService.update(article);
    return "listres";
}

权限处理

1.把jsp文件放到web/WEB-INF当中

2.创建LocationAction,修改链接跳转

<frameset rows="70,*" frameborder=0 border="0" framespacing="0">
    <frame src="${pageContext.request.contextPath}/location_top.action" name="topFrame" scrolling="NO" noresize>
    <frameset cols="250,*" frameborder="0" border="0"  framespacing="10">
        <frame src="${pageContext.request.contextPath}/location_left.action" name="leftFrame" scrolling="NO">
        <frame src="${pageContext.request.contextPath}/article_pageList.action" name="mainFrame" >
    </frameset>
</frameset>

3.设置拦截器

创建拦截器
public class LoginInterceptor extends MethodFilterInterceptor {
    @Override
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
        //判断用户是否登录
        User user = (User) ServletActionContext.getRequest().getSession().getAttribute("curUser");
        if(user == null){
            //没有登录
            ActionSupport action = (ActionSupport)actionInvocation.getAction();
            action.addActionError("你还没有登录,没有权限访问");
            //跳转login
            return "login";
        }else{
            //对请求的方法来放行
            return actionInvocation.invoke();
        }
    }
}
配置拦截器
<package name="struts" extends="struts-default">
    <interceptors>
        <interceptor name="loginInterceptor" class="com.le.web.LoginInterceptor"></interceptor>
    </interceptors>
    <global-results>
        <result name="login">/mgr_login.jsp</result>
    </global-results>

    <action name="location_*" class="locationAction" method="{1}">
        <result name="left">/WEB-INF/mgr/mgr_left.jsp</result>
        <result name="top">/WEB-INF/mgr/mgr_top.jsp</result>
        <result name="account">/WEB-INF/mgr/mgr_account.jsp</result>
        <result name="add">/WEB-INF/mgr/mgr_add_article.jsp</result>
        <allowed-methods>left,top,account,add</allowed-methods>
    </action>

    <!--loginAciton_login.action-->
    <action name="loginAciton_*" class="loginAction" method="{1}">
        <result name="success">/WEB-INF/mgr/mgr_index.jsp</result>
        <result name="login_out" type="redirect">/mgr_login.jsp</result>
            <interceptor-ref name="loginInterceptor">
                 <param name="excludeMethods">login</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
        <allowed-methods>login,loginout</allowed-methods>
    </action>
</package>

前端处理

前端首面

导航分类加载数据
var parentid = getParams("parentid");

if (parentid != null) {
    //根据parentid加载子级
    $.post("${pageContext.request.contextPath}/article_getCategory.action", {"parentid": parentid}, function (data) {
        console.log(data);
        var html = template('mytpl2', {list: data});
        $("#tab_content").html(html);
    }, "json");
    //in(4,5,6,7)
    //加载数据
    getPageList(1,parentid,null);
} else {
    //加载分页列表
    getPageList(1,null,null);
}

加载全部数据分页展示
发送请求
//加载分类数据
function getPageList(curPage,parentid,cid) {
    $.post("${ctx}/web_getPageList.action", {currPage: curPage,parentid:parentid,cid:cid}, function (data) {
        /*console.log(JSON.parse(data).list);*/
        console.log(data);
        var html = template('mytpl', {list: data.list});
        $("#content").html(html);
        //分页
        $("#page").paging({
            pageNo: data.currentPage,//当前页
            totalPage: data.totalPage,//总页数
            totalSize: data.totalCount,//总记录
            callback: function (num) {
                getPageList(num,parentid,cid);
            }
        });
    });
}

接收请求处理
@Setter
private ArticleService articleService;
/*获取分页数据*/
@Setter
private Integer currPage = 1;
@Setter
private Integer parentid;
@Setter
private Integer cid;
//前端分页
public void getPageList() throws IOException {
    //离线查询条件
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
    if(parentid != null){
        List<Category> categorys = articleService.getCategory(parentid);
        //构建一个数组
        Object[] cidArrays = new Object[categorys.size()];
        for(int i = 0; i< categorys.size(); i++){
            Category category = categorys.get(i);
            cidArrays[i] = category.getCid();
        }
        //设置条件
        detachedCriteria.add(Restrictions.in("category.cid",cidArrays));
    }
    if(cid != null){
        detachedCriteria.add(Restrictions.eq("category.cid",cid));
    }
    //调用业务层进行查询
    PageBean pageBean = articleService.getPageData(detachedCriteria,currPage,5);
    JsonConfig jsonConfig = new JsonConfig();
    //hibernate 延时加载
    jsonConfig.setExcludes(new String[]{"handler", "hibernateLazyInitializer"});
    JSONObject jsonObject = JSONObject.fromObject(pageBean,jsonConfig);
    // 将JSON打印到页面:
    ServletActionContext.getResponse().setContentType("text/json;charset=UTF-8");
    ServletActionContext.getResponse().getWriter().println(jsonObject.toString());
}
JSTemplate
概述

​ template.js是一款JavaScript模板引擎,用来渲染页面的。

引入JSTemplate.js

<script src="${ctx}/js/template.js"></script>
使用方法

​ 定义模板

<script id="mytpl1" type="text/html">
    {{if isAdmin}}
    <p>admin</p>
    {{else if score > 60}}
    <p>mvp</p>
    {{else}}
    <p>error!</p>
    {{/if}}
    {{title}}
    <hr>
    {{each list as value index}}
    <p>{{index}}--{{value}}</p>
    {{/each}}
</script>

​ 设置模板数据

<script id="mytpl1" type="text/html">
    var data = {
        title: '射手',
        isAdmin: false,
        score:61,
        list: ['鲁班', '孙尚香', '黄忠', '马可波罗', '公孙离', '后裔', '咖罗']
    };
</script>

​ 时间戳

//时间戳转换
template.helper('dateFormat', function (date, format){

    date = new Date(date);
    var map = {
        "M": date.getMonth() + 1, //月份 
        "d": date.getDate(), //日 
        "h": date.getHours(), //小时 
        "m": date.getMinutes(), //分 
        "s": date.getSeconds(), //秒 
        "q": Math.floor((date.getMonth() + 3) / 3), //季度 
        "S": date.getMilliseconds() //毫秒 
    };
    format = format.replace(/([yMdhmsqS])+/g, function (all, t) {
        var v = map[t];
        if (v !== undefined) {
            if (all.length > 1) {
                v = '0' + v;
                v = v.substr(v.length - 2);
            }
            return v;
        } else if (t === 'y') {
            return (date.getFullYear() + '').substr(4 - all.length);
        }
        return all;
    });
    return format;
});

展示数据
<%--定义模板--%>
<script id="mytpl" type="text/html">
    {{each list as value}}
    <li class="content_item">
        <div class="blog-list-left" style="float: left;">
            <div class="main-title">
                <a href="detail.jsp?id={{value.article_id}}">{{value.article_title}}</a>
            </div>
            <p class="sub-title">{{value.article_desc}}</p>
            <div class="meta">
                {{value.article_time | dateFormat:'yyyy-MM-dd '}}
            </div>
        </div>
        <img src="${ctx}/upload/{{value.article_pic}}" alt="" class="img-rounded">
    </li>
    {{/each}}
</script>
​ 分页处理
<script>
    //加载分类数据
    function getPageList(curPage,parentid,cid) {
        $.post("${ctx}/web_getPageList.action", {currPage: curPage,parentid:parentid,cid:cid}, function (data) {
            /*console.log(JSON.parse(data).list);*/
            console.log(data);
            var html = template('mytpl', {list: data.list});
            $("#content").html(html);
            //分页
            $("#page").paging({
                pageNo: data.currentPage,//当前页
                totalPage: data.totalPage,//总页数
                totalSize: data.totalCount,//总记录
                callback: function (num) {
                    getPageList(num,parentid,cid);
            }
        });
    });
</script>

​ 加载分类数据
分类点击

//获取分类的数据
//发送请求获取分类的数据
$.post("${pageContext.request.contextPath}/article_getCategory.action",{"parentid":0},function (data) {

    //遍历
    $(data).each(function (i,obj) {
       $("#nav").append("<li class='active'><a href='index.jsp?parentid="+ obj.cid+"'>"+ obj.cname +"</a></li>");
    });

},"json");

​ 前端获取参数方法
//获取当前参数
function getParams(key) {
    var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) {
        return unescape(r[2]);
    }
    return null;
}
获取子分类
var parentid = getParams("parentid");
if (parentid != null) {
    //根据parentid加载子级
    $.post("${pageContext.request.contextPath}/article_getCategory.action", {"parentid": parentid}, function (data) {
        console.log(data);
        var html = template('mytpl2', {list: data});
        $("#tab_content").html(html);
    }, "json");

    //in(4,5,6,7)
    //加载数据
    getPageList(1,parentid,null);

} else {
    //加载分页列表
    getPageList(1,null,null);
}
传参获取数据
@Setter
private ArticleService articleService;
/*获取分页数据*/
@Setter
private Integer currPage = 1;
@Setter
private Integer parentid;
@Setter
private Integer cid;
//前端分页
public void getPageList() throws IOException {
    //离线查询条件
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Article.class);
    if(parentid != null){
        List<Category> categorys = articleService.getCategory(parentid);
        //构建一个数组
        Object[] cidArrays = new Object[categorys.size()];
        for(int i = 0; i< categorys.size(); i++){
            Category category = categorys.get(i);
            cidArrays[i] = category.getCid();
        }
        //设置条件
        System.out.println(Arrays.toString(cidArrays));
        detachedCriteria.add(Restrictions.in("category.cid",cidArrays));
    }

    if(cid != null){
        detachedCriteria.add(Restrictions.eq("category.cid",cid));
    }

    //调用业务层进行查询
    PageBean pageBean = articleService.getPageData(detachedCriteria,currPage,5);
    JsonConfig jsonConfig = new JsonConfig();
    //hibernate 延时加载
    jsonConfig.setExcludes(new String[]{"handler", "hibernateLazyInitializer"});
    JSONObject jsonObject = JSONObject.fromObject(pageBean,jsonConfig);
    // 将JSON打印到页面:
    ServletActionContext.getResponse().setContentType("text/json;charset=UTF-8");
    ServletActionContext.getResponse().getWriter().println(jsonObject.toString());

}

​ 加载子分类列表

//如果标签是动态加载的,就不能使用这种方式注册事件
/*$(".categroy_btn").click(function () {
    alert("111");
});*/

$("body").on("click",".categroy_btn",function () {
    //获取当前点击的cid
    var cid = $(this).data("cid");
    alert(cid);
    getPageList(1,null,cid);
});

//加载分类数据
function getPageList(curPage,parentid,cid) {
    $.post("${ctx}/web_getPageList.action", {currPage: curPage,parentid:parentid,cid:cid}, function (data) {
        console.log(data);
        var html = template('mytpl', {list: data.list});
        $("#content").html(html);
        //分页
        $("#page").paging({
            pageNo: data.currentPage,//当前页
            totalPage: data.totalPage,//总页数
            totalSize: data.totalCount,//总记录
            callback: function (num) {
                getPageList(num,parentid,cid);
            }
        });
    });
}

​ 前端详情页

点击列表传递id
<%--定义模板--%>
<script id="mytpl" type="text/html">
    {{each list as value}}
    <li class="content_item">
        <div class="blog-list-left" style="float: left;">
            <div class="main-title">
                <a href="detail.jsp?id={{value.article_id}}">{{value.article_title}}</a>
            </div>
            <p class="sub-title">{{value.article_desc}}</p>
            <div class="meta">
                {{value.article_time | dateFormat:'yyyy-MM-dd '}}
            </div>
        </div>
        <img src="${ctx}/upload/{{value.article_pic}}" alt="" class="img-rounded">
    </li>
    {{/each}}
</script>
​ 获取参数加载相应数据

<script>
    //获取当前参数
    function getParams(key) {
        var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) {
            return unescape(r[2]);
        }
        return null;
    }
    //获取参数
    var id = getParams("id");

    //请求数据
    $.post("${pageContext.request.contextPath}/web_getDetail.action",{id:id},function (data) {
            console.log(data);
            $("#title").html(data.article_title);
            $("#content").html(data.article_content);
            $("#data-time").html(new Date(data.article_time).toLocaleDateString());
    });
</script>

​ 服务器处理
//根据id获取指定的文章
@Setter
private Integer id;
public void getDetail() throws IOException {
    Article oneArticle = articleService.getOneArticle(id);
    JsonConfig jsonConfig = new JsonConfig();
    //hibernate 延时加载
    jsonConfig.setExcludes(new String[]{"handler", "hibernateLazyInitializer"});
    JSONObject jsonObject = JSONObject.fromObject(oneArticle,jsonConfig);
    // 将JSON打印到页面:
    ServletActionContext.getResponse().setContentType("text/json;charset=UTF-8");
    ServletActionContext.getResponse().getWriter().println(jsonObject.toString());
}
​ 详细页显示
<article class="mainarea" style="display:block;">
    <div class="blog-tab">
        <div class="tab-content" >
            <div role="tabpanel" style="margin-left: 100px;" class="tab-pane fade in active" id="home">
                <div id="lk_blog_list" style="padding-left: 20px; width: 1000px" class="container">
                    <div class="row">
                        <ul class="blog-list">
                            <li>
                                <div class="blog-list-left">
                                    <div class="main-title" id="title"></div>
                                    <div style="color: #c2c2c2" id="data-time">2019-1-1</div>
                                    <hr>
                                    <div id="content"></div>
                                </div>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</article>

转载于:https://www.cnblogs.com/mumuyinxin/p/10871168.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值