struts2 实现简单BBS功能

以下是马老师教学内容。工程目标:做BBS后台管理中,对帖子目录的管理,包括添加,更新,删除,列帖子的4个功能,可以发现哈,这也数据库的增删改查是正好对应的,所以实现起来其实很简单。首先确定开发流程:

  1. 建立前台界面,用ext实现(此为官方建议流程,但我觉得1跟2可以换过来)
  2. 创建struts.xml文件-----内容包括确定namespace,package,action,result各自名称,以便较好的使用通配符,可以基本完成通路,包括前台+struts的框架运行,所有action ,jsp都依照计划可以走通。内部也有流程哈:1)写个上篇博客一样简单的框架,jsp,struts.xml,action,web.xml这些东西           2)复杂化struts.xml文件   3)完成复杂strtus.xml文件包含的action ,jsp 内容,方法都为空的,只是为了走通路;    4) 加上上面的ext前台,一起运行,走通category-list一条路  5) 由jsp的页面链接走通其他的路:category-add,category-update,category-delete。页面返回的内容也都是想test返回的页面一样,为一句话即可。
  3. 建Model层
  4. 建立DB层
  5. 建立Service层
  6. 与action连起来,将基本为空的方法用service实现,慢慢跑通即可。

具体操作:

  • ext页面为借鉴的别人的,这就不说了,工程中要添加ext的包,不然这个页面运行不起来
  • struts的搭建: 在上一个博客那边说啦简单的框架的搭建,这边也是一样,只是在其基础上添加写东西,一下为struts.xml文件内容,文件头部分的东西就省了:

<struts>
 <constant name="struts-devMode" value="true"></constant>//还是前面的那个简单工程的东西哈
<package name="front" namespace="/" extends="struts-default">
<action name="test" class="com.gao.action.TestAction">
<result>/test.jsp</result>
  </action></package>
 <package name="admin" namespace="/admin" extends="struts-default">//admin表示后台,此处action用了通配符哦,这个用着还挺爽的,第一个※为action名字,第二个为action中对应方法的名字,这个action name返回后,对应的result为action的名字,加上“-”再加上方法的页面,话说,coding中约定大于配置,所以,jsp的约定其实就是鼎城这样的,配置起来就相当简单了!
<action name="*-*" class="com.gao.action.{1}Action" method="{2}">
  <result>/admin/{1}-{2}.jsp</result>//返回的页面
  <result name="input">/admin/{1}-{2}.jsp</result>//有input返回的界面,此处为addInput,updateInput对应返回的界面,界面实现用户对帖子的增加,或者更新,最后以form的形式提交Category-add,Category-update两个action 做处理,再返回到上一个result。其实这两个可以合并,但是为了更清晰,所以就没有合并。
  </action></package></struts>

  • 对应struts.xml文件,实现action 和jsp页面
  1. action的实现:新建CategoryAction文件,其中包括list,update,add,delete,updateInput,addInput 6个空方法,returnSUCCESS,最后两个return INPUT即可。
  2. jsp 实现:新建6个jsp 文件,分别为Category-list,Category-add, Category-delete,Category-update,Category-addInput,Category-updateInput 6个文件,分别对应action中的6个方法的返回,页面内容可以只为个子的页面名称;注意连接关系,其中add,delete,update都是连接在list页面上的,不过,这是最简单的版本,所以不加也没问题。
  3. 跑通下。

基于以上内容,加上ext前台界面,跑通下!

  • 建立Model

Category类,其中包括int id,String name,String description及其set,get方法,此处若不写category的空构造方法也没事,对这个问题,有点迷糊,不知道什么时候要写,什么时候可以不写;

  • 建立DB

跟上卖弄一样简单。SQL语句如下“

create database bbs;

use bbs;

create table _category (id int primary key auto_increment,name varchar(50),description varchar(200));

即可。

  • 建Service

这个相对复杂点,在建这个之前,要建个DB的辅助类:DB类,其中包括的方法有:createConn(),prepare(),close().主要是跟DB打交道,并且吧try,catch这些东西都包括进来了,比较方便;贴出代码开看看,close就不写上来了,这里有rs,ps,conn的3个close:

public static Connection createConn() {//通常为static ,不然其他类不好调用;
Connection conn = null;
  try {Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost/bbs2009","root", "gao");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}

public static PreparedStatement prepare(Connection conn, String sql) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return ps;
}

然后实现Service类了。方法有:list,add,update,delete,调用DB类中的方法实现,不难,现在用的方法是,画个图出来,按照图直接写代码,不然脑袋真是记不住啊。。。

这里还有个就是,有delete,deleteById(id)两个方法,实现了两种方式,最好的方式是delete调用deleteById,属于service 提供了更好的接口给别人,如果别人要用你这个包得话,可基于SERVICE这个方法做二次开发。还有一个loadById(id)使用在updateInput中的,为了在更新的时候把原来的内容由ID取出来,放在输入框中,起提示作用;

其实最主要的就是SQL语句,DB类方法的使用,写过一遍以后就会觉得还挺简单的,因为都是一层不变的东西,会了这个类似的你就都会了,代码如下:

package com.gao.service;//放在service包下了

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.gao.model.Category;//模型包
import com.gao.util.DB;//DB辅助类包
public class CategoryService {


 public void add(Category c) {  //add方法
Connection conn = DB.createConn();
String sql = "insert into _category values(null, ?, ?)";
PreparedStatement ps = DB.prepare(conn, sql);

try {
ps.setString(1, c.getName());
ps.setString(2, c.getDescription());
ps.executeUpdate();

} catch (SQLException e) {
e.printStackTrace();
}
DB.close(ps);
DB.close(conn);

}

public void update(Category c) {
Connection conn = DB.createConn();
String sql = "update _category set name=?,description=? where id=?";
PreparedStatement ps = DB.prepare(conn, sql);

try {
ps.setString(1, c.getName());
ps.setString(2, c.getDescription());
ps.setInt(3, c.getId());

ps.executeUpdate();

} catch (SQLException e) {
e.printStackTrace();
}
DB.close(conn);
DB.close(ps);

}

public void delete(Category c) {
deleteById(c.getId());
}

public void deleteById(int id) {
Connection conn = DB.createConn();
String sql = "delete from _category where id=?";
PreparedStatement ps = DB.prepare(conn, sql);
try {
ps.setInt(1, id);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(ps);
DB.close(conn);
}

public List<Category> list() {
List<Category> categories = new ArrayList<Category>();
Category c = null;
Connection conn = DB.createConn();
String sql = "select * from _category";
PreparedStatement ps = DB.prepare(conn, sql);

ResultSet rs;
try {
rs = ps.executeQuery();
while (rs.next()) {
c = new Category();
c.setId(rs.getInt("id"));
c.setName(rs.getString("name"));
c.setDescription(rs.getString("description"));
categories.add(c);
}
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(ps);
DB.close(conn);

return categories;
}

public Category loadById(int id) {
Connection conn = DB.createConn();
Category c = null;
String sql = "select * from _category where id=?";
PreparedStatement ps = DB.prepare(conn, sql);
ResultSet rs = null;
try {
ps.setInt(1, id);
rs = ps.executeQuery();
while (rs.next()) {
c = new Category();
c.setId(id);
c.setName(rs.getString("name"));
c.setDescription(rs.getString("description"));
}
} catch (SQLException e) {
e.printStackTrace();
}
DB.close(rs);
DB.close(ps);
DB.close(conn);
return c;
 }}

好了,以上那个这个工作中最麻烦的工作了,记住了就万事大吉了,后面开始写action的具体方法,代码如下:

package com.gao.action;//放在action包中
import java.util.List;
import com.gao.model.Category;//model层
import com.gao.service.CategoryService;//service层
import com.opensymphony.xwork2.ActionSupport;

public class CategoryAction extends ActionSupport {//继承要记得写
 private Category category;     //定义的变量
private int id;
private List<Category> categories;
 private CategoryService categoryService = new CategoryService();//service的对象,此处定义并初始化了便可以直接调用了!
 public String add() {//add方法,只需直接调用service的方法即可,相当方便!
categoryService.add(category);
return SUCCESS;
}

 public String update() {//update方法,实现更新数据库中用户输入的内容。
categoryService.update(category);
return SUCCESS;
}

public String list() {//列出_category表中所有的内容
categories = categoryService.list();
return SUCCESS;
}

public String delete() {//注意哦,调用的是deleteById哟,因为ID也是此action的一个变量,所以可以这样,不然要写车category.id才行
categoryService.deleteById(id);
return SUCCESS;
}

 public String addInput() {//此处为空,直接返回INPUT,返回到category-addInput 界面,等用户输入结束后,再调用此action中的add方法,进行添加处理,最后返回catogory-add页面;
return INPUT;
}

public String updateInput() {//此处本来也应该为空的,但是要为category-updateInput界面提供提示,所以要做个查表的函数,将结果返回给用户;
this.category = this.categoryService.loadById(id);
return INPUT;
}

按照此aciton 的内容,将jsp的内容也都换成真的,比如category-list 中将update,delete都放在每个项目的后面,进行操作,贴出具体内容:

category-list.jsp内容:

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
  + path + "/";%> //这是新建jsp页面都会有的内容,主要是完成basepath的初始化,后面输入连接地址时,直接输本工程下的相对路径即可;
<%@taglib uri="/struts-tags" prefix="s"%>//此举为struts的标签,若不加,s:property就不可用。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><base href="<%=basePath%>">//使用!
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
  <!--<link rel="stylesheet" type="text/css" href="styles.css">-->
 </head>
<body>
  category list
<a href="admin/Category-addInput">添加categroy</a>//添加功能,注意,此处连到Category-addInput的action哦!所以会返回到category-addInput页面哦!
<br /><hr />
<s:iterator value="categories" var="c">//struts中做遍历的方式
<s:property value="#c.name" /> |//取name的值
<s:property value="#c.description" /> |//取description的值
 <a href="admin/Category-delete?id=<s:property value="#c.id"/>">删除Category</a> |//添加删除,传值id
<a href="admin/Category-updateInput?id=<s:property value="#c.id"/>">更新Category</a>//添加更新,传值id
<br />
</s:iterator>
<s:debug></s:debug>//调试标签,可查看值栈中内容
<br>
 </body></html>

category-addInput 内容:

<body>
<form action="admin/Category-add" method="post">//转到category-add的action;
category name:
<input type="text" name="category.name">//传参
category description:
<textarea name="category.description"></textarea>
<input type="submit" value="add">
<hr />
<br>
  </form> </body>

category-updateInput内容:

<body>
<form action="admin/Category-update" method="post"> //目的地,category-update 
  <input type="hidden" name="category.id"  //有ID的传值哦
  value="<s:property value="category.id"/>" /> //初始内容为查表所得,之后用户更改,然后跟ID,DESCRIPTION 一起传给category-update的action
  name:<input name="category.name"
value="<s:property value="category.name"/>" />
  descritpion<textarea name="category.description">
<s:property value="category.description" />
</textarea>
<input type="submit" value="update" />
  </form></body>

剩下的delete,add就非常简单,直接写的OK,或成功这种。

以上这些,都跑通一下就可以了!


这个比上一个是要复杂点,但对逻辑要求不是特别强,也有哈,在action ,jsp,action,jsp绕的那个地方,其他的都是基础,尤其是DB辅助类那,service那个类也是要记住的基础!还是那个方法哈,写方法之前,可以尝试着先画个流程图,然后用代码实现,这样效果会好很多!

好,这个就到这~~(这个博客好像不提供附件上传呢,还是我级别不够不让我传?!)

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值