Title:霍占强老师上课相关知识点总结(上)
description:
@Copyright:
@Company:
@autor:firefly
@version:1.0
@time:2013.1.10
1、获取请求的路径问题
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
<base href="<%=basePath%>">
request.getSchema()可以返回当前页面使用的协议,就是上面例子中的“http”
request.getServerName()可以返回当前页面所在的服务器的名字,就是上面例子中的“localhost"
request.getServerPort()可以返回当前页面所在的服务器使用的端口,就是80,
request.getContextPath()可以返回当前页面所在的应用的名字,就是上面例子中的myblog
这四个拼装起来,就是当前应用的根路径了
<base href="...">是用来表明当前页面的相对路径所使用的根路径的。
比如,页面内部有一个连接,完整的路径应该是 http://localhost:80/myblog/authen/login.do
其中http://server/是服务器的基本路径,myblog是当前应用程序的名字,那么,我的根路径应该是那么http://localhost:80/myblog/。
有了这个<base ... >以后,我的页面内容的连接,我不想写全路径,我只要写 authen/login.do就可以了。
服务器会自动把<base ...>指定的路径和页面内的相对路径拼装起来,组成完整路径。
如果没有这个<base...>,那么我页面的连链接就必须写全路径,否则服务器会找不到。
2、java.util.Properties类的运用
(1)、properties文件是一个文本文件,可以先创建一个文本类型的文件,扩展名改为.properties进行创建。
(2)、properties文件的语法有两种,一种是注释,一种属性配置。
注 释:前面加上#号 属性配置:以“键=值”的方式书写一个属性的配置信息。
(3)、properties文件的一个属性配置信息值可以换行,但键不可以换行。值换行用“\”表示。
(4)、properties的属性配置键值前后的空格在解析时候会被忽略。
(5)、properties文件可以只有键而没有值。也可以仅有键和等号而没有值,但无论如何一个属性配置不能没有键。
(6)Properties类的层次结构
java.lang.Object
java.util.Dictionary<K,V>
java.util.Hashtable<Object,Object>
java.util.Properties
从层次机构看,Properties类实现了Map接口,因为HashTable实现了Map接口,因此Properties类本质上是一种简单的Map容器。
实际上,Properties类本身表示了对一种Map结构的操作。properties文件本身就表示了一个“键值对”的集合。
因此,Properties类属于集合容器的家族,在使用前应该创建一个Properties的容器,实际上就是创建一个默认不带参数的Properties对象。
以后通过别的方式给里面添加“键值对”。
(7)、properties和xml的区别
通俗的说properties和xml都是用来按一定结构保存数据的(废话),一般用于资源文件、配置文件,xml也多用于数据传输。
其实很多情况下用.properties和还是用xml只是你个人爱好问题。 (比如log4j就即可以用.properties配置也可以用xml配置。)
要硬说有什么区别,我觉得xml的层次感更强些,适用于大型的配置文件,比如典型的web.xml;而.properties文件更适合于轻量级的配置或者是作为资源文件来用(比如在struts中作为处理国际化的资源文件)。
而且xml通用性更强(更“标准”),经常作为webservice的数据载体来跨语言传送数据。(比如java要和.net交互,用.properties就略显不合适,因为.net里很少用.properties文件)
当然,最后一点,生成和解析.properties和xml所用的类,方法是不同的,但是都有现成的类库可用。.properties操作jdk有内置的,操作xml有jdom、dom4j等。
附:想了解更多,请看博客http://trans.blog.51cto.com/503170/110227/ 人家写的很好的。
示例:
import java.util.Properties;
public class DBUtil { //这个是一个数据库的封装类中的一部分,详细可见DB(48)
private static String driver = null;
private static String url = null;
static //当初始化时,先执行static中语句块中的内容
{
try {
Properties p = new Properties();
InputStream inStream = DBUtil.class.getClassLoader().getResourceAsStream("config.properties");
p.load(inStream);
driver = p.getProperty("driver");
url = p.getProperty("url");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection()
{
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
3、滚动条的使用
<center>
<div align="center" style="background-color:#999999; width:350;">
<marquee direction="right" onMouseOver="this.stop()" onMouseOut="this.start()">
<font color="#FF0033" face="华文行楷">通知:今天上课全勤,没来的别担心!</marquee>
</div>
</center>
4、项目编号及固定格式的使用
<ol type="A" start="2">
<li>有序列表项1</li>
<li type="1">有序列表项2</li>
<li>有序列表项3</li>
</ol>
<pre>
学校 专业
河南理工大学 软件工程10-1-6
</pre>
5、锚点的使用
<a name="archor1">这里定义一个锚点的名字</a>
<h1><a href="#archor1">HTML</a></h1>
6、JSP中获得绝对路径
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
7、为表格设置标题
caption 标签必须紧随 table 标签之后。只能对每个表格定义一个标题。通常这个标题会被居中于表格之上。
<table border="2" width="300" align="center">
<caption>表格示例</caption>
<tr align="center">
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</table>
8、表格中rowspan和colspan的使用
<table border="1" width="50%">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td rowspan="2">6</td> //竖向占两列
</tr>
<tr>
<td colspan="2">7</td> //因为竖向占两列,所以第三行,只要占两个单元格的大小就将表格设计好了。
</tr>
</table>
9、框架集的运用
<frameset rows="150,*">
<frame name="topFrame" src="top.html"/>
<frameset cols="20%,*">
<frame name="leftFrame" src="left.html"/>
<frame name="mainFrame" src="main.html"/>
</frameset>
</frameset>
10、在文本上单击选中表单元素
<form>
<label for="male" accesskey="m">男</label>
<input type="radio" name="sex" checked="checked" id="male"/> //这里的id要和label标签里的for里面的值一样。
<label for="female" accesskey="f">女</label> //accesskey(热键)指定快捷键在不能使用鼠标的时候,也能通过键盘操作(Alt+相应字母)进行选择、跳转链接或按下按钮等操作。
<input type="radio" name="sex" id="female"/> //label标签为鼠标用户改进了可用性。如果在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会
//自动将焦点转到和标签相关的表单控件上。
</form>
示例程序如下:
<form action="">
<div>
<a href="accesskey.html" accesskey="j">跳转(<u>J</u>)</a>
</div>
<div>
<input type="radio" id="r1" name="YESNO" value="YES" checked>
<label for="r1" accesskey="y">YES(<u>Y</u>)</label>
<input type="radio" id="r2" name="YESNO" value="NO">
<label for="r2" accesskey="n">NO(<u>N</u>)</label>
</div>
<div>
<input type="checkbox" id="c1" name="Win">
<label for="c1" accesskey="w">Windows(<u>W</u>)</label>
<input type="checkbox" id="c2" name="Mac">
<label for="c2" accesskey="m">Macintosh(<u>M</u>)</label>
</div>
</form>
按住Alt键(Mac的话按住Ctrl键),按J键或B键试试看。
11、css部分使用方法
<head>
<title>无标题文档</title>
<style type="text/css">
a
{
text-decoration:none;
}
a:hover
{
text-decoration:underline;
}
.labelFont
{
font-family:"华文楷体";
/*font-size:36px;*/
color:#FF0000;
}
#lableFont2
{
font-family:"华文楷体";
font-size:12px;
color:#00FF00;
}
h2.cls1
{
color:#0000FF;
}
</style>
</head>
<body>
<p>
<h2 class="cls1">二级标题1</h2> <!--h2标签中名字为cls1的定义格式的使用,和下面标签的显示结果不同-->
</p>
<h2>二级标题2</h2>
<p>
<a href="#">超链接</a> <!--将鼠标移上去时,超链接自动加一个下划线,看上面css的定义-->
</p>
<form>
<label for="male" accesskey="m" class="labelFont">男</label> <!--lable标签的两种显示方式,这一种通过class来实现-->
<input type="radio" name="sex" checked="checked" id="male"/>
<label for="female" accesskey="f" id="lableFont2">女</label> <!--lable标签的两种显示方式,这一种通过id来实现,在css中是不同的定义方式-->
<input type="radio" name="sex" id="female"/>
</form>
</body>
12、从外部想入css文件的两种方式:
(1)、<link rel="stylesheet" href="css/main.css" type="text/css"/>
(2)、<style type="text/css">
@import url(css/main.css); /*@import rules must always be first in a document*/
</style>
13、javascript的简单使用
function clearName()
{
var name = document.regForm.un.value; //document后面写的是表单的名字,标签的名字,value代表标签的值。
if(name == "input your name")
{
document.regForm.un.value = "";
document.regForm.un.focus(); //这里要聚焦显示一下.
}
}
<form name="regForm" method="get" action="" οnsubmit="return confirmForm()">
Name:<input type="text" name="un" value="input your name" οnfοcus="clearName()"/><br/>
附:导入.js文件的方式:
<script language="javascript" src="js/main.js" charset="gbk"></script>
14、在servlet中out.print(this.getClass());的意思
this.getClass() 拿到当前类的对象
this.getClass().getSuperclass()拿到当前对象的父类对象
this.getClass().getSuperclass().getName()拿到当前对象的父类对象名字 即:父类名
"."表示的就是方法调用, 可以连续的用
this.getClass().getResource(fileName.txt); //文件名的位置就是调用类的位置
=this.getClass().getResource(/edu/hpu/com/cn/fileName.txt); //getResources将会把它作为一个绝对路径并简单地调用类加载器
=this.getClass().getClassLoader().getResource(edu/hpu/com/cn/fileName.txt);
//文件名的位置就是根路径的位置,你不能使用/在类加载器路径的前面,是因为/在此时不是一个有效的字符路径,所有的类加载器的路径是绝对的。
//以上三个语句的实际结果是一样的。使用this.getClass().getResource(fileName.ext);得到的是edu.hpu.com.cn.fileName.txt文件。
getResouce()方法的参数,以class为出发点,再结合相对路径的概念,就可以准确地定位资源文件了。
至于它的根目录,你用不同的IDE build出来是不同的位置下的,不过都是以顶层package作为根目录,比如在Web应用中,
有一个WEB-INF的目录,WEB-INF目录里面除了web.xml文件外,还有一个classes目录,没错了,它就是你这个WEB应用的package的顶层目录,
也是所有.class的根目录“/”,假如clasaes目录下面有一个file.txt文件,它的相对路径就是"/file.txt"
附:绝对路径、根路径及相对路径:
绝对路径:我们不需要知道其他任何信息就可以根据判断出文件的位置。
根目录:在网站的应用中,通常我们使用"/"来表示根目录,这里所指的根目录并不是你的网站的根目录,而是你的网站所在的服务器的的根目录
相对路径:在网站的应用中,我们使用“../”来表示上一级目录,“../../”表示上上级的目录
15、session的应用
session的创建和属性值的设定,也可以将其写成一个语句用下面的语句的书写格式。
HttpSession session = request.getSession();
session.setAttribute("user", "sandy");
当表单提交之后由web.xml中的设置,来执行相应的servlet文件
String username = request.getParameter("username"); //获取参数
String password = request.getParameter("password");
if("sandy".equals(username) && "123".equals(password)) //判断参数,正确了怎样,错误了怎样
{
request.getSession().setAttribute("username", username); //设置session
request.getRequestDispatcher("/welcome.jsp").forward(request, response); //由request,获得请求分发器,执行跳转
}
else
{
String msg = "Username or password error!"; //如果提交的参数错误的话,设置错误的信息msg,并将其在页面index.jsp中输出出来。
request.setAttribute("msg", msg);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
如果登陆的用户名和密码正确,跳转到welcom.jsp通过下面的session语句获得相应的信息:
Welcome <%=request.getSession().getAttribute("username")
16、利用session和list动态实现购买物品
Product p = new Product(); Product是一相servlet类里面有pName和pNum两个私有的属性和一个equals()方法及hashCode()方法(只不过eqauls方法这里看的不是很懂传入的是objet对象)
p.setPName(pName);
p.setPNum(pNum);
Object pList = request.getSession().getAttribute("productList");
if(pList == null)
{
List<Product> list = new ArrayList<Product>();
list.add(p);
request.getSession().setAttribute("productList", list);
}else
{
List<Product> list = (List<Product>)pList;
if(list.contains(p)) //对于string类型或者Int类型,我们可以直接用list.Contains()来判断是否存在p。不存在的话把p加入列表中。
{
for(Product t : list) //利用for循环逐个判断p是否存在在列表中。
{
if(t.getPName().equals(p.getPName()))
{
t.setPNum(t.getPNum() + p.getPNum());
}
}
}else
{
list.add(p);
}
}
request.getRequestDispatcher("/show.jsp").forward(request, response); //实现商品的添加后,从servlet跳转到show.jsp页面。
show.jsp页面知识点:
1.能实现list中数据的手动修改
2.能实现list中数据的删除
3.能返来到购买商品的表单提交页
4.名字相同的商品数据能过session实现累加
<head>
<script type="text/javascript">
function modifyNum(id,name,num)
{
//双引号与单引号要交替使用
var tdNode = document.getElementById(id);
var inputNode = "<input id='tmpInput' type='text' value='"+num+"' οnblur='doModify(\""+name+"\")' />";
tdNode.innerHTML = inputNode; //innerHTML用于更改一个链接的文本,用于设置属性或返回单元格的开始标签和结束标签之间的HTML。
document.getElementById("tmpInput").focus();
}
<%/*
document.getElementById(id) 方法可返回对拥有指定 ID 的第一个对象的引用。
在操作文档的一个特定的元素时,最好给该元素一个 id 属性,为它指定一个(在文档中)唯一的名称,然后就可以用该 ID 查找想要的元素。
HTML DOM 定义了多种查找元素的方法,除了 getElementById() 之外,还有 getElementsByName() 和 getElementsByTagName()等。
如果需要查找文档中的一个特定的元素,最有效的方法是 getElementById()。
更改一个链接的文本、URL和target;示例如下:
document.getElementById('myAnchor').innerHTML="W3School";
document.getElementById('myAnchor').href="http://www.w3school.com.cn";
document.getElementById('myAnchor').target="_blank";
*/>
function doModify(name)
{
var num = document.getElementById("tmpInput").value;
location.href = "modify?name="+name+"&num="+num; //在javascript中通过location.href实现从当前页面跳转到指定页面。
}
</script>
</head>
<body>
<h1>商品列表</h1>
<hr/>
<table width="40%" border="1">
<tr>
<th>商品名称</th>
<th>商品数量</th>
<th>操作</th>
</tr>
<%
List<Product> list = (List<Product>)request.getSession().getAttribute("productList"); //能过session获得list.
int i = 1;
for(Product p : list) //jsp页面中循环的使用方式。
{
%>
<tr>
<td><%=p.getPName()%></td>
<td id="tdNum<%=i %>" οnclick="modifyNum('tdNum<%=i %>','<%=p.getPName() %>',<%=p.getPNum() %>)"><%=p.getPNum() %></td> //单击单元格,并最终通过javascript跳转页面,修改数据。
<td><a href="delProduct?name=<%=p.getPName()%>">删除</a></td>
</tr>
<%
i++;
}
%>
</table>
<a href="index.jsp">返回</a>
</body>
修改数据的主要代码如下:
int pNum = 0;
if(pNumString != null)
{
pNum = Integer.parseInt(pNumString); //将传进来的字符串类型的商品数,转换为整形。
}
Product p = new Product();
p.setPName(pName);
p.setPNum(pNum);
Object pList = request.getSession().getAttribute("productList");
List<Product> list = (List<Product>)pList;
for(Product t : list) //通过循环,找到对应的名字,修改商品数量。
{
if(t.getPName().equals(p.getPName()))
{
t.setPNum(p.getPNum());
}
}
也可以用这样循环的方式删除一个商品,另一种更简便的方法是:通过list.remove(p);来直接删除一个商品p。
修改页面和删除页面和购买页面一样,最后都跳转到show.jsp.
17、生命周期的全过程
(1)加载:用classLoader把claass加载进来。
(2)实例化:new对象,运行构造方法。
(3)初始化:调用init()方法,init方法,可以传入参数,也可以不传入参数。
传参的init方法,可以这样去写:
public void init(ServletConfig config) throws ServletException {
System.out.println("Message from init method with parameter");
String uName = config.getInitParameter("universityName"); //用这条语句获得初始化参数universityName的值,universityName这个参数在web.xml中设置着,如下所示
System.out.println(uName);
}
web.xml中的配置配置信息:
<servlet> //在<servlet>中除了可以有<servlet-name>、<servlet-class>两个标签外,还可以用<init-param>设置某个servlet初始化时的参数名和参数值。
<servlet-name>lifeCycle</servlet-name>
<servlet-class>cn.edu.hpu.servlet.LifeCycleServlet</servlet-class>
<init-param>
<param-name>universityName</param-name>
<param-value>Henan Polytechnic University</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>lifeCycle</servlet-name>
<url-pattern>/lifecycle</url-pattern>
</servlet-mapping>
(4)处理请求:对HTTPServlet来说就是doget()和dopost()方法
(5)退出服务:在服务器关闭时调用destory()方法。
18、通过servlet中的aplication和list来实现jsp页面的监听,代码如下:
public class OnlineListener implements ServletContextListener,
HttpSessionListener, HttpSessionAttributeListener {
private ServletContext application = null;
public void contextDestroyed(ServletContextEvent arg0) { }
public void contextInitialized(ServletContextEvent event) { //应用上下文时,初始化要调的方法。
List<String> list = new LinkedList<String>();
application = event.getServletContext(); //创建一个aplication。
application.setAttribute("list", list); //为aplication设置属性值。
}
public void sessionCreated(HttpSessionEvent arg0) { }
public void sessionDestroyed(HttpSessionEvent event) { //会话销毁时调用的方法。
String user = event.getSession().getAttribute("user").toString();
List<String> list = (List<String>)application.getAttribute("list");
list.remove(user);
}
public void attributeAdded(HttpSessionBindingEvent event) { //往会话中添加属性时会调用的方法。
String name = event.getName();
if(name != null && name.equals("user"))
{
List<String> list = (List<String>)application.getAttribute("list"); //获取aplication的属性。
if(!list.contains(event.getValue().toString()))
{
list.add(event.getValue().toString());
}
}
}
public void attributeRemoved(HttpSessionBindingEvent arg0) { }
public void attributeReplaced(HttpSessionBindingEvent arg0) { } //当属性被替代时销毁。
}
servlet监听器,web.xml中的相关设置如下:
<listener>
<listener-class>cn.edu.hpu.listener.OnlineListener</listener-class>
</listener>
19、servlet过滤器,有三个方法,相关代码如下:
public class CharcterEncodingFilter implements Filter {
private FilterConfig config;
public void init(FilterConfig config) throws ServletException { //Filter初始化时的调用方法
this.config = config;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) thorws IOException, ServletException { //Filter主要做过滤工作的方法
String encoding = config.getInitParameter("encoding");
if(null != encoding && !"".equals(encoding)) {
request.setCharacterEncoding(encoding);
}
chain.doFilter(request, response); //用于调用过滤器链中的下一个过滤器。
}
public void destroy(){ } //Filter被释放时调用的方法。
}
servlet监听器,web.xml中的相关设置如下:
<filter>
<filter-name>Compression Filter</filter-name>
<filter-class>cn.edu.hpu.filter.CharcterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Compression Filter</filter-name>
<url-pattern>/pages/*</url-pattern>
</filter-mapping>
pages/*是过滤pages文件夹下的所有文件。
20、把mysql中的datetime日期类型转化为java.util.Date的类型。
String stuBirthday = req.getParameter("stuBirthday");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date birthday = sdf.parse(stuBirthday);
21、mysql中的修改语句的相关代码:
public boolean update(Student stu) {
boolean flag = false;
Connection conn = null;
PreparedStatement pst = null;
//下面的语句没有捕获异常
conn = DBUtil.getConnection();
String sql = "update student set name=?,age=?,address=?,birthday=? where id=?"; //运用这样的update语句修改,
pst = conn.prepareStatement(sql);
pst.setString(1, stu.getName());
pst.setInt(2, stu.getAge());
pst.setString(3, stu.getAddress());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
pst.setString(4, sdf.format(stu.getBirthday())); //format方法将一个 Date 格式化为日期/时间字符串。
pst.setInt(5, stu.getId());
int rows = pst.executeUpdate();
if(rows > 0)
{
flag = true;
}
}
附:有关日期的格式化
yyyy是元年,MM是月份,dd是日期 HH是小时(24制) hh是小时(12制) mm是分 s是秒 S是毫秒 E是星期 D是一年中的第几天 F是一月中第几个星期几
w是一年中第几个星期 W是一月中第几个星期 a是上午/下午 标记符 k是在一天中 (1~24) K是在上午或下午 (0~11) z 时区
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
(1)字串转日期:
20132-01-12 15:30:22要把它转成日期,可以用 Date date=sdf.parse("2012-01-12 15:30:22");
(2)日期转字串
假如把今天的日期转成字串可用 String datestr=sdf.format(new Date()); 这样datestr便会依照我们设定的格式输出
22、servlet中的cookie的创建及使用
String username = request.getParameter("username");
String password = request.getParameter("password");
if("sandy".equals(username) && "123".equals(password))
{
Cookie un = new Cookie("username",username); //创建一个cookie。
Cookie pwd = new Cookie("password",password);
un.setMaxAge(60*60*24*30); //这种cookie的形式被写在文档中,过了一个月后才会消失。
pwd.setMaxAge(60*60*24*30);
response.addCookie(un); //将cookie添加到response中去。
response.addCookie(pwd);
request.getRequestDispatcher("/getAllStudents").forward(request, response);
}else
{
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
<%
//如果将下面的代码写在jps页面中,则如果存在cookie,会自动将cookie中的相关数据填写到相应的地方。
String username = "";
String password = "";
Cookie [] cs = request.getCookies(); //从客户端拿到cookie,运用数组。
if(cs!=null) {
for(Cookie c : cs)
{
if(c.getName().equals("username"))
{
username = c.getValue();
}
if(c.getName().equals("password"))
{
password = c.getValue();
}
}
}
%>
<form action="login" method="post">
用户:<input type="text" name="username" value="<%=username %>"/><br/>
密码:<input type="password" name="password" value="<%=password %>"/><br/>
<input type="submit" value="提交"/>
</form>
23、通过Filter可以限制某一IP的使用,使其被拉黑,不能登录这个网站
public class IPAddressFilter implements Filter {
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
String ip = request.getRemoteAddr();
System.out.println(ip);
if("122.207.171.222".equals(ip))
{
request.getRequestDispatcher("/error.jsp").forward(request, response);
} else
{
System.out.println("请求数据之前的IPSddressFilter");
chain.doFilter(request, response);
System.out.println("请求数据之后的IPSddressFilter");
}
}
public void init(FilterConfig filterConfig) throws ServletException { }
}
24、通过servlet中的application实现访问总人数的统计
//实现用户计数功能,在GetAllStudentServlet.java中的代码
ServletContext application = getServletContext();
Integer userCount = (Integer)application.getAttribute("userCount");
Integer count = 1;
if(userCount == null)
{
application.setAttribute("userCount", count);
}else
{
count = userCount + 1;
application.setAttribute("userCount", count);
}
//下面这个是在show.jsp中的调用application的代码
您是本网站的第<%=application.getAttribute("userCount").toString() %>位访客.