1. form 表单的属性 action 表示表单数据要提交的位置
2. 关于xml:
1)<web-app> 是XML文件的根节点,根节点中包含一个没有前缀的命名空间。web-app标记包含两个子标记
(1) <servlet> 标记表示要加载的servlet类所在的位置,及Servlet的名称。
其子句包含两个子标记,<servlet-name> 标记表示Servlet类的名称,该名称可以自由命名,
实际上该名称是类的实例化对象在这里类的名称和类最好保持一致。
<servlet-class> 表示Servlet类的存在位置,要把全名写出啦,即包名.类名。
(2) <servlet-mapping> 标记表示访问Servlet类的时候,采用的URL路径。
<servlet-name> 是Servlet类实例化名称,要和<servlet> 标记中的名称保持一致。
<url-pattern> 是在访问这个Servlet时,在IE地址栏中输入的名称,名称可以改变,当要注意格式,要以”/“
开始。
2)注意: 在实际操作过程中发现:
<servlet-mapping>中子标记<url-pattern>值要与JSP文件中action属性的值一致(如果有jsp,在IE地址栏中输入的是xxx.jsp)
3. 下面的代码:
public void init(ServletConfig config) throws ServletException
{
super.init(config);
}
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException
{
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out=resp.getWriter();
out.println("<html><head><title>处理Servlet请求</title></head>");
out.println("<img src=\"imgs/2.jpg\" height=400 width=260><br>");
String protocol=req.getProtocol();
out.println("使用的协议时"+protocol+"<br>");
String path=req.getServletPath();
out.println("Servlet的访问路径是"+path+"<br>");
int length=req.getContentLength();
out.println("请求的内容的长度"+length+"<br>");
String header1=req.getHeader("User-Agent");
out.println("获取HTTP头文件中User-Agent的值"+header1+"<br>");
String header2=req.getHeader("accept");
out.println("获取HTTP头文件中accept的值"+header2+"<br>");
String header3=req.getHeader("Host");
out.println("获取HTTP头文件中Host的值"+header3+"<br>");
String IP=req.getRemoteAddr();
out.println("获取客户的IP地址"+IP+"<br>");
String clientName=req.getRemoteHost();
out.println("获取客户机的名称"+clientName+"<br>");
String serverName=req.getServerName();
out.println("获取服务器名称"+serverName+"<br>");
int serverPort=req.getServerPort();
out.println("获取服务器的端口号"+serverPort+"<br>");
String s="接受到一个";
String ss="请求,这是对该请求的响应";
out.println("<p>" +s +req.getMethod() + ss+"</p>");
out.println("</body></html>");
}
E:\Myeclipse10\Common\plugins\com.genuitec.eclipse.j2eedt.core_10.0.0.me201110301321\data\libraryset\EE_6
4: web
下面的代码是用于建立一个虚拟主机时在tomcat中server.xml中添加的一段代码
<Host name="www.sina.com" appBase="f:\sina">
<Context path="" docBase="f:\sina\news" />
</Host>
在f盘中建立的sina文件夹中的news子选项里,建立WEB-INF子文件夹,里面新建一个web.xml
用于设定默认欢迎界面
在建立虚拟主机时,需要在windows-system32-drivers-etc-hosts中加入 ip 主机名(如 115.14.90.150 www.sina.com)
这样在IE地址栏中就可以通过 http://www.sina.com:8080/ 访问自己建立的sina主机了。
5: 加载配置文件,用于连接数据库等。(这个类不在Servlet类当中,类名UserDao,配置文件 "db.properties")
1)采用类加载器的方式加载配置文件(文件不要太大,否则会溢出)
class UserDao
{
Properties dbconfig=new Properties();
public void update()
{
InputStream in = UserDao.class.getClassLoader().getResourseAsStream("db.properties");
dbconfig.load(in);
system.out.println(dbconfig.getProperty("url")); //url为配置文件中内容,就是map集合中的name属性
}
}
2)采用传统方式 (采用类加载器方法时,对于更新后的数据不能进行同步,因为类加载器只加载一次,
而通过类加载器的方式获得配置文件的位置,在通过传统方式读取配置文件数据这样就能读取更新后的数据!)
class UserDao
{
Properties dbconfig=new Properties();
public void update()
{
String path = UserDao.class.getClassLoader().getResourse("db.properties").getPath();
FileInputStream in = new FileInputStream("path");
dbconfig.load(in);
system.out.println(dbconfig.getProperty("url")); //url为配置文件中内容,就是map集合中的name属性
}
}
3)当UserDao中有多个方法要读取配置文件时,把读取配置文件的代码放在static静态代码块中比较好
static
{
try
{
InputStream in = UserDao.class.getClassLoader().getResourseAsStream("db.properties");
dbconfig.load(in);
}
catch(Exception e)
{
throw new ExceptionInInitializerError(e); //要把错误抛出去,不能打印
}
}
6. 解决post提交乱码
在服务器端 request.setCharacterEncoding("UTF-8");
解决get提交乱码问题
在服务器端 String username = request.getParameter("username");
username = new String(userName.getBytes("ISO-8859-1","UTF-8");
7. javaBean技术
1)javaBean其实就是一个java类。但是有相关的规定
(1)这个类可序列化(能够持久保存液能恢复状态),也就是它必须实现java.io.Serializable接口
(2)这个类必须带有一个无参数的构造方法。
(3)这个类的属性必须通过使用get、set和其他按标准命名规范来命名的方法操作:若成员变量名是XXX
那么要有方法:getXXX(),用来获取属性;setXXX()用来设置修改属性。对于boolean类型的成员变量
可以使用is代替get和set类中的方法的访问。属性必须都是public的。内种如果有构造方法,那么这个
构造方法也是Public的,并且是无参数的。
(4)这个类包含所有必须的事件处理方法。
2)在创建有状态应用程序时,数据管理很关键。为了能智能地管理用户数据,必须将其置于上下文中,这可以
通过作用域(scope)来实现。在javaBean中有4种作用域用于管理数据:application(应用程序)、
session(会话)、request(请求)、page(页面)。
(1)page作用域:这个域是4个作用域中范围最小的一个,他只适用于当前的JSP页面,当客户离开这个JSP
页面时javaBean就会失效。
<jsp:useBean id="Bean-name" class="class-name" scope="page">初始化成员</jsp:useBean>
(2)request作用域:使用jsp的request对象可以获得另外一个页面提交给本页面的信息。
同样,javaBean的request作用域和request对象有相同的作用域。当JSP页面分中使用<jsp: forward>操作
指令向另外一个JSP程序或者使用<jsp: include>指令导入另外的JSP页面时,第一个JSP页面会把request对象
传递到下一个JSP页面,而属于request作用域的javaBean类也将伴随着request对象的送出,而被第二个JSP页面接收。
使用request的javaBean组件对象使得JSP页面传递信息更容易,但是由于客户端不能执行JSP程序创建新的javaBean
对象,所以javaBean不能够由于客户端与服务器端之间传递信息。
<jsp: useBean id="Bean-name" class="class-name" scope="request">初始化成员</jsp: useBean>
request作用域范围的javaBean对象存储在当前ServletRequest中,有request范围的javaBean实例可以在处理请求的
所有JSP页面中都存在。这个对象只有在请求全部处理完毕后才会被释放掉,request范围的javaBean常用于共享同一次
请求的JSP页面中。例如判断用户登陆功能,如果用户密码合法就可以forward到一个合法的页面中,否则就forward到
一个出错页面。当然,转以后的页面仍然能够得到用户的输入。
(3)session作用域:例如购物车一般就是放在session中的或者登陆后的用户信息等也是可以放在session中。
注意:<%@ page %>标签中不要设置session=false,否则在这个JSP 页面中session将不会起作用,
在JSP 页面中,默认session=true,所以可以不必管它了。
<jsp:useBean id="Bean-name" class="class-name" scope="session" >初始化成员</jsp:useBean>
(4)application 作用域 :application作用域范围的javaBean对所有用户和所有页面都起作用,只需创建一次,而且
将会存在于WEB应用程序执行的整个过程中。
application作用域的javaBean对于处理需要对所有用户和页面都有效的数据十分有用。
例如:程序中常用的数据库连接URL、全局的计数器或者是聊天室中人员信息等。
作用域范围为application的javaBean对象存储在ServletContext 中,即application对象,这就意味中javaBean
生存周期是整个应用程序,当web Servlet停止才会消失。
<jsp:useBean id="Bean-name" class="class-name" scope="application">初始化成员</jsp:useBean>
(5)session作用域的javaBean和application作用域的javaBean可以用在多个页面,但是session的范围是在一个会话中,
而application的范围在整个网站中。
3)JSP页面通过useBean动作标记调用javaBean。如果JSP页面要设定javaBean中变量的值,可以通过set方法组;
获取变量的值,可以通过get方法组。
同样,也可以通过JSP中动作标记setProperty 来设置javaBean中的变量值,通过getProperty动作标记来获取变量值。
(1) setProperty 动作标记:
setProperty动作标记在使用之前,需要用useBean动作标记包含一个javaBean。
该标记可通过3中方式设置beans属性的值,分别为将beans属性的值设为一个表达式的值或字符串、通过http表单
的参数值来设置beans相应的属性值,以及通过request参数值来设置beans相应的属性值。
1)设为一个表达式的值或字符串
字符串赋值如下:
<jsp:setProperty name="bean name" property="property name" value="str" />
表达式赋值如下:
<jsp:setProperty name="bean name" property="property name" value=<%= expression %> />
上述两个表达式中,name="bean name" 是必须的,用来表明对哪个bean实例执行下面的动作,这个值和
动作<jsp:useBean>中定义的ID必须对应起来,包括大小写都必须一致。
property="property name"这个属性也是必须的,用来表示要设置哪个属性。
value="具体的值" 主要用来指定bean的属性的值。
2) 通过http表单参数值设置
通过http表单的参数值来设置beans相应的属性值,要求表单参数的名字必须与beans属性的名字相同。语法格式如下:
<jsp:setProperty name="bean name" property="*" />
property的值是“*”表示用户在可见的JSP页面中输入的全部值,存储在匹配的bean属性中。
匹配的方法是:bean的属性名称必须与输入框的名字相同。
3)通过request参数值设置
要求:request参数名字必须与javabean属性的名字相同。语法格式如下:
<jsp:setProperty name="beans name" property="property name" param="param name" />
上述代码中,name表示javabean的ID名称,property属性表示javabean中的属性名称,param属性代表了页面请求的
参数名字。
注意:不能同时使用 param 和value!
通过request给javabean赋值,param对应的是http表单中的文本框的名称,property对应的是javabean中变量的名称。
(2) getProperty 动作标记:
getProperty动作标记主要用来提取指定的bean属性的值,转换成字符串,然后输出。该动作标记实际是调用bean的get()方法。
在使用该动作标记之前,必须使用useBean标签获得一个javabean实例。该动作标记语法格式如下:
<jsp:getProperty name="beanInstanceName" property="propertyName" />
上述代码中,name="beanInstanceName"这个属性是必须的,用来表明对哪个bean实例执行下面的动作,这个值和动作
<jsp:useBean> 中定义的ID必须对应起来,包括大小写都必须一致。
property="*" | property="propertyName"这个属性也是必须的,用来表示要获取哪个属性。
8.JSP九大隐式对象
request\response\session\application\config\page\out\exception\pageContext
9.使用jstl需要导入jstl.jar 与standerd.jar 两个包
10.使用ini配置文件连接数据库的模板代码
//以下是模板代码
public static Connection getConnection() throws Exception
{
Properties props = new Properties();
FileInputStream in = new FileInputStream("E:\\Myeclipse10\\haha\\shiyansi\\src\\db.ini");
props.load(in);
in.close();
// String drivers = props.getProperty("SQLServerDriver");
String drivers = props.getProperty("MySQLDriver");
if(drivers != null)
{
// System.setProperty("SQLServerDriver", drivers);
Class.forName(drivers);
}
String url = props.getProperty("MySQLUrl");
String user = props.getProperty("MySQLUser");
String password = props.getProperty("MySQLPsw");
// String url = props.getProperty("SQLServerUrl");
// String user = props.getProperty("SQLServerUser");
// String password = props.getProperty("SQLServerPsw");
return DriverManager.getConnection(url, user, password);
}
11.数据库分页
MySql
select * from tableName limit 0,5
SqlServer
select top 5 * from tableName where id not in(select top 0 id from tableName);
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db909?useUnicode=true&characterEncoding=UTF8&useOldAliasMetadataBehavior=true
12.一个bean复制到另一个bean
public static void copyBean(Object src, Object dest)
{
//自定义类型转换器
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class type, Object value)
{
if(value==null)
{
return null;
}
String str = (String) value;
if(str.trim().equals(""))
{
return null;
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try
{
return df.parse(str);
}
catch(ParseException e)
{
throw new RuntimeException(e);
}
}
}, Date.class);
try
{
BeanUtils.copyProperties(dest, src);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
13. 关于异常:
下层想向上层抛异常,一般都是抛运行时异常-即RuntimeException 只有一种情况抛编译时异常,那就是向上层传递数据(返回值)的时候跑编译时异常。
14.事务的四大特性(ACID)
1)原子性
2)一致性
3)隔离性
4)持久性
create table test
(
id int primary key auto_increment,
name varchar(20),
money double
);
15. 使用包装设计模式五部曲:
1、实现与被增强对象相同的接口 BufferedReader
2、定义一个变量记住被增强对象
3、定义一个构造器,接收被增强对象
4、覆盖需要增强的方法
5、对于不想增强的方法,直接调用被增强对象(目标对象)的方法
1、编写一个实现tag接口的标签处理器类
public class ViewIPTag implements Tag {
private PageContext pageContext;
public int doStartTag() throws JspException {
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
JspWriter out = pageContext.getOut();
String ip = request.getRemoteAddr();
try {
out.write(ip);
} catch (IOException e) {
throw new RuntimeException(e);
}
return 0;
}
public int doEndTag() throws JspException {
return 0;
}
public Tag getParent() {
return null;
}
public void release() {
}
public void setPageContext(PageContext arg0) {
this.pageContext = arg0;
}
public void setParent(Tag arg0) {
}
}
2、在web-inf/目录下新建tld文件,在tld文件中对标签处理器进行描述
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>A tag library exercising SimpleTag handlers.</description>
<tlib-version>1.0</tlib-version>
<short-name>SimpleTagLibrary</short-name>
<uri>/itcast</uri>
<tag>
<name>viewIP</name> <!-- 为标签处理器类配一个标签名 -->
<tag-class>cn.itcast.web.tag.ViewIPTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
3、在jsp页面中导入并使用自定义标签
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/itcast" prefix="itcast" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>输出客户机的IP</title>
</head>
<body>
您的IP是:<itcast:viewIP/>
</body>
</html>
自定义标签的扩展功能:
控制jsp页面某一部分内容是否执行。
1.编写一个类实现tag接口,控制dostarttag方法的返回值,如果这个方法返回EVAL_BODY_INCLUDE,则执行标签体,如果返回SKIP_BODY,则不执行标签体
控制整个jsp页面是否执行。
2、编写一个类实现tag接口,控制doendtag方法的返回值,如果这个方法返回EVAL_PAGE,则执行标签余下的jsp页面,如果返回SKIP_PAGE,则不执行余下的jsp
控制jsp页面内容重复执行。
3.编写一个类实现Iterationtag接口,控制doAfterBody方法的返回值,如果这个方法返回EVAL_BODY_AGAIN, 则web服务器又执行一次标签体,依次类推,一直执行到doAfterBody方法返回SKIP_BODY,则标签体才不会重复执行。
修改jsp页面内容输出。
4、编写一个类实现BodyTag接口,控制doStartTag方法,返回EVAL_BODY_BUFFERED,则web服务器会创建BodyContent对象捕获标签体,开发人员在doendtag方法体内,得到代表标签体的bodyContent对象,从而就可以对标签体进行修改。。。。。。操作。
简单标签实现页面逻辑
控制jsp页面某一部分内容是否执行。
1.在dotag方法里面不调用jspFrament.invoke方法即可
控制jsp页面内容重复执行。
1.在dotag方法重复调用jspFrament.invoke方法即可
修改jsp页面内容输出
1.在dotag方法调用jspFrament.invoke方法时,让执行结果写一个自定义的缓冲中即可,然后开发人员可以取出缓冲的数据修改输 出
控制整个jsp页面是否执行。
1.在dotag方法抛SKIPPageException即可,jsp收到这个异常,将忽略标签余下jsp页面的执行
E:\Myeclipse10\MyEclipse 10\configuration\org.eclipse.osgi\bundles\16\1\.cp\lib
1、request:如果客户向服务器发请求,产生的数据,用户看完就没用了,像这样的数据就存在request域,像新闻数据,属于用户看完就没用的
2、session:如果客户向服务器发请求,产生的数据,用户用完了等一会儿还有用,像这样的数据就存在session域中,像购物数据,用户需要看到自己购物信息,并且等一会儿,还要用这个购物数据结帐
3、servletContext:如果客户向服务器发请求,产生的数据,用户用完了,还要给其它用户用,像这样的数据就存在servletContext域中,像聊天数据
演示不同隔离级别下的并发问题
1.当把事务的隔离级别设置为read uncommitted时,会引发脏读、不可重复读和虚读
A窗口
set transaction isolation level read uncommitted;
start transaction;
select * from account;
-----发现a帐户是1000元,转到b窗口
select * from account
-----发现a多了100元,这时候a读到了b未提交的数据(脏读)
B窗口
start transaction;
update account set money=money+100 where name='aaa';
-----不要提交,转到a窗口查询
2.当把事务的隔离级别设置为read committed时,会引发不可重复读和虚读,但避免了脏读
A窗口
set transaction isolation level read committed;
start transaction;
select * from account;
-----发现a帐户是1000元,转到b窗口
select * from account;
-----发现a帐户多了100,这时候,a读到了别的事务提交的数据,两次读取a帐户读到的是不同的结果(不可重复读)
B窗口
start transaction;
update account set money=money+100 where name='aaa';
commit;
-----转到a窗口
3.当把事务的隔离级别设置为repeatable read(mysql默认级别)时,会引发虚读,但避免了脏读、不可重复读
A窗口
set transaction isolation level repeatable read;
start transaction;
select * from account;
----发现表有4个记录,转到b窗口
select * from account;
----可能发现表有5条记如,这时候发生了a读取到另外一个事务插入的数据(虚读)
B窗口
start transaction;
insert into account(name,money) values('ggg',1000);
commit;
-----转到 a窗口
4.当把事务的隔离级别设置为Serializable时,会避免所有问题
A窗口
set transaction isolation level Serializable;
start transaction;
select * from account;
-----转到b窗口
B窗口
start transaction;
insert into account(name,money) values('ggg',1000);
-----发现不能插入,只能等待a结束事务才能插入
加入dbcp链接池
1.导入jar包
commons-dbcp-1.2.2.jar commons-pool.jar
2、在类目录下加入dbcp的配置文件:dbcpconfig.properties
3、在jdbcUtils的静态代码块中创建池
private static DataSource ds = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties prop = new Properties();
prop.load(in);
BasicDataSourceFactory factory = new BasicDataSourceFactory();
ds = factory.createDataSource(prop);
System.out.println(ds);
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}