Struts2开发-------------BBS

MVC开发模式

MVC模式是经典的Java开发模式。处理基于“请求-响应”模式的程序中的各种问题。

数据模型(model),视图(view,jsp),控制器(control,Action控制)

Strust2框架搭建

首先向项目中添加struts2的jar包,从struts2的安装路径下找一个示例程序,把web_info下lib包的jar工具拷贝过来,如下是我们所需要的:也把struts.xml和web.xml配置文件拷贝过来,便于参考

(一)构建数据库

sql 语句,或者使用mysql图形化工具Navicat操作,并且在项目下创建sql文件夹,添加mysql文件,记录项目中用到的sql语句,便于查看

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

顺便导入mysql的驱动jar包,build path

(二)建立model层

medel层与数据库表相对应,所以在model包下建立Category类,相对应表的字段信息,建立对应的属性以及set get 方法

package xidian.lili.bbs.model;

public class Category {
	private int id;
	private String name;
	private String description;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	
}

(三)建立service 层

首先建立DB的util包,把连接数据库创建statement,关闭连接放入utils包,方便使用

package xidian.lili.bbs.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DB {
	public static Connection getConn(){
		Connection con=null;
		try {
			Class.forName("com.mysql.jdbc.Driver");		
			con=DriverManager.getConnection("jdbc:mysql://localhost/bbs2009","root","123456");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return con;		
	}
	public static PreparedStatement getStatement(Connection con,String sql){
		PreparedStatement ps=null;
		try {
			ps= con.prepareStatement(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return ps;
	}
	public static void close(Connection con){
		if(con!=null);
		try {
			con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	public static void close(PreparedStatement ps){
		if(ps!=null);
		try {
			ps.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	public static void close(ResultSet rs){
		if(rs!=null);
		try {
			rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

涉及的service主要有增删改查

package xidian.lili.bbs.sercive;

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 xidian.lili.bbs.model.Category;
import xidian.lili.bbs.utils.DB;

public class CategoryService {
	//增加
	public void add(Category c){
		Connection con=DB.getConn();
		String sql="insert into _category value(null,?,?);";
		PreparedStatement ps=DB.getStatement(con, sql);
		try {
			ps.setString(1,c.getName());
			ps.setString(2,c.getDescription());
			ps.executeUpdate();
		} catch (SQLException e) {	
			e.printStackTrace();
		}
		DB.close(ps);
		DB.close(con);
	}
	//删除
	public void delete(Category c){
		this.delete(c.getId());
	}
	public void delete(int id){
		Connection con=DB.getConn();
		String sql="delete from _category where id=?";
		PreparedStatement ps=DB.getStatement(con, sql);
		try {
			ps.setInt(0, id);
			ps.executeUpdate();
		} catch (SQLException e) {	
			e.printStackTrace();
		}
		DB.close(ps);
		DB.close(con);
	}
	//更新
	public void update(Category c){
		Connection con=DB.getConn();
		String sql="update _category set name=?,description=? where id=?;";
		PreparedStatement ps=DB.getStatement(con, 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(ps);
		DB.close(con);		
	}
	//查询
	public List<Category> list(){
		Connection con=DB.getConn();
		String sql="select * form _category;";
		List<Category> list=new ArrayList();
		ResultSet rs=null;
		PreparedStatement ps=DB.getStatement(con, sql);
		Category c=null;
		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"));
				list.add(c);
			}
		} catch (SQLException e) {	
			e.printStackTrace();
		}
		DB.close(rs);
		DB.close(ps);
		DB.close(con);	
		return list;
	}
}

至此后台的代码就开发完了,我们需要把前台的框架准备好

(四)建立界面原型

使用Ext js完成界面部分,将解压以后的ext下的adapter,resources以及ext-all.js,ext-lang-zh_CN.js拷贝到WebRoot下的admin文件夹,我们把后台要显示的界面都放到admin中

完成自己的界面采用直接使用解压以后的ext的ext-3.0.0/examples/layout/accordion.html的界面html进行修改

界面index.html,

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=GB18030" />
		<title>西电BBS2018论坛管理平台</title>
		<link rel="stylesheet" type="text/css"
			href="ext/resources/css/ext-all.css" />
		<!-- GC -->
		<!-- LIBS -->
		<script type="text/javascript" src="ext/adapter/ext/ext-base.js">
	
</script>
		<!-- ENDLIBS -->
		<script type="text/javascript" src="ext/ext-all.js">
	
</script>

		<script type="text/javascript" src="ext/ext-lang-zh_CN.js">
	
</script>
		<style type="text/css">
html,body {
	font: normal 12px verdana;
	margin: 0;
	padding: 0;
	border: 0 none;
	overflow: hidden;
	height: 100%;
}

.empty .x-panel-body {
	padding-top: 0;
	text-align: center;
	font-style: italic;
	color: gray;
	font-size: 11px;
}

.x-btn button {
	font-size: 14px;
}

.x-panel-header {
	font-size: 14px;
}
</style>
<script type="text/javascript">
	Ext.onReady( function() {
		//页面一加载从这个函数开始执行
		var addPanel = function(btn, event) {
			var n;
			n = tabPanel.getComponent(btn.id);
			if(n) {
				tabPanel.setActiveTab(n);
				return;
			}
			n = tabPanel.add( {
				id : btn.id,
				title : btn.id,
				html : '<iframe width=100% height=100% src=' + btn.id + ' />',
				//autoLoad : '',
				closable : 'true'
			});
			tabPanel.setActiveTab(n);
		}

		var item1 = new Ext.Panel( {
			title : 'Category管理',
			//html : '&lt;empty panel&gt;',
			cls : 'empty',
			items : [ 
				new Ext.Button({
					id : 'Category_list',
					text : 'Category列表',
					width : '100%',
					listeners : {
						click : addPanel
					}
				}),
				new Ext.Button({
					id : 'Settings',
					text : '设置',
					width : '100%',
					listeners : {
						click : addPanel
					}
				})
				]
		});
		var item2 = new Ext.Panel( {
			title : 'Contacts',
			html : '&lt;empty panel&gt;',
			cls : 'empty',
			items : [ 
				new Ext.Button({
					id : 'New Friend',
					text : '新朋友',
					width : '100%',
					listeners : {
						click : addPanel
					}
				}),
				new Ext.Button({
					id : 'Group Chat',
					text : '群聊',
					width : '100%',
					listeners : {
						click : addPanel
					}
				})
				]
		});
		var item3 = new Ext.Panel( {
			title : 'Discover',
			html : '&lt;empty panel&gt;',
			cls : 'empty'
		});

		var item4 = new Ext.Panel( {
			title : 'Accordion Item 4',
			html : '&lt;empty panel&gt;',
			cls : 'empty'
		});

		var item5 = new Ext.Panel( {
			title : 'Accordion Item 5',
			html : '&lt;empty panel&gt;',
			cls : 'empty'
		});

		var accordion = new Ext.Panel( {
			region : 'west',
			margins : '5 0 5 5',
			split : true,
			width : 210,
			layout : 'accordion',
			items : [ item1, item2, item3, item4, item5 ]
		});

		var tabPanel = new Ext.TabPanel( {
			region : 'center',
			enableTabScroll : true,
			deferredRender : false,
			activeTab : 0,
			items : [ {
				title : 'index',

				//html : 'aaaaaa'
				autoLoad : 'Category_list'
			} ]
		});

		var viewport = new Ext.Viewport( {
			layout : 'border',
			items : [ accordion, tabPanel ]
		});
});
</script>
	</head>
	<body>
		
		<!-- EXAMPLES -->
	</body>
</html>

 整个界面是一个viewport,分成两块,左面是参考ext examples中的accordion块,右边是加入的tabPanel

var viewport = new Ext.Viewport( {
            layout : 'border',
            items : [ accordion, tabPanel ]
        });

定义tabPanel块,主要是  autoLoad 参数,可以在panel上显示对应的jsp文件

var tabPanel = new Ext.TabPanel( {
            region : 'center',
            enableTabScroll : true,
            deferredRender : false,
            activeTab : 0,
            items : [ {
                title : 'index',
                autoLoad : 'Category_list'
            } ]
        });

定义accordion块,west位置在左边,然后加入5个items

var accordion = new Ext.Panel( {
            region : 'west',
            margins : '5 0 5 5',
            split : true,
            width : 210,
            layout : 'accordion',
            items : [ item1, item2, item3, item4, item5 ]
        });

分别定义5个items,以第一个为例说明,每一个items是一个Panel,给里面加入button,每个button都有对应的id,并在button的click事件中添加监听器,就是放点击该button时,执行addPanel函数

var item1 = new Ext.Panel( {
            title : 'Category管理',
            //html : '&lt;empty panel&gt;',
            cls : 'empty',
            items : [ 
                new Ext.Button({
                    id : 'Category_list',
                    text : 'Category列表',
                    width : '100%',
                    listeners : {
                        click : addPanel
                    }
                }),
                new Ext.Button({
                    id : 'Settings',
                    text : '设置',
                    width : '100%',
                    listeners : {
                        click : addPanel
                    }
                })
                ]
        });

解析addPanel函数,获取tabPanel的事件,根据button的id判断,若tabPanel已经有该button说明在tabPanel中打开了button对应的页面,此时active激活,若是没有该button对应的id,在tabPanel新建一个Component,并激活

var addPanel = function(btn, event) {
            var n;
            n = tabPanel.getComponent(btn.id);
            if(n) {
                tabPanel.setActiveTab(n);
                return;
            }
            n = tabPanel.add( {
                id : btn.id,
                title : btn.id,
                html : '<iframe width=100% height=100% src=' + btn.id + ' />',
                //autoLoad : '',
                closable : 'true'
            });
            tabPanel.setActiveTab(n);
        }
结果

(五)struts.xml文件配置及Action类实现

首先配置完成Action类,要实现的功能有增删改查,规定对应的Action名字,做出相应的返回

对于增加  Action name  Category_add name对应对应的action method 为add 对应的jsp文件定义为Category_add.jsp

这样定义我们在struts.xml文件中可以使用通配符

将前台和后天在Action类中联系起来

当前台有Category_add的action时,执行method为add,就是执行CategoryAction类中的add()方法,这个时候先执行后天service中的增加方法,这样就把前台和后台联系起来了

package xidian.lili.bbs.action;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

import xidian.lili.bbs.model.Category;
import xidian.lili.bbs.sercive.CategoryService;

public class CategoryAction extends ActionSupport{
	private CategoryService categoryservice=new CategoryService();
	private Category c;
	private List<Category> categories;
	private int id;
	
	public String add(){
		categoryservice.add(c);
		return SUCCESS;
	}
	public String delete(){
		categoryservice.deletebyId(id);
		return SUCCESS;
	}
	public String update(){
		categoryservice.update(c);
		return SUCCESS;
	}	
	public String list(){
		categories=categoryservice.list();
		return SUCCESS;
	}
	public String addinput(){
		return INPUT;
	}
	public String updateinput(){
		this.c=this.categoryservice.loadById(id);
		return INPUT;
	}
	public CategoryService getCategoryservice() {
		return categoryservice;
	}
	public void setCategoryservice(CategoryService categoryservice) {
		this.categoryservice = categoryservice;
	}
	public Category getC() {
		return c;
	}
	public void setC(Category c) {
		this.c = c;
	}
	public List<Category> getCategories() {
		return categories;
	}
	public void setCategories(List<Category> categories) {
		categories = categories;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
}

 struts.xml配置文件:

	<package name="front" namespace="/" extends="struts-default">
		<default-action-ref name="Category_list" />
		<action name="Category_list" class="xidian.lili.bbs.action.CategoryAction" method="list">
			<result>/index.jsp</result>
		</action>
	</package> 
	<package name="admin" namespace="/admin" extends="struts-default">
		<action name="*_*"   class="xidian.lili.bbs.action.{1}Action" method="{2}">
			<result>/admin/{1}_{2}.jsp</result>
			<result name="input">//admin/{1}_{2}.jsp</result>
		</action>
	</package> 

我们在前面的界面中,让TabPanel对应的Action是Category_list.,这就是TabPanel,执行CategoryAction中的list()函数查找,我们把前台增删改的action都放在这个jsp文件中

  <body>
Category_list
<a href="admin/Category_addinput">添加用户</a>
<hr/>
<s:iterator value="categories" var="c">
	<s:property value="#c.name"/>|
	<s:property value="#c.description"/>|
<a href="admin/Category_delete?id=<s:property value="#c.id"/>">删除用户</a>
<a href="admin/Category_updateinput?id=<s:property value="#c.id"/>">更新用户</a>
<br/>
</s:iterator>
<s:debug></s:debug>

  </body>

 

添加

当你想添加一个category,应该要输入值,所以我们执行Category_addinput的Action,转到Category_addinput.jsp,输入数据,然后提交到Category_add的Action,这里使用domin model进行参数接收,读取到输入的name和description,这个时候CategoryAction的model变量c就有了值,然后执行方法add(),完成数据添加

  <body>
add input
<form action="admin/Category_add" method="post">
name<input name="c.name" />
description<textarea name="c.description" ></textarea>
<input type="submit" value="add" />
</form>
  </body>

 

 查询

执行了Action类中的list(),Action类中的局部变量categories就有了内容,我们用struts标签来遍历这个list,并通过OGNL表达式进行读取数据,这里使用var,存放到ActionContext中,用#加的方式读取

<s:iterator value="categories" var="c">
    <s:property value="#c.name"/>|
    <s:property value="#c.description"/>|
<a href="admin/Category_delete?id=<s:property value="#c.id"/>">删除用户</a>
<a href="admin/Category_updateinput?id=<s:property value="#c.id"/>">更新用户</a>
<br/>
</s:iterator>

删除

用?+参数名接收参数,取到当前遍历到的对象的id传递给delete action,进行操作

更新

用跟删除同样的方法接收要更新的id,传递给updateinput的action(同addinput),然后根据id得到要更新的Category,然后交给Category_update的Action,但是要在updateinput的时候做下面的事情:

 <body>
update input
<form action="admin/Category_update" method="post">
<input type="hidden" name="c.id" value="<s:property value="c.id"/>"  />
name<input name="c.name" value="<s:property value="c.name"/>"/>
description<textarea name="c.description" ><s:property value="c.description"/></textarea>
<input type="submit" value="update" />

所以这里要在service中增加方法

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

然后再action的updateinput中执行该方法

这样就完成了一个前后台连接的增删改查 

猜你喜欢

转载自blog.csdn.net/wangdongli_1993/article/details/81127295