ajax+struts基础知识02
两种不同的框架
struts 1.X
struts 2.X webwork
struts1:并没有对ajax的支持(因为struts1流行的时候并没有太多的异步处理请求)
由于struts1主要是通过action来进行对页面的转发和重定向的
而ajax是通过js请求发送给服务器的。
比如validate.action请求到ActionServlet之后,经过Action的处理在这里返回的是null而非success和fail
如果返回null的话,则不将其进行转发或者重定向了,可以在action用其他代码来完成工作
由于action里面包含request和response;也没有必要往request里面去存放数据
一、加载Struts1.2的变化
通过MyEclipse加载struts1.2的变化
1、将antlr.jar,commons-benutils.jar,commons-digester.jar,commons-fileupload.jar,commons-logging.jar
commons-validator.jar,jakarta-oro.jar,struts.jar复制到了/WEB-INF/lib目录下
2、在/WEB-INF目录下放置了几个文件:
//一个TLD就是一个标记库定义文件
struts-bean.tld
struts-config.xml//struts提供的配置文件
struts-html.tld
struts-logic.tld
struts-nested.tld
struts-tiles.tld
validator-rules.xml
3、修改了web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name />
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
4、在src目录下创建了一个ApplicationResources.properties文件并在struts-config.xml文件中添加
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans></form-beans>
<global-exceptions />
<global-forwards />
<action-mappings><action-mappings>
<message-resources parameter="ApplicationResources" />
</struts-config>
一个功能一个action
5、创建一个测试Action;验证加载struts是否成功;
假设我们这里先创建一个TestAction
package org.whatisjava.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class TestAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//在这里传递进四个参数,其中ActionMapping,ActionForm,request,response
//ActionMapping是配置对象,一个ActionMapping封装一个action对象的信息
//返回值为ActionForward,struts2中的返回值为String
//一个ActionForward就是封装了一个将要返回的地址
System.out.println("access db......");
//return new ActionForward("/WEB-INF/jsp/test.jsp");
//return "success";
return mapping.findForward("success");//mapping里面可以找到forward
//这种方式与struts2里面的区别在于:这种方式一起把配置文件中的相关信息都暴露给程序员了
//封装性较差
}
}
6、修改struts-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<data-sources />
<form-beans />
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/test" type="org.whatisjava.action.TestAction">
<forward name="success" path="/WEB-INF/jsp/test.jsp"/>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources" />
</struts-config>
二、如何设计一个框架页面:
框架页面index.jsp页面
header.jsp顶部
menu.jsp左下
main.jsp右下
1、index.jsp页面
<%@page pageEncoding="utf-8" %>
<BODY style="MARGIN: 0px">
<DIV
style="Z-INDEX: 2; LEFT: 0px; WIDTH: 100%; POSITION: absolute; TOP: 0px; HEIGHT: 65px">
<IFRAME id="header"
style="Z-INDEX: 1; VISIBILITY: inherit; WIDTH: 100%; HEIGHT: 65px"
name=header src="header.do" frameBorder=0 scrolling=no></IFRAME>
</DIV>
<TABLE style="TABLE-LAYOUT: fixed" height="100%" cellSpacing=0
cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=165 height=65></TD>
<TD></TD>
</TR>
<TR>
<TD>
<IFRAME id="menu"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=menu src="menu.do" frameBorder=0 scrolling=yes></IFRAME>
</TD>
<TD>
<IFRAME id="main"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=main src="main.jsp" frameBorder=0 scrolling=yes></IFRAME>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
这个页面是有3 个<iframe></iframe>构成的。如下:
<IFRAME id="header"
style="Z-INDEX: 1; VISIBILITY: inherit; WIDTH: 100%; HEIGHT: 65px"
name=header src="header.do" frameBorder=0 scrolling=no>
</IFRAME>
<IFRAME id="menu"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=menu src="menu.do" frameBorder=0 scrolling=yes>
</IFRAME>
<IFRAME id="main"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=main src="main.jsp" frameBorder=0 scrolling=yes>
</IFRAME>
<iframe id="" style="" name=header src="">
假设存在一个iframe的话,首先要加载框架,然后再发一个请求去接收iframe src的信息
也就是对于上面index.jsp框架页面来说,至少有4个请求。
<iframe>类似于<img src="">
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/style.css"
/////
////<%=request.getContextPath()%>,响应绝对地址
///
type=text/css rel=stylesheet />
</head>
<body topMargin="10">
<div id="append_parent"></div>
<img src="images/1.jpg" width="760" height="530">
</body>
</html>
2、对应的<struts-config>修改
<data-sources />
<form-beans />
<global-exceptions />
<global-forwards />
<action-mappings>
<action path="/Test" type="org.whatisjava.action.TestAction">
<forward name="success" path="/WEB-INF/jsp/Test.jsp"></forward>
</action>
<action path="/menu" type="org.apache.struts.actions.ForwardAction"
parameter="/WEB-INF/jsp/menu.jsp"/>
//这句话意思,真实版本struts的ForwardAction,什么也不做,直接将其转到parameter指定的定制
//切记这里forward可能不行,需要采用parameter来指定转发路径
//切记切记。
</action-mappings>
<message-resources parameter="org.whatisjava.struts.ApplicationResources" />
</struts-config>
3、header.jsp
//togglemenu以及sethighlight函数
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/main/style.css"
type=text/css rel=stylesheet />
<script type="text/javascript">
var menus = new Array('g1','g2');
//全局变量;字符串数组
function togglemenu(id) {
for (i = 0; i < menus.length; i++) {
var k = menus[i];
parent.menu.document.getElementById(k).style.display = (k == id ? '' : 'none');
//任何一个div,getElementById("abc").style.display
//parent在这里代表index.jsp框架页面;menu代表的是menu.jsp的id
}
}
function sethighlight(n) {
//document.getElementById('');
var lis = document.getElementsByTagName('li');
//获得页面中标签为li的标记对象
// obj.getElementsByTagName
for(var i = 0; i < lis.length; i++) {
lis[i].id = '';
}
lis[n].id = 'menuon';
}
</script>
</head>
<body>
<table class="topmenubg" cellspacing="0" cellpadding="0" width="100%"
border="0">
<tbody>
<tr>
<td width="160" rowspan="2">
<div class=logo>
<span class="editiontext">Java 宫殿 <span
class="editionnumber">1.0</span> <br />
</div>
</td>
<td>
<div class="topmenu">
<ul>
<li id="menuon">
<span> <a
onclick="sethighlight(0); togglemenu('g1');"
href="javascript:;">页面技术1</a> </span>
</li>
<li>
<span> <a
onclick="sethighlight(1); togglemenu('g2');"
href="javascript:;">页面技术2</a> </span>
</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
4、menu.jsp
//这个页面中的重点是:menu的display;
<a href="showCourse.do" target="main">
<!-- target是重点,页面在哪里显示 -->
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/main/style.css"
type=text/css rel=stylesheet />
<script src="<%=request.getContextPath()%>/js/prototype-1.6.0.3.js"
type=text/javascript></SCRIPT>
<script>
function collapse_change(menucount) {
if ($('menu_' + menucount).style.display == 'none') {
$('menu_' + menucount).style.display = '';
$('menuimg_' + menucount).src = '${pageContext.request.contextPath}/css/main/menu_reduce.gif';
} else {
$('menu_' + menucount).style.display = 'none';
$('menuimg_' + menucount).src = '${pageContext.request.contextPath}/css/main/menu_add.gif';
}
}
</script>
</head>
<body style="">
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing="0"
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<div align="center">
<a href="#">首页</a>
</div>
</td>
</tr>
</tbody>
</table>
<div id="g1">
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing=0
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<img id="menuimg_11"
src="${pageContext.request.contextPath}/css/main/menu_reduce.gif"
border="0">
<a onclick="collapse_change(11);return false;" href="#">页面技术</a>
</td>
</tr>
</tbody>
<tbody id="menu_11">
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="showCourse.do" target="main">综合练习一</a>
<!-- target是重点,页面在哪里显示 -->
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="listProject.do?page=1" target="main">综合练习二</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="bookForm.do" target="main">综合练习三</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="loginForm.do" target="main">综合练习四</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="005/listModule.do" target="main">综合练习五</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div id="g2" style="display:none">
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing=0
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<img id="menuimg_11"
src="${pageContext.request.contextPath}/css/main/menu_reduce.gif"
border="0">
<a onclick="collapse_change(11);return false;" href="#">页面技术</a>
</td>
</tr>
</tbody>
<tbody id="menu_11">
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="showCourse.do" target="main">综合练习六</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="listProject.do?page=1" target="main">综合练习二</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="bookSearchForm.do" target="main">综合练习三</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="loginForm.do" target="main">综合练习四</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="005/listModule.do" target="main">综合练习五</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<table class="leftmenulist" cellSpacing="0" cellPadding="0"
width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<div style="MARGIN-LEFT: 48px">
<a href="#">退出</a>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
5、main.jsp
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/style.css"
type=text/css rel=stylesheet />
</head>
<body topMargin="10">
<div id="append_parent"></div>
<img src="images/1.jpg" width="760" height="530">
</body>
</html>
******************************************************************************************************
三、页面上的数据是一次取过来的还是多次取过来的
1、数据1次拿到,有js控制变更
2、数据多次拿到
数据少的时候全部拿过来;如果数据多,分多次拿
我们可以认为,写一个action,调用dao,然后把数据拿到request里面,然后发到页面上。这样的话,页面没有那么多的空间来展示页面
最好的是写一个action,然后让action仅仅显示页面,然后这个页面里面有一个js去异步访问数据库的获取数据,action返回的是JSON字符串。然
后js再控制事件去显示数据
浏览器------ActionServlet-------action--------DAO-------action-----JSP-------浏览器
第一个action显示页面,包含一个foward-------直接用struts里面的简单的ActionForward就行
第二个action获取数据,不包含forward
多个字段搜索
设计表的时候,主键不要与业务相关联
category_value????????
turn int(3) not null;
最典型的集成映射
<%@page pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<fmt:formatDate var="publishDate" value="${book.publishDate}" pattern="yyyy年M月" />
<b>${publishDate}</b>
//从value所存的日期,按照pattern的格式来存储,并存到pageContext中,叫publishDate
<td class="altbg2">
<fmt:formatNumber var="price" value="${book.price}" pattern="¥0.00" />
<b>${price}</b>
</td>
四、如何扩展EL表达式??
1、写一个类,里面用静态方法描述功能
2、写一个*.tld文件
一个功能定义一个function
<function>
<!--函数标记的名称,用在EL中-->
<name>len</name>
<!--这个函数的实现类-->
<function-class>org.whatisjava.el.ELFunction</function-class>
<!--方法的签名声明-->
<function-signature>
java.lang.Integer length(java.lang.Object)
</function-signature>
3、在页面中写一些东西
<%@taglib uri="/WEB-INF/jsp/lib/el-function.tld" prefix="f"%>
五、struts如何进行验证
步骤:
1、首先将工程里面添加struts2能力
2、创建一个form.jsp页面
3、创建一个AddAction.java的action,并修改struts-config.xml;创建Action;验证action是否正常工作
继承Action
4、再创建一个UserForm.java的action,并修改struts-config.xml;创建Action;并添加form-beans
继承ActionForm,其属性与表单页面提交的内容对应
5、修改AddAction,看其能否正常工作
但是这个时候提交上来的数据可能有些为空,有些不是合格数据
6、修改UserForm,添加validate方法
7、
验证框架的一种东西
原理commons有一个组件
commons-validator,这个组件准备用于数据的验证(数据的格式等的验证)
可以不去写validate这个方法,可以采用commons-validator
六、常用的form表单
<form action="" method="">
<input type="text" name=""/>
<input type="password" name=""/>
<input type="radio" name="..." value=""/>
<input type="checkbox" name="" value=""/>
<select name="">
<option value="">...</option>
</select>
</form>
struts提供的标记
<html:form action="" method="">
<html:text property=""/> //对应表单的文本框,property对应的name
<html:password property=""/>
<html:radio property="" value=""/>
<html:multibox property="" value=""/>
<html:select property="">
<html:option value="">
......
</html:option>
</html:select>
</html:form>
1、分页技术
2、选择导航
3、框架页面
4、各种顺序排序:如按照名称降序和升序;分页的时候仍然按照名称降序或者升序
5、数据的增删改查
6、登入、登出系统
7、弹出层可以进行选择
8、发消息,互相发消息
9、关联选取(异步方式)
10、标签库等ajax,STL
加载hibernate+struts2+mysql
mysql
create database palace1;
use palace1;
create table t_user();
//建表的类型 默认是MyISAM,尽量采用InnoDB
ENGINE=InnoDB;
采用MyISAM不支持外键约束,也不支持事务
用hibernate只是把方言更改下即可
框架iFrame
css是做好的;
index.jsp
<%@page pageEncoding="utf-8" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Index</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
</HEAD>
<BODY style="MARGIN: 0px">
<DIV style="Z-INDEX: 2; LEFT: 0px; WIDTH: 100%; POSITION: absolute; TOP: 0px; HEIGHT: 65px">
<IFRAME id="header"
style="Z-INDEX: 1; VISIBILITY: inherit; WIDTH: 100%; HEIGHT: 65px"
name=header src="header.do" frameBorder=0 scrolling=no>
</IFRAME>
<!--IFRAME是一个标记;id属性、src属性比较重要;style可以写在这里也可以现在css里面
首先把标记展示出来,然后再根据src属性的地址另外发一个请求将其展示出来。
有点类型于<img src=""/>
-->
</DIV>
<TABLE style="TABLE-LAYOUT: fixed" height="100%" cellSpacing=0
cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width=165 height=65></TD>
<TD></TD>
</TR>
<TR>
<TD>
<IFRAME id="menu"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=menu src="menu.do" frameBorder=0 scrolling=yes></IFRAME>
</TD>
<TD>
<IFRAME id="main"
style="Z-INDEX: 1; VISIBILITY: inherit; OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%"
name=main src="main.jsp" frameBorder=0 scrolling=yes></IFRAME>
</TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/style.css"
*******************************************************************
type=text/css rel=stylesheet />
</head>
<body topMargin="10">
<div id="append_parent"></div>
<img src="images/1.jpg" width="760" height="530">
</body>
</html>
定义一个包org.whatisjava.action专门来放action
在struts-config.xml文件里面配置org.apache.struts.actions.ForwardAction(只是用于转发页面而已,其他什么也不做)
<action-mappings>
<action path="/menu" type="org.apache.struts.actions.ForwardAction" parameter="/WEB-INF/jsp/menu.jsp">
<action path="/header" type="org.apache.struts.action.ForwardAction" parameter="/WEB-INF/jsp/header.jsp">
</action-mappings>
***************************
顶部导航菜单
左边菜单 右边主显示页面
**************************
实际上这是3个不同的页面
header.jsp
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/main/style.css"
type=text/css rel=stylesheet />
<script type="text/javascript">
var menus = new Array('g1','g2');
//全局变量;字符串数组;这里,g1,g2是menu里面的菜单的id
function togglemenu(id) {
for (i = 0; i < menus.length; i++) {
var k = menus[i];
parent.menu.document.getElementById(k).style.display = (k == id ? '' : 'none');
//任何一个div,getElementById("abc").style.display
//parent代表外面对象的id,menu代表左边的框,
//样式里面的display=none或者是id
}
}
function sethighlight(n) {
//document.getElementById('');
var lis = document.getElementsByTagName('li');
//获得页面中标签为li的标记对象
// obj.getElementsByTagName//不一定是document对象才有
for(var i = 0; i < lis.length; i++) {
lis[i].id = '';
}
lis[n].id = 'menuon';
}
</script>
</head>
<body>
<table class="topmenubg" cellspacing="0" cellpadding="0" width="100%"
border="0">
<tbody>
<tr>
<td width="160" rowspan="2">
<div class=logo>
<span class="editiontext">Java 宫殿 <span
class="editionnumber">1.0</span> <br />
</div>
</td>
<td>
<div class="topmenu">
<ul>
<li id="menuon">
<span> <a
onclick="sethighlight(0); togglemenu('g1');"
href="javascript:;">页面技术1</a> </span>
</li>
<li>
<span> <a
onclick="sethighlight(1); togglemenu('g2');"
href="javascript:;">页面技术2</a> </span>
</li>
<!--一个li代表一个导航
如何实现导航菜单,选中后突出显示呢?
通过<a onclick="sethighlight(0);togglemenu("g1");" href="javascript:;">
sethighlight方法
togglemenu方法
-->
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
menu.jsp
<%@page pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath()%>/css/main/style.css"
type=text/css rel=stylesheet />
<script src="<%=request.getContextPath()%>/js/prototype-1.6.0.3.js"
type=text/javascript></SCRIPT>
<script>
function collapse_change(menucount) {
if ($('menu_' + menucount).style.display == 'none') {
$('menu_' + menucount).style.display = '';
$('menuimg_' + menucount).src = '${pageContext.request.contextPath}/css/main/menu_reduce.gif';
} else {
$('menu_' + menucount).style.display = 'none';
$('menuimg_' + menucount).src = '${pageContext.request.contextPath}/css/main/menu_add.gif';
}
}
</script>
</head>
<body style="">
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing="0"
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<div align="center">
<a href="#">首页</a>
</div>
</td>
</tr>
</tbody>
</table>
<div id="g1">
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing=0
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<img id="menuimg_11"
src="${pageContext.request.contextPath}/css/main/menu_reduce.gif"
border="0">
<a onclick="collapse_change(11);return false;" href="#">页面技术</a>
</td>
</tr>
</tbody>
<tbody id="menu_11">
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="showCourse.do" target="main">综合练习一</a>
<!-- target是重点,页面在哪里显示 -->
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="listProject.do?page=1" target="main">综合练习二</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="bookForm.do" target="main">综合练习三</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="loginForm.do" target="main">综合练习四</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="005/listModule.do" target="main">综合练习五</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div id="g2" style="display:none">
******************************************
<table class="leftmenulist" style="MARGIN-BOTTOM: 5px" cellSpacing=0
cellPadding="0" width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<img id="menuimg_11"
src="${pageContext.request.contextPath}/css/main/menu_reduce.gif"
border="0">
<a onclick="collapse_change(11);return false;" href="#">页面技术</a>
</td>
</tr>
</tbody>
<tbody id="menu_11">
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="showCourse.do" target="main">综合练习六</a>
*****************************************************
<!--target的目标意义-->
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="listProject.do?page=1" target="main">综合练习二</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="bookSearchForm.do" target="main">综合练习三</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="loginForm.do" target="main">综合练习四</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr class="leftmenutd">
<td>
<table class="leftmenuinfo" cellSpacing="0" cellPadding="0"
border="0">
<tbody>
<tr>
<td>
<a href="005/listModule.do" target="main">综合练习五</a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<table class="leftmenulist" cellSpacing="0" cellPadding="0"
width="146" align="center" border="0">
<tbody>
<tr class="leftmenutext">
<td>
<div style="MARGIN-LEFT: 48px">
<a href="#">退出</a>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
关联选取(异步)
课程:
主题:
一个课程对应多个主题
从后往前分析
首先要有两张表:课程表、主题表;两张表存在关联关系
//t_course课程表字段为id,name其中id为自增长,主键;并插入2条数据
DROP TABLE IF EXISTS t_course;
CREATE TABLE t_course (
id int(11) NOT NULL auto_increment,
name varchar(50) default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
#
# Dumping data for table t_course
#
INSERT INTO t_course VALUES (1,'Java语言核心');
INSERT INTO t_course VALUES (2,'组件和框架');
//主题表有id,name,course_id,其中id为主键,course_id为外键与课程表主键值一样
//通过主外键来关联关系
DROP TABLE IF EXISTS t_subject;
CREATE TABLE t_subject (
id int(11) NOT NULL auto_increment,
name varchar(50) default NULL,
course_id int(11) default NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=REDUNDANT;
#
# Dumping data for table t_subject
#
INSERT INTO t_subject VALUES (1,'JSP技术',1);
INSERT INTO t_subject VALUES (2,'Servlet技术',1);
INSERT INTO t_subject VALUES (3,'Struts框架',2);
INSERT INTO t_subject VALUES (4,'Hibernate框架',2);
INSERT INTO t_subject VALUES (5,'Spring框架',2);
接下来我们看下Course.java Subject.java
package org.whatisjava.domain;
//实体类;
import java.util.Set;
public class Course {
//course表中无subject;为什么在其实体类中加上该属性呢?
//
private Integer id;
private String name;
private Set<?> subjects;
//为什么在这里设置一个Set<?> subjects呢?
//这是一对多单向关联
//主要是从业务角度方面考虑
//当我们选择课程的时候一定会把主题带出来;
//与此类似的还有省份----地市等
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<?> getSubjects() {
return subjects;
}
public void setSubjects(Set<?> subjects) {
this.subjects = subjects;
}
}
package org.whatisjava.domain;
public class Subject {
private Integer id;
private String name;
private Integer courseId;
//courseId关联关系;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCourseId() {
return courseId;
}
public void setCourseId(Integer courseId) {
this.courseId = courseId;
}
}
映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.whatisjava.domain">
<!--针对实体类Course-->
<class name="Course" table="t_course">
<id name="id" type="integer">
<generator class="native" /><!--native:主键的生成方法;
碰到oracle用序列;
主要看数据库用的哪种方言??
-->
</id>
<property name="name" type="string" />
<set name="subjects">
<key column="course_id" />
<one-to-many class="Subject" />
<!--set name为subjects,类名为Subject;其关联列名为course_id;通过couse_id来进行映射-->
</set>
</class>
<!--针对实体类Subject-->
<class name="Subject" table="t_subject">
<id name="id" type="integer">
<generator class="native" />
</id>
<property name="name" type="string" />
<property name="courseId" column="course_id" type="integer" />
</class>
<!--如果type也省略的话表示是string;如果column也省略的话表示的与列名一样-->
<query name="findAllCourse">
<![CDATA[
from Course
]]>
<!--这里面是纯文本;-->
</query>
<!--在这里的意思是可以在避免在程序中直接使用HQL语句;-->
<query name="findAllCourseWithSubjects">
<![CDATA[
from Course c left outer join fetch c.subjects
]]>
<!--为什么要加left outer;因为如果不加这个,没有主题的课程就提取不出来-->
</query>
</hibernate-mapping>
将mapping001.xml文件配置项加入到hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="myeclipse.connection.profile">mysql</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/palace
</property>
<property name="connection.username">root</property>
<property name="connection.password">******</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="show_sql">true</property>
<!-- 这句话的意思是什么呢?在运行hibernate语句的时候把sql语句打印出来 -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<mapping resource="org/whatisjava/domain/mapping001.xml" />
<mapping resource="org/whatisjava/domain/mapping003.xml" />
<mapping resource="org/whatisjava/domain/mapping002.xml" />
</session-factory>
</hibernate-configuration>
在这里我们主要是采用接口,实现接口来进行
//CourseDao接口,本身无实现;通过CourseDaoImpl来实现
//只有方法定义
package org.whatisjava.dao;
import java.util.List;
public interface CourseDao {
public List<?> findAllCourse();
public List<?> findAllCourseWithSubjects();
}
//*CourseDaoImpl实现类
package org.whatisjava.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.whatisjava.domain.Course;
public class CourseDaoImpl implements CourseDao {
/**
* 返回所有的课程
*/
public List<?> findAllCourse() {
return list;
}
/**
* 返回所有的课程且带主题
*/
public List<?> findAllCourseWithSubjects() {
return list;
}
}
在这里就不能再通过***Dao xxx=new xxxDao()来创建实例了。
最好是通过一个工厂来生产一个实例
构建一个DaoFactory工厂
package org.whatisjava.dao;
public class DaoFactory {
public static CourseDao getCourseDao(){
//切记返回值为CourseDao
return new CourseDaoImpl();
//这个方法是什么意思呢?
//CourseDao XXXXX=new CourseDaoImpl();
}
}
//这样操作的话,代码里面就不会出现CourseDaoImpl()了。
考虑到CourseDaoImpl实现中会连接数据库,在这里采用hibernate,则最好需要一个HibernateSessionFactory
HibernateSessionFactory工厂
package org.whatisjava.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactory(){
private static Configuration conf;
private static SessionFactory factory;
static {
conf=new Configuration();
conf.configure();
factory=conf.buildSessionFactory();
}
public static Session openSession(){
return factory.openSession();
}
}
构建一个测试类:
package org.whatisjava.test;
import org.whatisjava.dao.CourseDao;
import org.whatisjava.dao.DaoFactory;
public class TestCourseDao {
public static void main(String [] args){
CourseDao dao=DaoFactory.getCourseDao();
dao.findAllCourse();
}
}
//*CourseDaoImpl实现
package org.whatisjava.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.whatisjava.domain.Course;
public class CourseDaoImpl implements CourseDao {
/*
* 返回所有的课程
*/
public List<?> findAllCourse() {
//先获得session;
//通过createQuery返回值为query对象
Session session = HibernateSessionFactory.openSession();
//Query query=session.createQuery("from Course");
Query query=session.createQuery("from Course c join fetch c.subjects");
//Query query=session.createQuery("select distinct c from Course c join fetch c.subjects");
//联合抓取
//采用select distinct c from Course c join fetch c.subjects在3.2的版本之后可以清除重复的
//一般情况下,我们不想把HQL写到这里,最好的是写到映射文件里面
//Query query=session.getNamedQuery("findAllCourse");
//定义到映射文件里面
List<?> list=query.list();
//假设createQuery("from Course")返回的 list里面应该有课程的数据,但无主题的数据;
System.out.println(list);
Course c1=(Course)list.get(0); //list.get(0);
//list.get(0);
System.out.println(c1.getName()); //getName();
System.out.println(c1.getSubjects());
//由于延迟加载,session从这里关闭后就不能再引用数据了。
//1、请求不在这里关可以等数据拿出来之后再关;比如通过过滤器来关闭
//2、或者在mapping.xml文件里面<set name="subjects" lazy=false></set>对应位置加上lazy=false???
//一旦加上lazy=false之后,就不会再有延迟加载了。
//执行的时候就可以看到n+1条sql语句
//什么叫n+1查询语句?就是说如果用默认的方式取数据的话,就看couse表里面有n条记录;
//等用到的时候再根据每一个couse_id把数据查询出来
//这样查询的话,效率是比较低的。但是延迟加载的话,必须是n+1
//hibernate即使设置不使用延迟加载的时候,还是n+1
//我们改变这种方式的话,两个表做连接即可
//就是把上面的query语句由A变成B即可
A:Query query=session.createQuery("from Course");
B:Query query=session.createQuery("from Course c join fetch c.subjects");
//在查询subject表;
//先取出一条couse记录
session.close();
return list;
}
/**
* 返回所有的课程且带主题
*/
public List<?> findAllCourseWithSubjects() {
// TODO Auto-generated method stub
Session session=HibernateSessionFactory.openSession();
Query query=session.getNamedQuery("findAllCourseWithSubjects");
List <?> list=query.list();
session.close();
List list1=new ArrayList();
for (int i=0;i<list.size();i++){
if (!list1.contains(list.get(i))){
list1.add(list.get(i));
//集合里面的方法contains
//拿里面的对象用equals来进行比较
//看是否重写equals
//对象的相等逻辑是否真正相等的。
}
}
return list1;
}
}
课程:
java基础
框架
主题:
java基础--jsp基础;corejava;
框架----hibernate;struts;spring;
当选择课程时,主题变化
可以分为两种方式来解决:
1、数据量大的时候,可以全部取出来由JS来控制。
请求先发给前端控制器----action----dao----返回数据到action----jsp-----浏览器
在这里并不是把数据全部显示在页面上,而是由js来控制分层显示
2、
请求----画出页面---页面中js异步请求数据;这样
写一个action只显示页面;
第二个action去获取数据----只是解析成json字符串
struts-config.xml
<action path="" type="">
</action>
ListCourseAction
package org.whatisjava.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.whatisjava.dao.CourseDao;
import org.whatisjava.dao.DaoFactory;
public class ListCourseAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception{
CourseDao dao=DaoFactory.getCourseDao();
//建立dao
List list=dao.findAllCourseWithSubjects();
//获得课程和主题
JSONArray json = JSONArray.fromObject(list);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json.toString());
return null;
}
}
Course_form.jsp页面文件
<%@page contentType="text/html;charset=utf-8"%>
<%@include file="../common.jsp"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8" />
<link href="<%=request.getContextPath() %>/css/main/style.css"
type=text/css rel=stylesheet />
<script type="text/javascript"
src="<%=request.getContextPath() %>/js/prototype-1.6.0.3.js"></script>
<script type="text/javascript">
var courseObj = null;//全局变量
// 异步加载课程信息
function loadCourse() {
new Ajax.Request("listCourse.do", {
method :"get",
onSuccess : function(req) {//表示状态变成4之后,调用的方法;req是被封装起来的request对象
courseObj = req.responseText.evalJSON();
//响应回来的是一些文本对象,通过JSON将其转换成数组
//返回的是一组课程,数组;数组里面的元素是对象;
fillCourse();
}
//Ajax.Request有2个参数,第一个是字符串;第二个是对象(有2个属性,第一个属性是字符串;第二个属性是一个方法)
//是prototype来提供的
//new Ajax.Request("url",{method:"",onSucess:function(resp){...} }有两个参数
//向url地址发送请求;method是请求的类型,响应成功后会调用一个方法,这个方法会被传进来一个参数。
//传进来的这个参数就是Ajax.Request封装好的一个原始的请求对象
//{里面内容}:意思是响应成功之后要做什么事
});
}
/*
* 填充课程和主题
*/
function fillCourse() {
if (courseObj != null) {
var courseSelect = $('course'); //$ 即为:document.getElementByID
//这里的course为下面的select的id;
for (i = 0; i < courseObj.length; i++) {
// select 对象的属性options,表示其下所有的Option
// JS 中通过new Option 创建 option 对象;在java中是不能增加数组的长度的而js是可以随便增加的;
courseSelect.options[i] = new Option(courseObj[i].name,courseObj[i].id);
//第一个参数是中间显示的内容,第二个参数是提交的值
//以前就有的话,则会覆盖,如果没有的话就是新增
}
courseSelect.options[0].selected = true;
//courseSelect对象是select元素所对应的对象;第0个option被选中
fillSubject(courseObj[0].subjects);
//填充下面那个选择项(传输了一个参数过来)
}
}
function fillSubject(subjectObj) {
var subjectSelect = $('subject');
//subjectSelect.length=0; 目的是清空option;防止遗留上次的option
subjectSelect.length = 0;
for (i = 0; i < subjectObj.length; i++) {
subjectSelect.options[i] = new Option(subjectObj[i].name,
subjectObj[i].id);
}
}
/*
* 变更课程
*/
function changeCourse(index) {
var courseSelect = $('course');
courseSelect.options[index].selected = true; //index表示要改成谁?
fillSubject(courseObj[index].subjects);
}
</head>
<body topMargin="10">
<div id="append_parent"></div>
<table cellSpacing=6 cellPadding=2 width="100%" border=0>
<tbody>
<tr>
<td>
<table class=guide cellSpacing=0 cellPadding=0 width="100%"
border=0>
<tbody>
<tr>
<td>
<a href="#">页面技术</a> ?
<a href="#">001</a> ? 关联选取(异步方式)
</td>
</tr>
</tbody>
</table>
<br />
<form id="settings" name="settings" action="#" method="post">
<table class="tableborder" cellSpacing="0" cellPadding="0"
width="100%" border="0">
<tbody>
<tr class="header">
<td colSpan="2">
关联选取
</td>
</tr>
<tbody>
<tr>
<td class="altbg1" width="20%">
<b>课程:</B>
</td>
<td class="altbg2">
<select name="courseId" id="course"
onchange="changeCourse(this.selectedIndex)">
<!-- this表示当前选中的select的id;这个需要看w3cshcool文档 -->
<option value="-1">
--请选择课程--
</option>
</select>
</td>
</tr>
<tr>
<td class="altbg1" width="20%">
<b>主题:</b>
</td>
<td class="altbg2">
<select name="subjectId" id="subject">
<option value="-1">
--请选择主题--
</option>
<!--提交的是值,以及显示的内容、
-->
</select>
</td>
</tr>
</tbody>
</table>
<!--异步加载数据
//为什么不要写在这里?
如果代码放在前面的话,浏览器是从上到下面加载页面
loadCourse使用了select元素所以必须放在select元素的后面
-->
<script type="text/javascript">
loadCourse();
</script>
<br />
<center>
<input type="hidden" name="from">
<input class="button" type="submit" value="提 交"
name="settingsubmit">
</center>
</form>
</td>
</tr>
</tbody>
</table>
</body>
</html>