JavaWeb(李兴华著)开发笔记

1.Java语法-基础

环境变量-JAVA_HOME, PATH, ClassPath

变量名

作用

举例

JAVA_HOME

指向JDK目录

C:\Program Files\Java\jdk1.7.0_21

PATH

指向java.exe目录。

%JAVA_HOME%\bin;

%JAVA_HOME%\jre\bin

CLASSPATH

执行.jar文件、zip文件、.class文件所在目录。

(程序要用到哪些.class文件,)

%JAVA_HOME%\lib\dt.jar;

%JAVA_HOME%\lib\tools.jar;

控制语句  99 bottles of beer

public class GoJava2 {

/**

* @param args

*/

public static void main(String[] args) {

int beerNum=99;

String word="bottles";

while(beerNum>1){

System.out.println(beerNum+" "+word+" of beer on the wall");

System.out.println(beerNum+" "+word+" of beer");

System.out.println("Take one down");

System.out.println("pass it around");

beerNum--;

}

if(beerNum==1){

System.out.println(beerNum+" bottle of beer on the wall");

System.out.println("Take one down, no more beers");

}

}

}


guessNumber 游戏

public class
Player {

int number;

public int Guess(){

this.number=(int)(Math.random()*10);

return this.number;

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

Player
p1=new
Player();

Player
p2=new
Player();

Player
p3=new
Player();

boolean continueFlag=true;

int answer=-1;

while(continueFlag){

answer=(int)(Math.random()*10);

int n1=p1.Guess();

int n2=p2.Guess();

int n3=p3.Guess();

System.out.println("answer is:"+answer);

System.out.println("player1 guesses:"+n1);

System.out.println("player2 guesses:"+n2);

System.out.println("player3 guesses:"+n3);

if(n1==answer||n2==answer||n3==answer){

System.out.println("we have a winner among the p1,p2,p3");

continueFlag=false;

}

else{System.out.println("no one guessed the answer,game continue");}

}

System.out.println("p1 guesses:"+(p1.number==answer));

System.out.println("p2 guesses:"+(p2.number==answer));

System.out.println("p2 guesses:"+(p3.number==answer));

}

}

引用变量  遥控 对象

public class
Dog {

String
name;

public void bark(){

System.out.println(this.name+" is barking");

}

/**

* @param args

*/

public static void main(String[] args) {

Dog[] dogs=new Dog[3];

dogs[2]=new Dog();

dogs[0]=new Dog();

dogs[0].name="Fido";

dogs[2]=dogs[0];

dogs[2].bark();

if(dogs[2].name==dogs[0].name){

System.out.println(true);

}

else{

System.out.println(false);

}

}

}

输出:

Fido is barking

true

super()


final

作用:修饰变量

效果:赋值之后 无法改变。

.java文件中放多个类

规则:

最多只能有一个public Class.

如果存在public Class,那么 .java的文件名必须是public
Class的名字

.java-.class-.jar 文件

摘要

类型

说明

.java

写代码写在这文件中

.jar

本质:多个.class文件的压缩包。

如何生成:(1)IDE中Export JAR我那件

(2)winzip将class文件压缩成.jar

.class文件

本质:在java虚拟机中运行的二进制文件

----

如何生成:

step1:进入到.java文件的目录

f:

cd pkgSvt

step2:javac  java文件名

效果:相同位置产生.class文件

如何运行.class文件

step1 
java –cp f:\pkgSvt ClsStrSB //设置classpath,要用哪些class

step2 
cd pkgSvt        //进入父目录

step3 
java ClsStrSB   //执行class 中的 main

Object 
为空判断

判断对象为null

If(obj==null){//为空

}

eclipse导出jar, classpath not found

工程文件夹应该会有个大红感叹号。右击工程文件夹,properties
选择java
build class,查看各选项卡,有红色错误提醒的remove之即可。


数组- List -ArrayList

数组

摘要:直接声明。

指定长度声明。

不可动态改变长度。

String[] IDNUMs={"US100","US120"};

String[] temp=new String[10];

数组随机 专家术语机.

Index:Math.random,  String[] ={},

数组定义:

String[] 
array1={“”,””,””}

public static void
main(String[] args) {

String[]
wordListOne = {"24/7","multi-Tier","30,000
foot","B-to-B","win-win","frontend","web-based","pervasive", "smart", "sixsigma","critical-path", "dynamic"};

String[]
wordListTow={"process","tipping-point","solution","archetecture","core-competency","strategy","mind-care"};

String[]
wordListThree={"toomcat","apache","Linux","nginx"};

String
word1=wordListOne[(int)(Math.random()*wordListOne.length)];

String
word2=wordListTow[(int)(Math.random()*wordListTow.length)];

String
word3=wordListThree[(int)(Math.random()*wordListThree.length)];

for(int
i=0;i<=9;i++){

System.out.println(word1+"
"+word2+" "+word3);

}

}

输出:

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

web-based core-competency apache

List

List<E>([]内的内容可省略),与数组类似:

ArrayList<DisPoint> liPts=new ArrayList<DisPoint>();

while(rs.next()){

DisPoint pt=new DisPoint(rs.getInt("ID"),rs.getString("Name"),rs.getDouble("Longitude"),rs.getDouble("Latitude"));

liPts.add(pt);

              }
 
获得集合内元素个数:list.size();

添加元素:
默认添加:list.add(e);
指定下标添加(添加后下标后的元素向后挪一位):list.add(index,e); 删除元素:
返回是否删除:list.remove(e);
直接删除指定下标的元素(只删除找到的第一个相符合的元素):list.remove(index); 替换元素(替换掉指定下标的元素):list.set(index,e); 取出元素:list.get(index); 清空集合:list.clear(); 判断集合中是否存在某个元素(存在返回true,不存在返回false):list.contains(e); 对比两个集合中的所有元素:
两个对象一定相等:list.equals(list2);
两个对象不一定相等:list.hashCode() == list2.hashCode();
(两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。) 获得元素下标:
元素存在则返回找到的第一个元素的下标,不存在则返回-1:list.indexOf(e);
元素存在则返回找到的最后一个元素的下标,不存在则返回-1:list.lastIndexOf(e); 判断集合是否为空(空则返回true,非空则返回false):list.isEmpty(); 返回Iterator集合对象:list.iterator(); 将集合转换为字符串:list.toString(); 截取集合(从fromIndex开始在toIndex前结束,[fromIndex,toIndex)):list.subList(fromIndex,toIndex); 将集合转换为数组:
默认类型:list.toArray();
指定类型(objects为指定类型的数组对象,并将转换好的数组赋值给objects数组):list.toArray(objects); 以上为List常用的方法。

ArrayList

int数组

ArrayList<Integer> arID=new
ArrayList<Integer>();

ArrayList转Array

public static
Integer[] getUtfAr(String usr,int del){

ArrayList<Integer>
ar=new ArrayList<Integer>();

for(int
i=0;i<=usr.length()-1;i++){

ar.add(usr.codePointAt(i));

}

Integer[]
tm=(Integer[])ar.toArray(new
Integer[ar.size()]);

return tm;

}

2.SVN操作

目标:集成到eclipse, 源代码管理

1.下载 svn.jar包

2.解压到
得到两个目录:

features,plugins

3.将features,plugins拷贝到ecplise/dropins目录下

4.启动eclipse,创建一个workSpace, 例如fareWeb

5.FileàNewàOtheràsvnà从svn检出项目

6.输入url

https://10.254.53.4:8443/svn/bii2ITA/trunk/src/SourceCode/fareWeb

用户名:gaoxk

密码:gaoxk123

3. 测试-调试

在java classc测试- main函数

public static void
main(String[] args) {

Crud crud=new
Crud();

Employee emp=new
Employee("孔卡",26,"足球运动员");

Employee inserted=crud.insertOne(emp);

crud.printOne(inserted);

inserted.Name="穆里奇";

Employee updated=crud.updateOne(inserted);

crud.printOne(updated);

crud.showAll();

crud.deleteRecs(updated.id);

}

查看方法执行时间

System.out.println("getCond时间:"+((new
Date()).getTime()-now.getTime()));

System.out.println 调试

描述:控制台输出

参数:string

举例

System.out.println(“hello world”)

如何查看变量的值

1>   
进入Debug View

2>   
Window àShow View Expressions

3>   
在Name中添加变量名/.变量值,Value中查看值

如何查看类型的所有方法/属性  (API Documentation)

1>   
鼠标放到类型上,按F2, Open Javadoc
in Browser

获取离线JavaSE Documentation

1>   
网页版

访问Oracle.com, JavaSE 下载页面,页面靠下的部分有 Java SE Documentation下载,是一个网站(Zip包)

2.>Chm版

在baidu上搜 Java SE API Chm。

使用正则查找/替换

需求:

在 edit.html中 ,draw***();替换成空

譬如:

drawPeoples(); drawGender();

正则表达式

draw[a-zA-Z]+\(\);

Tomcat

目录结构

序号

目录名

描述

1

bin

可运行程序目录。start,shutdown在此目录下。

2

lib

放jar包

3

conf

放配置文件

4

logs

存放日志文件

5

webapps

web项目(war包)在此即发布

6

work

临时目录,jsp生成 .java文件将在此

端口号设置

http端口

conf/server.xml

<Connector
port="8080" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443"
/>

SSL端口

<Connector port="8443"
protocol="HTTP/1.1" SSLEnabled="true"

maxThreads="150"
scheme="https" secure="true"

clientAuth="false" sslProtocol="TLS"
/>

-->

AJP端口

<Connector port="8009"
protocol="AJP/1.3" redirectPort="8443" />


role和用户配置 tomcat-users.xml

用途:管理用户

(设置某个web的jsp权限)

字段:

举例:

打开conf/tomcat-users.xml

添加两个role,两个 user

<role rolename="admin"/>

<role rolename="guest"/>

<user username="admin"
password="admin" roles="admin"/>

<user username="guest"
password="guest" roles="guest"/>

创建虚拟目录

原则:每一个虚拟目录存放一个Web项目

步骤

序号

详细

概要

1

在硬盘上建立目录,并在目录中建立WEB-INF目录

创建虚拟目录

2

将tomcat/webapps/Root/web.xml拷贝到WEB-INF目录下

添加配置文件web.xml

3

<Host>

......

<Context path=”/test1” docBase=”E:\test1”></Context>

......

</Host>

将虚拟目录关联到conf/server.xml

4

在test1下写 index.jsp:

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<h1><%
out.println("Hello,JSP World");%></h1>

</body>

</html>

启动tomcat,访问地址

localhost/test1/

测试

第一个JSP

在已关联的虚拟目录下创建index.jsp,内容如下:

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<h1><% out.println("Hello,JSP
World");%></h1>

</body>

</html>

效果:


虚拟目录/WEB-INF/web.xml

web.xml中的路径符号

url-pattern

说明

实际地址

su

无法启动

../su

不允许../ 服务器无法启动

/su

虚拟目录/su

http://localhost/UI05/su

页面form 的路径

sample1.htm

pattern

说明

实际地址

<form action="su"

与页面同级的su

http://localhost/UI05/su

<form action="../su"

页面父目录的su

http://localhost
/su

Web标准目录结构

WEB-INF必须存在

要点:

(1)虚拟目录下必须存在WEB-INF目录。 WEB-INF必须包好web.xml文件。

(2)by default, internet用户无权限访问WEB-INF下的内容。

(3)不想被浏览器直接访问的页面,放在WEB-INF下。增强安全

web.xml  jsp映射

摘要:

<servlet>

<servlet-name></servlet-name>

<jsp-file></jsp-file>

</servlet>

<servlet-mapping>

<servlet-name></servlet-name>

<url-pattern></
url-pattern>

</servlet-mapping>

jsp映射

<servlet>

<servlet-name>serA</servlet-name><!--servlet-name only
works inside web.xml,to connect JSP-FILE with URL-PATTERN-->

<jsp-file>/test.jsp</jsp-file><!--JSP-FILE-->

</servlet>

<servlet-mapping>

<servlet-name>serA</servlet-name>

<url-pattern>/hello</url-pattern><!--URL-PATTERN-->

</servlet-mapping>

web.xml servlet映射

servlet映射

摘要:

<servlet>

<servlet-name></servlet-name>

<servlet-class></servlet-class>

</servlet>

<servlet-mapping>

<servlet-name></servlet-name>

<url-pattern></
url-pattern>

</servlet-mapping>

摘要:使用通配符 *

<web-app>

<servlet>

<servlet-name>SvtHello</servlet-name>

<servlet-class>pkgResiCrud.SvtHello</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>SvtHello</servlet-name>

<url-pattern>/hello/*</url-pattern>

</servlet-mapping>

</web-app>

init-param配置 驱动-dburl-用户名-密码

在web.xml中

注意:

(1)要放在servlet标签下

(2)客户端请求url-pattern时,getInitParameter生效。

客户端直接请求jsp时, getInitParameter取值为null.

<servlet>

<init-param>

<param-name>DbDriver</param-name>

<param-value>oracle.jdbc.driver.OracleDriver</param-value>

</init-param>

<servlet-name>serA</servlet-name>

<jsp-file>/test.jsp</jsp-file>

</servlet>

<servlet-mapping>

<servlet-name>serA</servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

在JSP页面中:

以config.getInitParameter(“”)获取参数值


<error-page> 设置出错处理页面

<error-page>

<error-code>404</error-code>

<location>error.jsp</location>

<error-code>500</error-code>

<location>error.jsp</location>

</error-page>

</web-app>

效果:

index.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<h2>index.jsp</h2>

<%int result=10/0;%>

服务端跳转:

error.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<h2>页面发生了错误...</h2>

<a href="index.jsp">点击此处返回主页面</a>

备注:with
web.xml,即使没有<%@
page isErrorPage=”true”%>,it still works


security-contraint页面权限

备注:GET和Post Request都要求验证

前件:要在tomcat-users.xml中 添加role,和role类的用户

效果:访问页面需要输入用户名密码

用途:保护管理员页面

密码传输方式:不是明文

配置方式:

<security-constraint><!--page
and roles-->

<web-resource-collection><!--pages
are protected-->

<url-pattern>/check.jsp</url-pattern>

</web-resource-collection>

<auth-constraint><!--allowed
roles-->

<role-name>admin</role-name><!--must-->

</auth-constraint>

</security-constraint>

<login-config><!--Login
form for validation-->

<auth-method>BASIC</auth-method>

</login-config>

<security-role><!--withoud
this,warning appears when start-->

<role-name>admin</role-name>

</security-role>

</web-app>

JSP

第一个JSP

<%@ page language=”Java” contentType=”text/html;charset=utf-8”%>

<h1><%out.println("hello
world");%></h1>

访问:

http://localhost:8080/UI05/html/first.jsp

效果:

...

结论:

(1)jsp文件,可以不写<!DOCTYPE><head><body>

JSP本质是 java类

JSP文件最终都是以.java文件在服务端执行

后果:

(1)第一次访问.jsp比第二次之后慢

(2)访问后在硬盘上生成.java文件

第一个交互表单

在虚拟目录下创建
index.jsp和index.html

index.html:

<!DOCTYPE HTML>

<html>

<head></head>

<body>

<form action='index.jsp'>

<input type="text"
name="info" value=""/><input type="submit"
value="提交"/>

</form>

</body>

</html>

index.jsp:

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<h1><%
out.println(request.getParameter("info"));%></h1>

</body>

</html>

访问:index.html

点击提交:


基础语法

注释符号

序号

举例

1

<%-- out.println(“hello world”);--%>

2

<% //out.println(“hello world”);%>

3

<% /*out.println(“hello world”);*/
%>

java语句标签

作用:java语句要写在 java语句标签内。

备注:不要将指令写在语句标签内

序号

举例

说明

1

<%!public String HelloWorld(){

return “hello world”;

}%>

作用:

定义 类,方法,全局变量。

(备注:

不要在JSP中定义方法,类。

在JavaClass中定义。)

2

<% String one=”hello world”;

out.println(one);

%>

执行语句。

3

<%=one%>

获取变量。

(备注:

不要在<%=%>中添加注释)

4

<jsp:scriptlet></jsp:scriptlet>

举例:

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

</head>

<body>

<%!public String helloWorld(){

return
"hello world";

};//定义方法%>

<%String one="one";//定义变量%>

<h1><%=helloWorld()%></h1>

<h2><%=one%><%//取变量%></h2>

</body>

</html>


out.print vs <%=%>

<%=%> 称作
表达式输出。

结论:

使用<%=%> 取代<%out.println()%>

好处(1)效率高

(2)html代码和 java代码分离


if else写法

正确:

<%if(info.equals("true")){%>

<jsp:forward
page="success.jsp">

<jsp:param name="info"
value="<%=paraU%>"></jsp:param>

</jsp:forward>

<%}else{%>

错误:

 

<%if(info.equals("true")){%>

<jsp:forward
page="success.jsp">

<jsp:param name="info"
value="<%=paraU%>"></jsp:param>

</jsp:forward>

<%}%>

<%else{%>

Page指令索引

常用的4种:

contentType , pageEncoding, errorPage ,import,


Page import指令

导入Jar包

备注:1个page指令 只能由1个import,1个import只能导1个jar

<%@ page
contentType="text/html;" pageEncoding="GBK"
import="java.util.*"%>

<%@ page
import="java.io.*"%> <%// one page Dir can only import one
jar%>

<%@ page
import="java.math.*"%>

Page pageEncoding=”GBK” 显示中文

<%@ page
language="Java" contentType="text/html;"
pageEncoding="GBK"%><%//jsp要显示中文%>

<table border=1>

<tr><td>序号</td><td>名称</td><td>描述</td></tr>

</table>

Page指令contentType 显示html

contentType=”mimeType;”

举例

Mime类型

contentType=”text/html;”

text/html

<%@ Page language="Java"
contentType="text/html; "%>

 

Page contentType vs response.setHeader控制编码

Page设置 Content-Type 正常

 

<%@ page language="Java"
contentType="text/html;" pageEncoding=”GBK”%>

<table border="1"
cellpadding=0 cellspacing=0>

<tr><td>序号</td><td>名称</td><td>描述</td><tr>

</table>

setHeader-ContentType乱码

<%@ page language="Java"%>

<%response.setHeader("Content-Type","text/html;charset=GBK");%>

<table border="1"
cellpadding=0 cellspacing=0>

<tr><td>序号</td><td>名称</td><td>描述</td><tr>

</table>

结论:

 JSP页面编码,使用Page指令,不用response.setHeader


Page指令 设置出错页

show.jsp:

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<%@ page language="Java"
errorPage="error.jsp"%>

<h2>index.jsp</h2>

<%int result=10/0;%>

error.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<%@ page
isErrorPage="true"%><%//此页可处理错误%>

<h2>页面发生了错误...</h2>

<a href="index.jsp">点击此处返回主页面</a>

效果:

特点:

服务端跳转(客户端只发送了一次请求。服务端执行了另一个页面的代码)


Include指令
包含jsp,htm文件

原理:所有file被included into index.jsp,再编译

应用:

index.jsp:

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<%@include file="left.htm"%>

<%@include file="middle.htm"%>

<%@include
file="right.htm"%>

left.htm

<div style="display:inline-block;
width:300px;">

<h1>We<h1>

</div>

middle.htm

<div style="display:inline-block;
width:300px;">

<h1> are cellestial<h1>

</div>

right.htm

<div style="display:inline-block;
width:300px;">

<h1> man<h1>

</div>

效果:


jsp:include指令
动态包含

区别:各部分被分别编译,然后包含

jsp:forward指令 跳转


jsp实现登录功能

login.htm

<!DOCTYPE HTML>

<html>

<head></head>

<body>

<center>

<form
action="login_check.jsp">

<table
cellspacing=0 cellpadding=0 style="border-collapse:collapse;border:1px
solid rgb(0,0,0);">

<tr><td
colspan=2>登录系统</td><td></td></tr>

<tr><td>用户名:</td><td><input
type="text" name="usr" /></td></tr>

<tr><td>密码:</td><td><input
type="text" name="psw" /></td></tr>

<tr><td
colspan=2><input type="submit" value="登录" /><input
type="reset" value="重置"></td><td></td></tr>

</table>

</form>

</center>

</body>

</html>

login_check.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<%@ page
import="java.sql.*"%>

<%

final String DbDriver="oracle.jdbc.driver.OracleDriver";

final String DbUrl="jdbc:oracle:thin:@localhost:1521:orcl";

final String Usr="test";

final String Psw="test";

String paraU=request.getParameter("usr");

String paraP=request.getParameter("psw");

Class.forName(DbDriver);

Connection conn=DriverManager.getConnection(DbUrl,Usr,Psw);

Statement stmt=conn.createStatement();

String sqlStr="select usr, psw from account";

String info="false";

ResultSet rs=stmt.executeQuery(sqlStr);

while (rs.next()){

if(rs.getString("usr").equals(paraU)){

if(rs.getString("psw").equals(paraP)){

info="true";

}

else{

info="invalid password";

}

}

else{

continue;

}

}

info=info.equals("false")?"user does not
exist":info;

rs.close();

stmt.close();

conn.close();

%>

<%if(info.equals("true")){%>

<jsp:forward
page="success.jsp">

<jsp:param name="info"
value="<%=paraU%>"></jsp:param>

</jsp:forward>

<%}else{%>

<jsp:forward
page="fail.jsp">

<jsp:param
name="info" value="<%=info%>"></jsp:param>

</jsp:forward>

<%}%>

success.jsp

<%@ page
contentType="text/html;charset=GBK"%>

<h1>You're
Welcome,<%=request.getParameter("info")%></h1>


fail.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<h1>登录失败...<%=request.getParameter("info")%></h1>

<a href="login.htm">返回登录页</a>

效果


服务端跳转 和 客户端跳转

代码

浏览器效果

服务端跳转

<jsp:forward page=”other.jsp”></>

地址栏未改变

客户端跳转

<a href=<%=loc2%> />

地址栏变化

效率:服务端跳转高


JSP 内置对象索引

常用5个:request, response, pageContext, session,
application

作用范围 request , session,
application


page 范围

用途:

jsp页面内存取变量

范围:

在当前jsp页面中有效

失效情况(any)

<jsp:
forward=”page2.jsp”></jsp:forward>


request 范围

特点:

比page略长,服务器端跳转后
依然有效;

客户端跳转后,无效

举例-服务端跳转,有效

request_01.jsp

request_02.jsp

request-客户端跳转

requst_01.jsp


session 范围

特点:session.setAttribute(“info”,”Juptor
Mind”)执行

如果不关闭浏览器,则Webapp下其它页面都可取

无法取得:

浏览器关闭后

举例:

session_01.jsp

session_02.jsp

application 范围

特点:存在服务器上。所有session都可存取

中止:服务器重启

举例:

application_1.jsp

application_2.jsp


request 范围实验(DIY)

req1.jsp

<%@ page language="java"
contentType="text/html;charset=GBK"%>

<title>Req1.jsp</title>

<%request.setAttribute("info","Jupitor
mind");%>

<span>request.getAttribute("info")=<%=request.getAttribute("info")%></span>

<a href="req2.jsp">anchor
to req2.jsp</a></br><%//prove 客户端跳转%>

<jsp:forward
page="req2.jsp"></jsp:forward> <%//prove 服务端跳转.进行
服务端跳转,请去除此语句%>

req2.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<title>req2.jsp</title>

<span>request.getAttribute("info")
is:<b><%=request.getAttribute("info")%></b></span>

session范围实验(DIY)

req1.jsp

<%@ page language="java"
contentType="text/html;charset=GBK"%>

<title>Req1.jsp</title>

<%session.setAttribute("info","Jupitor
mind");%>

<span>session.getAttribute("info")
is:<b><%=session.getAttribute("info")%></b></span></br>

<a href="req2.jsp">click to
req2.jsp</a>

req2.jsp

<%@ page language="Java"
contentType="text/html;charset=GBK"%>

<title>req2.jsp</title>

<span>session.getAttribute("info")
is:<b><%=session.getAttribute("info")%></b></span>


HttpServletRequest对象

备注:

JSP页面和Servlet中的request都是HttpServletRequest类型。

setCharacterEncoding
解析中文

应用:客户端发送未编码的中字,先使用此方法,否则乱码

实验

check.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%><%//jsp要显示中文%>

<%

request.setCharacterEncoding("GBK");
//解析中文字符串

String
usr=request.getParameter("usr");

%>

usr:<%=usr%>

login.htm

<!DOCTYPE HTML>

<html>

<head><meta
content-type="text/html;charset=utf-8"></head>

<body>

<form action="check.jsp"
method="post">

<table><tr><td>用户名:</td><td><input type="text"
name="usr" value="his name is 木星意志"/></td></tr>

<tr><td
colspan=2><input type="submit" value="提交"></td><td></td></tr>

</table>

</form>

</body>

</html>

getParameter(name) 取一个value


getParameterValues(name) 获取同name标签values

背景:任何两个html标签允许同名。

login.htm

<!DOCTYPE HTML>

<html>

<head><meta
content-type="text/html;charset=utf-8"></head>

<body>

<form action="check.jsp"
method="post">

<table>

<tr><td>姓名</td><td>

<input
type="text" name="name" value="木星"/>

<input
type="text" name="name" value=""/>

</td></tr>

<tr><td>爱好</td>

<td>

游泳<input
type="checkbox" name="inter" value="游泳"/>

篮球<input
type="checkbox" name="inter" value="篮球"/>

神风<input
type="checkbox" name="inter" value="神风"/>

</td>

</tr>

<tr><td
colspan=2><input type="submit" value="提交"/></td><td></td></tr>

</table>

</form>

</body>

</html>


check.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%><%//jsp要显示中文%>

<%

request.setCharacterEncoding("GBK");
//解析中文字符串

String[]
names=request.getParameterValues("name");

String[]
inters=request.getParameterValues("inter");

%>

<%

if(names!=null){

for(int i=0;i<=names.length-1;i++){%>

name[<%=i%>]:<%=names[i]%></br>

<%}}%>

<%if(inters!=null){

for(int i=0;i<=inters.length-1;i++){

%>

interest[<%=i%>]:<%=inters[i]%>

<%}}%>

getParameterNames取所有name

用途:获取所有传入参数

举例:获取复选框项

适用于:存在复选框时

拓展:查询条件组合,购物车

login.html

<!DOCTYPE HTML>

<html>

<head><meta
content-type="text/html;charset=utf-8"></head>

<body>

<form action="check.jsp"
method="post">

<table>

<tr><td>姓名</td><td>

<input
type="text" name="name" value="木星"/>

</td></tr>

<tr><td>邮箱</td><td>

<input
type="text" name="mail"
value="1695539064@qq.com"/>

</td></tr>

<tr><td>爱好</td>

<td>

游泳<input
type="checkbox" name="inter" value="游泳"/>

篮球<input
type="checkbox" name="inter" value="篮球"/>

神风<input
type="checkbox" name="inter" value="神风"/>

</td>

</tr>

<tr><td
colspan=2><input type="submit" value="提交"/></td><td></td></tr>

</table>

</form>

</body>

</html>

check.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%><%//jsp要显示中文%>

<%@ page
import="java.util.*"%>

<%

request.setCharacterEncoding("GBK");
//解析中文字符串

Enumeration
pNames=request.getParameterNames();    //取所有names

while(pNames.hasMoreElements()){//遍历names

String
pName=(String)pNames.nextElement();

%>

参数名:<%=pName%>,参数值:<%String[] values=request.getParameterValues(pName);//retrive
values of one Name

for(int
i=0;i<=values.length-1;i++){%>

<%=values[i]%><span>  </span>

<%}

%></br>

<%}%>

效果:

 


Header Cookie, agent, IP , referer,method

举例:遍历request头信息

<%@ page language="Java"
contentType="text/html" pageEncoding="GBK"
import="java.util.*"%>

<%

Enumeration items=request.getHeaderNames();

%>

method:<%=request.getMethod()%></br>

clientIP:<%=request.getRemoteAddr()%></br>

<%while(items.hasMoreElements()){

String hName=(String)items.nextElement();

String value=(String)
request.getHeader(hName);

%>

<%=hName%>:<%=value%></br>

<%}%>

clientIP:127.0.0.1
host:localhost
connection:keep-alive
content-length:80
cache-control:max-age=0
accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
origin:http://localhost
user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/28.0.1500.72 Safari/537.36
content-type:application/x-www-form-urlencoded
referer:http://localhost/test1/login.htm
accept-encoding:gzip,deflate,sdch
accept-language:zh-CN,zh;q=0.8
cookie:JSESSIONID=816945B50F0C1130B0E00C99B90F731C

判断role类型

前提:

(1)在tomcat-users.xml中添加了role和user

(2)在虚拟目录-web.xml中配置security-constraint,login-config,security-role

效果:

login验证通过后,retrive用户role.(不是username)

<%@ page language="Java"
contentType="text/html" pageEncoding="GBK"%>

<%if(request.isUserInRole("admin")){%>

Welcome,<b>Role admin</b>

<%}%>

getContextPath()
获取应用名

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

host:<b><%=request.getHeader("host")%></b></br>

ContextPath:<b><%=request.getContextPath()%></b></br>

ServletPath:<b><%=request.getServletPath()%></b>

getServletPath() 取应用名之后部分


getCoockies()  Cookies[]

HttpServletReponse对象

备注:JSP页面和Servlet中的request都是HttpServletRequest类型。

setHeader(“refresh”) 定时跳转

摘要:setHeader(“refresh”,”3;url=login.htm”)

备注:客户端跳转

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<%response.setHeader("refresh","3;url=login.htm");%><%//setHeader("refresh","2;url="),客户端跳转%>

3秒钟后将跳转到login.htm...

sendRedirect  客户端跳转

备注:客户端跳转

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<%response.sendRedirect("login.htm");%>

response.setHeader
保存word

页面:

<%@ page language="Java"
pageEncoding="GBK"%>

<%response.setHeader("Content-Disposition","attachment;filename=test.doc");%>

<table border="1">

<tr><td>序号</td><td>名称</td><td>描述</td><tr>

</table>

Mime设置:

打开conf/web.xml,

确认一下mime-mapping存在

<mime-mapping>

<extension>dot</extension>

<mime-type>application/msword</mime-type>

</mime-mapping>

效果:页面不打开,直接下载

byte[]返回文件 (下载)

InputStream inStream=null;

//全部

try {

inStream=ResiCrud.createExcel(filePath);

} catch
(ClassNotFoundException | WriteException

|
SQLException e) {

// TODO
Auto-generated catch block

e.printStackTrace();

}

response.reset();

response.setHeader("Content-Disposition",
"attachment;filename=" +response.encodeURL(fileUrl));

response.setContentType("application/octet-stream");

byte[] fileBytes=new byte[1024];

int length=0;

while((length=inStream.read(fileBytes))>0){

response.getOutputStream().write(fileBytes,0,length);

}

response.flushBuffer();

response.getOutputStream().close();

inStream.close();

return;


response返回文本数据

(1)  
response.getOutputStream.write二进制流

//设置 数据编码

response.setHeader("Content-type", "text/plain;charset=utf-8");

String
result="hello World";

//传送 二进制数组,将字符串以 utf-8变成 二进制数组

response.getOutputStream().write(result.getBytes("utf-8"));

(2)response.getWriter.write() 字符串

response.setHeader("Content-type","text/html;charset=UTF-8");

PrintWriter writer =
response.getWriter();

writer.write("中国");

Cookie对象

意义:Cookie生存在客户端上。常用于存放用户名密码等信息。

在周期满后,会被清除。浏览器执行清空Cookie操作后,也被清除。

个数限制:最多300个

Cookie 索引

命名空间:javax.Servlet.http.Cookie

response.addCookie 添加Cookie

模拟登录,Cookie遍历,添加,

摘要:

取所有Cookies

Cookie[]
cos=request.getCookies();

遍历Cookies

for(int
i=0;i<=cos.length-1;i++){

String coName=cos[i].getName();

String coVal=cos[i].getValue();

}

设置Cookies时长

coName.setMaxAge(600);//十分钟

客户端 延时跳转

response.setHeader(“refresh”,”3;url=login.jsp”)

客户端 立即跳转

reponse.sendRedirect(“login.jsp”)

login.jsp

<%@ page
language="Java" pageEncoding="GBK"
contentType="text/html"%>

<%

Cookie[] cos=request.getCookies();

String usr=null;

String psw=null;

%>

<%if(cos!=null){

for(int
i=0;i<=cos.length-1;i++){

if(cos[i].getName().equals("usr")){

usr=cos[i].getValue();

}

if(cos[i].getName().equals("psw")){

psw=cos[i].getValue();

}

}

if(usr!=null&&psw!=null){%>

<jsp:forward
page="index.jsp"></jsp:forward><%--服务端跳转--%>

<%}%>

<%}%>

<!DOCTYPE
HTML>

<html>

<head><meta
content-type="text/html;charset=utf-8"></head>

<body>

<form action="check.jsp"
method="post">

<table>

<tr><td colspan=2>登录系统</td><td></td></tr>

<tr><td>用户名</td><td><input type="text"
name="usr"/></td></tr>

<tr><td>密码</td><td><input type="text"
name="psw"/></td></tr>

<tr><td
colspan=2><input type="submit" value="登录"></td><td></td></tr>

</table>

</form>

</body>

</html>

check.jsp

<%@ page language="Java" contentType="text/html;"
pageEncoding="GBK"%>

<%

String
usr=request.getParameter("usr");

String
psw=request.getParameter("psw");

String
info="用户名不存在";

if(usr.equals("test")){

if(psw.equals("test")){

info="true";

}

else{info="密码无效";}

}

%>

<%

if(info=="true"){

Cookie
cName=new Cookie("usr",usr);

Cookie
cPsw=new Cookie("psw",psw);

response.addCookie(cName);

response.addCookie(cPsw);

response.sendRedirect("index.jsp");

}

else{%>

<%=info%>,<a
href="login.htm">请重新登录</a>

<%}%>

index.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<%

Cookie[] cos=request.getCookies();//取所有Cookie

String usr=null;

String psw=null;

for(int i=0;i<=cos.length-1;i++){

if(cos[i].getName().equals("usr")){//取用户名Cookie

usr=cos[i].getValue();

}

%>

CookieName:<%=cos[i].getName()%>,Value:<%=cos[i].getValue()%></br>

<%}%>

<%if(usr!=null){%>

欢迎你,<b><%=usr%></b>

<%}else{%>

请先登录,<a
href="login.htm">点此前往登录页</a>

<%}%>

Cookie.setMaxAge 存在时间

背景:

不设置Cookie时间,则浏览器关闭后,Cookie被清空。

co.setMaxAge(600)
,Cookie存在10分钟

check.jsp

 

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<%

String
usr=request.getParameter("usr");

String
psw=request.getParameter("psw");

String
info="用户名不存在";

if(usr.equals("test")){

if(psw.equals("test")){

info="true";

}

else{info="密码无效";}

}

%>

<%

if(info=="true"){

Cookie
cName=new Cookie("usr",usr);

cName.setMaxAge(600);

Cookie
cPsw=new Cookie("psw",psw);

cPsw.setMaxAge(600);

response.addCookie(cName);

response.addCookie(cPsw);

response.sendRedirect("index.jsp");

}

else{%>

<%=info%>,<a
href="login.htm">请重新登录</a>

<%}%>

Session对象

应用:用户登录-注销

生存周期:浏览器关闭。

为啥发明session:

客户端访问服务器,服务器产生唯一的SessionID,用于 标记一次访问

专门用于身份验证。

命名空间:javax.servlet.http.HttpSession

sessionID产生和 获取

产生:服务端收到request之后,即产生session

获取:session.getId();

或者request.getCookies[“JSESSIONID”]

在客户端,sessionID被存储在Cookie中

session登录和注销

评定:

类别

思路

比较

Cookies进行登录校验

(1)login.jsp中,遍历Cookies,判断usr是否存在。

不存在,进行登录àreponse.AddCookie(“usrid”,usr)

à跳转到index.jsp,index.jsp中取Cookie(“usrid”),存在,则允许访问;不存在,则跳转到登录页

不存在à登录

可设置时间长度。

Session进行登录校验

(1)login.jsp中,

session.getAttribute(“usrid”)存在

则跳转到index.jsp页;

不存在,则进行验证。验证完成

session.setAttribute(“usrid”)。跳转到页面index.jsp

比Cookie少一次遍历。

摘要:

设置session

session.setAttribute(“uid”,usrName)

获取session

session.getAttribute(“uid”)

清空session(注销)

session.invalidate()

客户端 延时跳转

response.setHeader(“refresh”,”3;url=login.jsp”)

客户端 立即跳转

reponse.sendRedirect(“login.jsp”)

代码:

login.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<form action="login.jsp"
method="post">

<table>

<tr><td colspan=2>登录系统</td><td></td></tr>

<tr><td>用户名</td><td><input
type="text" name="usr"></td></tr>

<tr><td>密码</td><td><input
type="password" name="psw"/></td></tr>

<tr><td colspan=2><input
type="submit" value="登录"></td><td></td></tr>

</table>

</form>

<%
if(session.getAttribute("uid")!=null){

response.addHeader("refresh","index.jsp;");

}

String usr=request.getParameter("usr");

String psw=request.getParameter("psw");

String info="";

if(usr!=null){

if(usr.equals("test")){

if(psw.equals("test")){

info="true";

}

else{

info="密码无效";

}

}

else{info="用户名不存在";  }

if(info.equals("true")){

session.setAttribute("uid",usr);

response.sendRedirect("index.jsp");

}

else{%>

<b><%=info%></b>

<%}

}%>

index.jsp

<%@ page language="Java"
contentType="text/html;" pageEncoding="GBK"%>

<%//注销分支

String
t=request.getParameter("t");

if(t!=null&&t.equals("0")){

session.invalidate();

response.sendRedirect("login.jsp");

return;

}

%>

<% //校验分支

String
uid=(String)session.getAttribute("uid");

if(uid==null){

response.setHeader("refresh","3;url=login.jsp");%>

<b>尚未登录系统..

<span
id="spT">3</span>

<script
type="text/javascript">

var
count=2;

setInterval(function(){

document.getElementById("spT").innerHTML=count;

count--;

},1000);

</script>s后跳转到登录页</b></br><a
href="login.jsp">点击登录系统</a>

<%}else{%>

<b>欢迎,<%=uid%></b></br>

<a
href="index.jsp?t=0">点击此处注销</a>

<%}

%>

4种会话跟踪

表单隐藏 和 地址重写 不安全。

结论:使用session 活着Cookie进行 会话跟踪。

session记录 用户的登录
注销时间

摘要:

session建立的时间

session.getCreationTime()

session结束的时间

session.getLastAccessedTime()

<%@ page
contentType="text/html;" pageEncoding="GBK"%>

<%

long
start=session.getCreationTime();

long
end=session.getLastAccessedTime();

long
time=(end-start)/1000;

response.setHeader("refresh","1;url=test.jsp");

%>

您已经在页面上提留了<%=time%>秒


isNew()判断新session

application对象(this.getServerletContext)

所属类:javax.servlet.ServletContext

备注:this.getServletContext()
等价于application

代表:整个虚拟目录 (test1)

取虚拟目录绝对路径

摘要:

this.getServletContext().getRealPath("/")

<%@ page
contentType="text/html;" pageEncoding="GBK"%>

虚拟目录绝对路径:<%=this.getServletContext().getRealPath("/")%></br>


写文件内容

摘要:

引用的jar

import=”java.io.*”

初始化File对象

File file=new File(path)

判断目录存在

file.getParentFile().exists()

创建目录

file.getParentFile().mkdir()

写入内容

PrintStream ps=new PrintStream(new
FileOutputStream(file));

ps.println(fC);

ps.close();

fos.close();

代码:

test.jsp

<%@ page contentType="text/html;"
pageEncoding="GBK"%>

<form action="file.jsp"
method="post">

<table>

<tr><td>输入文件名</td><td><input
type="text" name="fNa"
value="file.txt"></td></tr>

<tr><td>文件内容</td><td><textarea
name="fCo"
style="height:200px"></textarea></td></tr>

<tr><td
colspan=2><input type="submit" value="保存"><input
type="reset" value="清空"></td><td></td></tr>

</table>

</form>

<%%>

file.jsp

<%@ page
contentType="text/html;" pageEncoding="GBK"
import="java.io.*"%>

<%

request.setCharacterEncoding("GBK");

String
fN=request.getParameter("fNa");

String
fC=request.getParameter("fCo");

String
fPath=this.getServletContext().getRealPath("/")+"\\files\\"+fN;

File
file=new File(fPath);

if(!file.getParentFile().exists()){

file.getParentFile().mkdir();

}

FileOutputStream
fos=new FileOutputStream(file);

PrintStream ps=new PrintStream(fos);

ps.println(fC);

ps.close();

fos.close();

%>

fN:<%=fN%></br>

fC:<%=fC%></br>

fPath:<%=fPath%></br>


读文件

摘要:

FileInputStream存文件内容

FieInputStream fiStr=

new
FileInputStream(this.getServletContext().getRealPath("/")+"\\files\\file.txt")

Scanner逐行取FileInputStream

Scanner scan=new Scanner(fiStr)

遍历Scan,内容存到String中

String co="";

while(scan.hasNext()){//逐行读取

co+=scan.next();

}

scan.close();

fis.close();

备注:

文件内容过长时,使用

StringBuffer  buf=new StringBuffer();

buf.append(scan.next());

test.jsp

<%@ page
contentType="text/html;" pageEncoding="GBK"
import="java.util.*" import="java.io.*"%>

<%

FileInputStream fis=new FileInputStream(this.getServletContext().getRealPath("/")+"\\files\\file.txt")

Scanner scan=new Scanner(fis);

scan.useDelimiter("\n");//使用换行符

StringBuffer
buf=new StringBuffer();

while(scan.hasNext()){//逐行读取

buf.append(scan.next());

}

scan.close();

fis.close();

%>

<form action="file.jsp"
method="post">

<table>

<tr><td>文件内容</td><td><textarea
name="fCo"
style="height:200px"><%=buf%></textarea></td></tr>

<tr><td
colspan=2><input type="submit" value="保存"><input
type="reset" value="清空"></td><td></td></tr>

</table>

</form>

<%%>

效果

访量计数器

思路:

访客总数写到count.txt中

每当session.isNew()时,打开count.txt,取数并加1,保存,返回新数。

摘要:

调试方法,在eclipse的console下进行。比用哪日志快2h

读文件和写文件

BigInteger 来记录数值

test.jsp

<%@ page
contentType="text/html;" pageEncoding="GBK" import="java.util.*"%>

<%@ include
file="fOper.jsp"%>

<%

String
path=this.getServletContext().getRealPath("/")+"\\files\\count.txt";

BigInteger
newNum;

if(session.isNew()){

synchronized(this){//同步操作,原因不详

newNum=load(path);

newNum=newNum.add(new
BigInteger("1"));

save(path,newNum);

}

}

else{

newNum=load(path);

}

%>

您是第<b><%=newNum%></b>个访;

fOper.jsp

<%@ page pageEncoding="GBK"
import="java.io.*"%>

<%@ page
import="java.util.*"%>

<%@ page
import="java.math.BigInteger"%>

<%!

public
static void save(String path,BigInteger count){

try{

FileOutputStream fos=new
FileOutputStream(path);

PrintStream ps=new PrintStream(fos);

ps.println(count);

ps.close();

fos.close();

}

catch(Exception e){

e.printStackTrace();

return;

}

}

//测试,在eclipse下进行.

public static BigInteger load(String path){

try{

FileInputStream
fis=new FileInputStream(path);

Scanner
scan=new Scanner(fis);

scan.useDelimiter("\n");//使用换行符

BigInteger
count=new BigInteger("0"); //can't use 0 for para

while(scan.hasNext()){//逐行读取

count=new
BigInteger(scan.nextLine().trim());

}

scan.close();

fis.close();

return
count;

}

catch(Exception
e){

e.printStackTrace();

return
new BigInteger("0");

}

}

%>

getAttributeNames 遍历属性

摘要:

获取AttrNames

this.getServletContext().getAttributeNames()

Enumeration

获取某个attr的值

this.getServletContext().getAttribute(name)

<%@ page
contentType="text/html;" pageEncoding="GBK"%>

<%@ page import="java.util.*"%>

<%

Enumeration es=this.getServletContext().getAttributeNames();

while(es.hasMoreElements()){

String
na=(String)es.nextElement();

%>

Name:<%=na%>,Value:<%=this.getServletContext().getAttribute(na)%></br>

<%}%>

config对象

命名空间:javax.servlet.ServletConfig

代表:web.xml对象的init-param

取DbDriver,
DbUrl, usr, psw. 参见 web.xml配置

PageContext对象

pageContext的等价操作

page.Context

相同

pageContext.forward("login.jsp");

<jsp:forward
page="login.jsp"></jsp:forward>

pageContext.include("login.jsp");

<jsp:include
page="login.jsp"></jsp:include>

pageContext.getServletConfig()

config

不等价

pageContext.getServletRequest()取的对象是HttpServletRequest,不是request。

pageContext.getServletResponse()取的对象是HttpServletResponse,不是response.

备注:

pageContext在 jsp标签开发中 常见。很少直接使用。


JavaBean 规范 C7

为啥有JavaBean规范?

将Class写成 JavaBean组件,提高开发效率。

JavaBean被谁用?

Servlet和JSP.

JavaBean 规范的内容(对class)

1. Class必须放在某个Package中

2. Class必须用public声明

3.Class必须包含无参数构造函数

4. 属性必须用private声明

5. 要被外界操作的属性,则必须声明setter和Getter

6 属性必须用小写字母开头(很重要!,否则jsp:setProperty 无法自动赋值属性)

上述5条都满足的class, 即符合JavaBean 的Class.

JavaBean的类别

1

简单JavaBean

只包含 属性,setter,getter

2

POJO

3

VO

4

TO

属性,setter,getter,
Serializable接口

简单javaBean

备注: Java默认生成不带参数的构造函数

class Person{

private
String name;

private int age;

public Person(){};

public void
setName(String name){

this.name=name;

}

public
String getName(){

return this.name;

}

public void
setAge(int age){

this.age=age;

}

public int
getAge(){

return this.age;

}

}

打包 和 调用两种方式

摘要

打包

方法1:export jar包

方法2:javac –d  目录

最后,扔到classes目录下

调用

方法1:在jsp页面中 import=”pkg.*”

方法2:

<jsp:useBean class="pkgTest.Person"
id="p1" scope="page"></jsp:useBean>

scope的取值:page, request, session, application

import
Jar
调用JavaBean

<%@ page
language="Java" pageEncoding="GBK"
import="pkgTest.*"%>

<%

Person p1=new Person();

p1.setName("高承荀");

p1.setAge(26);

%>

姓名:<%=p1.getName()%><br></br>

年龄:<%=p1.getAge() %>

jsp:useBean
class=”” scope=”page” id=”objName”

 

<%@ page
language="Java" pageEncoding="GBK""%>

<jsp:useBean class="pkgTest.Person" id="p1" scope="page"></jsp:useBean>

姓名:<%=p1.getName()%><br></br>

年龄:<%=p1.getAge() %>

jsp useBean-Property  简化表单映射

摘要:

原始

jsp

loop{ //n次

obj.setPropertiy(request.getParameter)

}

jsp:setProperty

name=javaBeanId property=”*”

两句将表单中所有
name值映射到

obj对应property上

备注:Model必须符合JavaBean规范6条。否则赋值为null

login.htm

<!DOCTYPE HTML>

<html>

<head></head>

<body>

<form action="test.jsp"
method="post">

<div>姓名:<input type="text" name="name"
value="高承荀"></div>

<div>年龄:<input type="text" name="age"
value="26"></div>

<div>邮箱:<input type="text" name="email"
value="1695539064@qq.com"></div>

<div><input type="submit" value="提交"></div>

</form>

</body>

</html>

test.jsp

<%@ page
language="Java" pageEncoding="GBK"%>

<%
request.setCharacterEncoding("GBK");%>

<jsp:useBean class="pkgTest.Person" id="p1" scope="page"></jsp:useBean>

<jsp:setProperty name="p1" property="*"/>

姓名:<%=p1.getName()%></br>

年龄:<%=p1.getAge()%></br>

邮箱:<%=p1.getEmail()%>

jsp:setPropery  4种设置方式

1

property=”*”

自动 name-property映射

2

property=”属性名”

只为某property赋值

3

property=”属性名” param=”参数名”

property 获得指定 name值

4

property=”属性名” value=”内容”

perperty获得value值

只为某property赋值

<%@ page
language="Java" pageEncoding="GBK"%>

<%
request.setCharacterEncoding("GBK");%>

<jsp:useBean class="pkgTest.Person" id="p1" scope="page"></jsp:useBean>

<jsp:setProperty name="p1" property="name"/>

姓名:<%=p1.getName()%></br>

年龄:<%=p1.getAge()%></br>

邮箱:<%=p1.getEmail()%>

效果

property 获得指定 name

<jsp:useBean class="pkgTest.Person" id="p1" scope="page"></jsp:useBean>

<jsp:setProperty name="p1" property="name" param="age"/>

<jsp:setProperty name="p1" property="email" param="name"/>

姓名:<%=p1.getName()%></br>

年龄:<%=p1.getAge()%></br>

邮箱:<%=p1.getEmail()%>

姓名:26
年龄:0
邮箱:高承荀

 

property获得指定value

<jsp:useBean class="pkgTest.Person" id="p1" scope="page"></jsp:useBean>

<jsp:setProperty name="p1" property="name"
value="姓名"/>

<jsp:setProperty name="p1" property="age" value="123"/>

<jsp:setProperty name="p1" property="email" value="jjkjkkj"/>

姓名:<%=p1.getName()%></br>

年龄:<%=p1.getAge()%></br>

邮箱:<%=p1.getEmail()%>

姓名:姓名
年龄:123
邮箱:jjkjkkj

jsp:getPropery 获取属性

摘要

取obj某个property

<jsp:getProperty name=”objID”
property=”属性名”/>

效果等价于<%=obj.getProperty()%>

<jsp:setProperty name="p1" property="name"
value="姓名"/>

姓名:<jsp:getProperty name="p1" property="name"/>

姓名:姓名

JavaBean scope 属性

描述:obj的生存周期

1

page

页面内有效,跳转后失效。

2

request

请求内有效。(如果服务器端跳转到b.jsp,则b.jsp中有效)。

回应完请求则失效。

3

session

一次会话内有效。

浏览器关闭失效。

4

application

保存在服务器上。

服务器重启/关闭 失效。

删除JavaBean

摘要

序号

scope

删除语句

1

page

pageContext.removeAttribute(id);

2

request

request.removeAttribute(id);

3

session

session.removeAttribute(id);

4

application

application.removeAttribute(id);


应用- 注册功能

索引:Page 200

蓝图

详情:jspCode\register

摘要:

1

index.jsp 同时具备显示空白和提示功能

<%@ page
language="Java" pageEncoding="GBK"%>

<jsp:useBean id="person" scope="request"
class="pkgTest.Person"></jsp:useBean>

<form action="check.jsp" method="post">

<div>姓名:<input type="text" name="name"
value="<%=person.getName()%>"/><%=person.getError("nameEr")%></div>

<div>年龄:<input type="text" name="age"
value="<%=person.getAge()%>"/><%=person.getError("ageEr")%></div>

<div>邮箱:<input type="text" name="email"
value="<%=person.getEmail()%>"/><%=person.getError("emailEr")%></div>

<div><input type="submit" value="提交"></div>

</form>

//构造函数中,默认设置Name,Age,Email为空;
JavaBean的无参数构造函数~

//getError中默认如果取到的是null,则返回””

2

check.jsp

引用index.jsp中的javaBean对象

<jsp:useBean class="pkgTest.Person"
id="person" scope="request"></jsp:useBean>

<jsp:setProperty name="person"
property="*"></jsp:setProperty>

3

person.java中将age设置成String

private
String name;

private
String age;

private
String email;

private
Map<String,String> errors=null;

//好处:所有项都能用Regex校验

//JavaBean的set,get不会出现type不匹配

4

无参数构造函数

public
Person(){

this.name="";

this.age="";

this.email="";

this.errors=new
HashMap<String,String>();

};

5

Map和HashMash

表示

[{key,value}]

//添加 errors.put("emailEr", "邮箱格式不正确");

//获取 this.errors.get(key)

//Map是一个 [{key,value}]

//这样初始化this.errors=new
HashMap<String,String>();

6

正则验证

姓名:if(!this.name.matches("\\w{6,15}")){

年龄:if(!this.age.matches("\\d+")){

邮箱:if(!this.email.matches("\\w+@\\w+\\.\\w+\\.?\\w*")){

7

两种实现思路

第1: index.htm+Servlet

第2:
index.jsp+check.jsp

index.jsp 和check.jsp 间使用服务端跳转 到出错页

check.jsp和index.jsp间使用服务端跳转


Web开发模式

JSP-JavaBean-数据库
模式

摘要:

JSP单职责模式

职责

缺点

JSP

显示,流程控制

流程控制和前端在一起。

维护困难。

JavaBean

数据库操作

数据库

MVC模式

Model-View-Controller

Model层

JavaBean类。

View层

JSP页。

接收Servlet内容,生成和显示数据。

Controller层

处理所有http请求。

解析参数,进行流程控制。

关键:

Servlet中requestDistpatcher(“test.jsp”).forward(request,response)

Servlet到jsp使用request记录属性

MVC模式下,JSP的4规范

目的:确保jsp简洁,

1. 接收属性

2. 判断属性存在,流程控制

3. 使用迭代或者Model进行输出

4. 只许import “java.util.*”包


应用 MVC模式 的登录功能

//不足:(1)界面不美观(2)未加密post (比ajaxHtm+Servlet+JavaBean的MVC)

//作战目的:
熟悉  JSP+Servelet+JavaBean的MVC

            记住 JSP页面的4个规范

数据库准备

使用Account数据库

代码清单

ClsDbConfig

数据库配置(driver,url,usr,psw)

取得Connection

关闭Connection

成员:

private,...

private Connection conn

方法:

public Connection getConnection

ClsDbOper

方法:

public static boolean checkAccount

Account

JavaBean

成员:

ID,usrName,password

Map<String,String>

方法:

public boolean isValidate()

public String getError(String key)

svt

接收requestParameter

调用isValidate

--

case 校验不通过,

req.setAttribute(“info”,info);

request.getRequestDispatcher(“test.jsp”)

.forward(req,res);

case 校验通过,isValidate未通过

req.setAttribute(“info”,info)

req.getRequestDispatcher(“url”)

.forward(req,res)

case 校验通过,isValidate通过

session.setAttribute(“uid”,uid)

response.sendRedirect(url);

--

login.jsp

登录界面

错误提示

输入校验

index.jsp

校验session(“uid”)

case通过:欢迎

case未通过:

response.sendRedirect(“login.jsp”)

作战开始:14:23

完成时间:16:18

2h

设计模式

数据访问- DAO模式

DAO: Data Access Object

功能:实现CRUD功能

各层的功能

类别

功能

编码规则

客户层

浏览器(B/S架构)

显示层

JSP/Servlet页面效果显示。

业务层

从客户的角度,就是一个功能。

从代码的角度,就是调用一组数据层函数。

数据层

CRUD操作。
直接操作数据库

DAO类军规:

1.DAO类名与表名相同

2.DAO类添加,更改,删除
以 do开头。

举例:

Emp doCreat(Emp)

Emp doUpdate(Emp)

boolean doDelete(int
ID)

3.DAO类查询
以find,

get开头

List<Emp>  doFind(String
key)

Emp doGet(int
ID)

Model类军规:

Model类JavaBean规范

应用 DAO-雇员管理系统

战斗序列:

数据库设计

(1)字段-类型-约束

(2)创建表-添加数据

Model类设计

(1)类名同表名

(2)JavaBean规范开发Model类

DataConnection类设计

(1)定义Driver,DbUrl,usr,psw

(2)实现getConnection()和close方法

DAO类设计

数据库设计

类型

约束

ID

Number

主键,自增

Name

varchar(10)

非空

Job

varchar(9)

非空

EmpDate

varchar(10)

雇佣日期

sal

number

薪水

min 10

Model类设计

package pkgEmp;

import
java.util.HashMap;

import java.util.Map;

public class Emp{

private int id;

private
String name;

private
String job;

private
String empDate;

private
String salary;

private
Map<String,String> errors=null;

public
Emp(){

this.id=-1;

this.name="";

this.job="";

this.empDate="";

this.salary="";

this.errors=new
HashMap<String,String>();

}

public boolean
isValidate(){

boolean flag=true;

if(!this.name.matches("\\w{2,10}")){

flag=false;

this.errors.put("erN","姓名长度必须是2~10");

System.out.println("Name:"+this.name+".  erN,姓名长度必须是2~10");

return flag;

}

if(this.job!=null&&this.job.length()==0){

flag=false;

this.errors.put("erJ","工作不能为空");

System.out.println("erJ工作不能为空");

return flag;

}

if(!this.salary.matches("\\d+")){

flag=false;

this.errors.put("erS","薪水必须是数值");

System.out.println("erS薪水必须是数值");

return flag;

}

System.out.println(flag);

return flag;

}

public
String getError(String key){

if(this.errors.get(key)==null){return "";}

return this.errors.get(key);

}

public int
getID(){

return this.id;

}

public void
setID(int id){

this.id=id;

}

public
String getName(){

return this.name;

}

public void
setName(String str){

this.name=str;

}

public
String getJob(){

return this.job;

}

public void
setJob(String str){

this.job=str;

}

public
String getEmpDate(){

return this.empDate;

}

public void
setEmpDate(String str){

this.empDate=str;

}

public String
getSalary(){

return this.salary;

}

public void
setSalary(String str){

this.salary=str;

}

}min5

DbConnection类

private DbDriver

private DbUrl

private Usr

private Psw

public static getCoonection

return this.conn

public class
DbConnection {

public static final
String DbDriver="oracle.jdbc.driver.OracleDriver";

public static final
String DbUrl="jdbc:oracle:thin:@localhost:1521:orcl";

public static final
String Usr="test";

public static final
String Psw="test";

public static
Connection getConnection() throws
ClassNotFoundException, SQLException{

Connection
con=null;

Class.forName(DbDriver);

con=DriverManager.getConnection(DbUrl, Usr, Psw);

return con;

}

}

min 10

DAO类设计

public Emp doCreate(Emp emp)

public List<Emp> find(String key)

public Emp getById(int ID)

 

 public static Emp
doCreate(Emp emp) throws
ClassNotFoundException, SQLException{

Connection con=DbConnection.getConnection();

String sqlStr="insert
into emp(Name,Job,EmpDate,Salary) values('"+emp.getName()+"','"+emp.getJob()+"','"+emp.getEmpDate()+"',"+emp.getSalary()+")
returning ID into :1";

OraclePreparedStatement pstmt
=(OraclePreparedStatement)con.prepareStatement(sqlStr);

pstmt.registerReturnParameter(1, Types.NUMERIC);

pstmt.executeUpdate();

ResultSet
rs=pstmt.getReturnResultSet();

rs.next();

emp.setID(rs.getInt(1));

rs.close();

pstmt.close();

con.close();

return emp;

}

public static
List<Emp> find(String key) throws ClassNotFoundException,
SQLException{

List<Emp> li=new
ArrayList<Emp>();

Connection con=DbConnection.getConnection();

String sqlStr="select
ID,Name,Job,EmpDate,Salary from emp";

if(!key.equals("")){sqlStr+="
where Name like '%"+key+"%'";}

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery(sqlStr);

while(rs.next()){

Emp emp=new
Emp();

emp.setID(rs.getInt("ID"));

emp.setName(rs.getString("Name"));

emp.setJob(rs.getString("Job"));

emp.setEmpDate(rs.getString("EmpDate"));

emp.setSalary(rs.getString("Salary"));

li.add(emp);

}

return li;

}

public static Emp
getById(int ID) throws
SQLException, ClassNotFoundException{

Connection con=DbConnection.getConnection();

String sqlStr="select
ID,Name,Job,EmpDate,Salary from emp where ID="+ID;

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery(sqlStr);

Emp emp=new
Emp();

while(rs.next()){

emp.setID(rs.getInt("ID"));

emp.setName(rs.getString("Name"));

emp.setJob(rs.getString("Job"));

emp.setEmpDate(rs.getString("EmpDate"));

emp.setSalary(rs.getString("Salary"));

}

return emp;

}

min20

测试DAO

/*

for(int
i=0;i<=4;i++){

Emp
emp=new Emp();

emp.setName("李兴华"+i);

emp.setJob("程序员"+i);

emp.setEmpDate("2012-01-0"+i);

emp.setSalary(String.valueOf(1000*(i+2)));

doCreate(emp);

}*/

/*

List<Emp>
emps=find("李");

for(int
i=0;i<=emps.size()-1;i++){

System.out.println(emps.get(i).getName());

}

*/

/*

Emp
emp=getById(2);

System.out.println(emp.getName());

*/

min10


Jsp 添加

insert.jsp

字段信息输入,提示信息错误

doCreate.jsp

校验信息,执行添加。

添加成功则显示。

添加失败则跳转到insert.jsp并提示错误。

insert.jsp

<%@ page
language="Java" pageEncoding="GBK"%>

<%request.setCharacterEncoding("GBK");%>

<jsp:useBean id="emp" class="pkgEmp.Emp"
scope="request"/>

<form action="doCreate.jsp"
method="post">

<table>

<tr><td>姓&nbsp;&nbsp;名</td><td><input type="text" name="name"
value="<%=emp.getName()%>"/></td><td><%=emp.getError("erN")%></td></tr>

<tr><td>职&nbsp;&nbsp;位</td><td><input type="text" name="job"
value="<%=emp.getJob()%>"/></td><td><%=emp.getError("erJ")%></td></tr>

<tr><td>受聘日期</td><td><input type="text" name="empDate"
value="<%=emp.getEmpDate()%>"/></td><td><%=emp.getError("erE")%></td></tr>

<tr><td>薪&nbsp;&nbsp;资</td><td><input type="text" name="salary"
value="<%=emp.getSalary()%>"/></td><td><%=emp.getError("erS")%></td></tr>

<tr><td colspan=3><input type="submit"
value="提交"/></td></tr>

</table>

</form>

doCreate.jsp

<%@ page
language="Java" pageEncoding="GBK"
import="pkgEmp.*"%>

<%request.setCharacterEncoding("GBK");%>

<jsp:useBean class="pkgEmp.Emp" id="emp"
scope="request"/>

<jsp:setProperty name="emp" property="*"/>

<%if(emp.isValidate()){

Emp
emp2=DbOper.doCreate(emp);

if(emp2.getID()!=-1){%>

<h1>添加成功</h1>

姓名:<%=emp2.getName()%><br/>

工作:<%=emp2.getJob()%><br/>

受聘日期:<%=emp2.getEmpDate()%><br/>

薪水:<%=emp2.getSalary()%>

<%}else{%>

<jsp:forward page="insert.jsp"/>

<%}%>

<%}else{%>

<jsp:forward page="insert.jsp"/>

<%}%>


 

Jsp显示

list.jsp

查询关键字输入框

--

table显示信息

list.jsp

<%@ page
language="Java" pageEncoding="GBK"
import="pkgEmp.*"%>

<%@ page
import="java.util.*" %>

<%

request.setCharacterEncoding("GBK");

String
key="";

key=request.getParameter("key")==null?"":request.getParameter("key");

List<Emp>
emps=DbOper.find(key);

String
dataStr="";

%>

<form action="emp_list.jsp"
method="post">

<div>请输入查询关键字:<input type="text" value=""
name="key"/><input type="submit"
value="查询"></div>

<table border=1><tr><td>姓名</td><td>工作</td><td>入职日期</td><td>薪资</td></tr>

<%for(int
i=0;i<=emps.size()-1;i++){ %>

<tr><td><%=emps.get(i).getName()%></td><td><%=emps.get(i).getJob()%></td><td><%=emps.get(i).getEmpDate()%></td><td><%=emps.get(i).getSalary()%></td></tr>

<%}%>

</table>

</form>


文件上传

smartUpload手册

参考jspsmartupload.zip

图片上传

jar包:jspSmartUpload.jar

特点:(1)可限制类型

(2)获取文件名、类型、尺寸

额外依赖:

jsp-api.jar    (tomcat自带)

servlet-api.jar  (tomcat自带)

备注:放在lib目录下

摘要:

(1)表单中使用 <input type=”file” name=””/>上传

任务

upload.htm

(1) <input type=”file” name=””/>

input标签 上传

(2) form action=”su”

指向svt

pkgUpload.ClsUpload

(1)取文件-检查合法性-保存-页面跳转

依赖项

(1)jsp-api.jar

(2)servlet-api.jar

(3)jspSmartUpload.jar

upload.htm

<HTML>

<BODY BGCOLOR="white">

<H1>jspSmartUpload
: Sample 1</H1>

<HR>

<FORM METHOD="POST"
ACTION="su" ENCTYPE="multipart/form-data">

<INPUT TYPE="FILE" NAME="FILE1"
SIZE="50"><BR>

<INPUT TYPE="SUBMIT" VALUE="Upload">

<input type="text" name="info"
value="test photp"/>

</FORM>

</BODY>

</HTML>

ClsUpload.java

protected void
doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

// TODO
Auto-generated method stub

//存储路径

String filePath = "F:\\Workspaces\\UI05\\UI05\\WebContent\\upload\\";

String messages="";

String forward="";

SmartUpload su = new
SmartUpload();

long
maxsize = 2 * 1024 * 1024;// 设置大小,为2MB

String allowedFilesList = "jpg,gif,bmp,png";//允许文件

//拒绝文件

String
denidFilesList = "exe,bat,jsp,htm,html,,";

try {

su.initialize(this.getServletConfig(),
request, response);        //初始化

su.setMaxFileSize(maxsize);                                     // 限制上传文件的大小

su.setAllowedFilesList(allowedFilesList);                        // 设置允许上传的文件类型

su.setDeniedFilesList(denidFilesList);

su.upload();                                                   
// 上传文件

// 获取上传的文件,因为只上传了一个文件,所以可直接获取

File file =
su.getFiles().getFile(0);

// 如果选择了文件

if
(!file.isMissing()) {

//获取当前时间并格式化为字符串

String now = new
Date().getTime() + "";

//filePath值

String photoAddr=filePath +
now + "."+file.getFileExt();

System.out.println(photoAddr);

file.saveAs(photoAddr,File.SAVEAS_PHYSICAL);

}else{

System.out.println("file
is Missing()");

messages="请选择要上传的文件!";

forward="/admin/error.jsp";

}

}catch
(java.lang.SecurityException e){

System.out.println("上传失败82");

messages="<li>上传文件失败!上传的文件类型只允许为:jpg,gif,bmp</li>";

forward="/admin/error.jsp";

}catch
(SmartUploadException e) {

System.out.println("上传失败86");

messages="上传文件失败!";

forward="/admin/error.jsp";

e.printStackTrace();

} catch
(SQLException e) {

System.out.println("92");

e.printStackTrace();

}

request.setAttribute("messages",messages);

request.getRequestDispatcher(forward).forward(request, response);

}

}


混合表单处理

背景:客户端form中包含照片 和 备注信息

摘要:

SmartUpload
su = new SmartUpload();

su.initialize(this.getServletConfig(),request,
response);

su.setAllowedFilesList("jpg,gif,bmp,png");//允许文件

su.setMaxFileSize(2
* 1024 * 1024);// 设置大小,为2MB

su.getRequest.getParameter(“info”)

取备注信息

su.getFiles().getFile(0)

取文件

htm

<!Doctype HTML>

<html><head><meta charset="GBK"/></head>

<body>

<form action="sa"
method="post" enctype="multipart/form-data">

<table><tr><td>姓名</td><td><input type="text" name="name"/></td></tr>

<tr><td>照片</td><td><input type="file" name="photo"/></td></tr>

<tr><td colspan=2><input type="submit"
value="提交"/><input type="reset" value="重置"/></td></tr>

</table>

</form>

</body>

</html>

 

svt

protected void
doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

request.setCharacterEncoding("GBK");

SmartUpload
su = new SmartUpload();

su.initialize(this.getServletConfig(),request,
response);

su.setAllowedFilesList("jpg,gif,bmp,png");//允许文件

su.setMaxFileSize(2
* 1024 * 1024);// 设置大小,为2MB

Map<String,String>
info=new HashMap<String,String>();

try {

su.upload();

} catch
(SmartUploadException e1) {

e1.printStackTrace();

info.put("false", "上传发生错误");

}

String name=su.getRequest().getParameter("name");

File fi=su.getFiles().getFile(0);

if(!info.isEmpty()){

request.setAttribute("failReason",info.get("false"));

request.getRequestDispatcher("/re.jsp").forward(request,response);

return;

}

String fiName=new
Date().getTime()+"."+fi.getFileExt();

System.out.println(fiName);

try {

fi.saveAs(this.getInitParameter("dirPic")+"\\"+fiName,File.SAVEAS_PHYSICAL);

} catch
(SmartUploadException e) {

e.printStackTrace();

request.setAttribute("failReason","保存发生错误");

request.getRequestDispatcher("/re.jsp").forward(request,response);

return;

}

request.removeAttribute("failReason");

System.out.println(name);

request.setAttribute("name",name);

//request.setAttribute("url","/pics/"+fiName);//host/pics/

request.setAttribute("url","pics/"+fiName);//host/vir/pics

request.getRequestDispatcher("/re.jsp").forward(request,response);

return;

}

re.jsp

<%@ page
language="Java" contentType="text/html"
pageEncoding="GBK"%>

<% if(request.getAttribute("failReason")!=null){%>

<b>保存失败,原因:</b><h3><%=request.getAttribute("failReson")%></h3>

<%}else{%>

<b>保存成功</b>

<div>姓名:<%=request.getAttribute("name")%></div>

<div><img alt="照片" src="<%=request.getAttribute("url")%>"/></div>

<%  }%>

Servlet

背景知识

Servlet本质

继承了HttpRequest的 java类。 它是一个.java文件

依赖项

将tomcat/lib/servlet-api.jar拷贝到Web-inf/lib目录下

结构

pkgSvt

ClsSvt

引用

Export jar到:

WebContent/WEB-INF/classes

web.xml映射

<web-app>

<servlet>

<servlet-name>sA</servlet-name>

<servlet-class>pkgSvt.ClsSvt</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>sA</servlet-name>

<url-pattern>pkgSvt.ClsSvt</url-pattern>

<servlet-mapping>

</web-app>

svt比CGI的优势

svt多线程, 项目比CGI高。

第一个Servlet

创建Servlet

1.创建servlet, 输入package Name(对应nameSpace和className(servletName)

package
servletPack;

public class
ReqHandler extends HttpServlet {//继承HttpServlet

备注:servletPack.ReqHandler
之后将写入
servlet-class

2.把这个java的doGet写上代码。

// TODO
Auto-generated method stub

protected void
doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

// TODO
Auto-generated method stub

PrintWriter
print=response.getWriter();

String result="<html><head></head><body><h1>Hello
World</h1></body></html>";

print.print(result);

}

将servletPackage导出成jar,并拷贝到WebContent/Web-inf/classes目录下

web-inf\web.xml 配置信息

在Web-Inf的Web.xml中添加请求映射

<?xml version="1.0"
encoding="utf-8"?>

<web-app>

<servlet>

<servlet-name>SvtHello</servlet-name>

<servlet-class>pkgResiCrud.SvtHello</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>SvtHello</servlet-name>

<url-pattern>/hello</url-pattern>

</servlet-mapping>

</web-app>

备注:

1. <servlet>标签下的<servlet-name>与<servlet-mapping>下的<servlet-name>相同

2.s<servlet-class>写packageName.servletName

3.servlet-name不要和url-pattern完全相同,否则tomcat无法启动,譬如

<servlet-mapping>

<servlet-name>SvtHello</servlet-name>

<url-pattern>/SvtHello</url-pattern>

</servlet-mapping>

即可

访问url:

http://ip/webAppName/hello

访问url,测试


获取Ajax的postData

结论:request.getInputStream

//数据流

ServletInputStream
inpStream=request.getInputStream();

//数据流总长

int
dataLength=request.getContentLength();

//已读长度

int
readLength=0;

//本次读取长度

int
curLength=0;

//存放数据流的
byte数组

byte[]
byteArr=new byte[dataLength];

while(readLength<dataLength){

curLength=inpStream.read(byteArr);

readLength+=curLength;

}

String
dataString=new String(byteArr,"utf-8");

System.out.println("dataGet:"+dataString);


获取form.submit的data

结论:request.getParameter(name)

test.html

<script>

function bindEvents(){

$("#btnTest1").on("click",function(){

$("#frmDownload")[0].action="../resiCrud";

var
postData={cmd:5,data:null};

$("#inpPostData").val(JSON.stringify(postData));

$("#frmDownload")[0].submit();

});

}

</script>

<body>

<input type="button"
id="btnTest1" value="getXls"/>

<form id="frmDownload"
method="post" style="display:none">

<input type="text" name="postData"
id="inpPostData"/>

</form>

</body>

servlet

String
postData=request.getParameter("postData");

System.out.println(postData);

获取url中的参数

结论:request.getQueryString()

test.html

function bindEvents(){

$("#btnTest1").on("click",function(){

$("#frmDownload")[0].action="../resiCrud?para1=1&para2=2";

var
postData={cmd:5,data:null};

$("#inpPostData").val(JSON.stringify(postData));

$("#frmDownload")[0].submit();

});

}

</script>

</head>

<body>

<input type="button"
id="btnTest1" value="getXls"/>

<form id="frmDownload"
method="post" style="display:none">

<input type="text" name="postData"
id="inpPostData"/>

</form>

</body>

servlet

protected void
doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

// TODO
Auto-generated method stub

String
postData=request.getParameter("postData");

System.out.println("postData:"+postData);

String queryStr=request.getQueryString();

System.out.println("queryString:"+queryStr);

....

输出结果:

postData:{"cmd":5,"data":null}

queryString:para1=1&para2=2

冲突 getParameter和getInputStream()

结论:

对象HttpServletRequest,
getParameter()执行之后,会让getInputStream()的值发生改变。反之亦然。

because
POST data can be read only once

解决方法:

在url中添加queryString。暗示使用getParameter还是getInputStream来获取request参数

//从form来

String queryStr=request.getQueryString();

System.out.println("queryString:"+queryStr);

//从getInputStream中取参数

if(queryStr==null){

}

//从getParameter中取参数

else if(queryStr.equals("para")){

}


取config,session,
application对象

config

this.getServletConfig()

session

request.getSession()

application

this.getServletContext()


svt中取servlet initParam

摘要:

init-param
存在于 servlet标签下。不能直接放在web-app目录下。

一个servlet标签下可以存放多个init-param

web.xml配置

在对应servlet标签下 添加 <init-param>

svt中获取

使用this.getServletContext.getInitParameter(“name”)

<servlet>

<servlet-name>sA</servlet-name>

<servlet-class>pkgSu.ClsSu</servlet-class>

<init-param>

<param-name>dirPic</param-name>    <param-value>F:\\Workspaces\\UI05\\UI05\\WebContent\\pics</param-value>

</init-param>

</servlet>

this.getServletContext().getInitParameter(“dirPic”)


svt 客户端跳转

response.sendRedirect("http://www.baidu.com");

svt服务端跳转

摘要:等价于
<jsp:forward page=”” />

request.getRequestDispatcher(url).forward(request,
response);

参数:url-要跳转的路径。 request-传递参数,response-传递参数

Svt返回页面

摘要:

设置页面字符串

StringBuffer.append(“<html>...</html>”);

response 页面字符串

PrinterWriter pw=reponse.getWrite();

pw.write(buf.toString());

pw.close()

protected void
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {

// TODO
Auto-generated method stub

this.doPost(request,
response);

}

/**

* @see
HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

*/

protected void
doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {

// TODO
Auto-generated method stub

StringBuffer
buf=new StringBuffer();

response.setCharacterEncoding("utf-8");

buf.append("<!Doctype
html><html><head><meta
charset='utf-8'></head><body>");

buf.append("<h1>Page
write by PrinterWriter</h1><h2>测试Svt输出页</h2></body><html>");

PrintWriter
pw=response.getWriter();

pw.write(buf.toString());

pw.close();//关闭响应

}


ajax,jsp,svt制作页面比较

结论:使用ajax制作页面,使用svt处理请求

方便程度排序:

Ajax>jsp>svt

代码分离程度:

Ajax>jsp>svt

思路

工具

ajax

html,css,jq,js

jsp

<%%>

html

svt

StringBuffer

PriterWriter

Servlet生命周期

阶段

前件

时间

初始化

int()

(1)jar在class目录下

(2)web.xml 中servletMapping

web容器启动时

(tomcat\bin\startup)

服务

doGet(),doPost()

初始化完成

接到http请求

中止,释放

destroy()

以下任意:

(1)web容器关闭

(2)接到卸载svt指令

过滤Servlet

摘要:

作用

限制客户对WebContent中资源的访问

本质

实现了
servlet.Filter的 java Class

主要方法:

init()

web容器启动时,调用FilterConfig取得配置参数

doFilter()

完成过滤操作

destroy()

结束过滤器,释放资源



ResultSet

获取记录条数

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection
conn=DriverManager.getConnection("");

Statement
std=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

String
sqlStr="select * from Resident";

ResultSet
rs=std.executeQuery(sqlStr);

//获取记录条数.

int
rowCount=0;

rs.last();

rowCount=rs.getRow();

System.out.println("rowCount:"+rowCount);

//将cursor移到第一条

rs.first();

String
result="[";

while(rs.next()){

//Todo.....

}

遍历所有字段

停用:

rs.getString(0) 值会变化,停用

使用:

rs.getString(“Name”);


正则-String

Java 正则

分组

String Str="{District:4,hyID:6,IsActivated:2}";

//(?<dVal>\\d),将\\d存储到group,dVal中

Pattern pat = Pattern.compile("District:(?<dVal>\\d),");

Matcher m = pat.matcher(Str);

while(m.find()) {

System.out.println(m.group("dVal"));//group(para),para即分组号

}

//(\\d),()将被分组,从1开始编号.读取 用m.group(1).
备注:group(0)对应整个匹配项

Pattern pat2 = Pattern.compile("District:(\\d),");

m=pat2.matcher(Str);

while(m.find()) {

System.out.println(m.group(1));//group(para),para即分组号

}

输出:

4

4

姓名-年龄-邮箱

姓名:if(!this.name.matches("\\w{6,15}")){

年龄:if(!this.age.matches("\\d+")){

邮箱:if(!this.email.matches("\\w+@\\w+\\.\\w+\\.?\\w*")){


String

replaceAll替换字符串中的所有 \”null\”

背景:rs.getString(“Address”)会将null值表示成 \”null\”.

返回给前端的JSON串要写成Address:””

String oStr="\"null\"
is null";

String dStr=oStr.replaceAll("\"null\"","\"\"");

System.out.println("dString
is:"+dStr);

字符串相等

在编程中,通常比较两个字符串是否相同的表达式是“==”,但在Java中不能这么写。在Java中,如果要比较a字符串是否等于b字符串,需要这么写:

if(a.equals(b)){

}

原因:

由于字符串是对象类型,而使用equals()方法比较两个对象的内容

字符串非空

if(queryStr!=null&&queryStr.length()>0){

}

字符串为空

queryStr==null|| queryStr.length()==0


String byte[]互相
转换

String
str="你";

byte[] b=str.getBytes("UTF-8");

for(int
i=0;i<=b.length-1;i++){

System.out.println(b[i]);

}

String back=new String(b);

System.out.println(back);

String+ 和 StringBuffer.append比较

摘要:

String +被转换成
StringBuffer执行 append操作。

编码中使用StringBuffer效率高。

public static
String strPlus(String a,String b){

/*
StringBuffer sA=new StringBuffer(a);

* sA.append(b);

* return sA.toString();

* */

return a+b;

}

public static
String strAppend(String a,String b){

StringBuffer
sb=new StringBuffer(a);

sb.append(b);

return
sb.toString();

}

JSON处理

客户端JSON处理

解析responseString

即使是一个JSON对象,不用数组传回去。eval提示字符串错误。

未知原因。

建议用[]包裹字符串

将requestData 转成JSONString

var reqData={cmd:0,data:null};

JSON.stringify(reqData)

服务端JSON处理

JSON字符串和JSON对象的差异(重要)

JSON字符串,要求属性名加双引号。如果属性值是对象,对象花括号不要引号

举例:

{"Done":true,"Info":{"ID":15090,"Longitude":116.32502,"Latitude":40.00006}}

JSON对象,
属性名不要双引号

JSONView的检验能通过,但JSON.parse出错,一定是因为,有属性名没有加引号

将ResultSet写成JSON字符串

result+="{\"ID\":"+rs.getString("ID")+",\"Name\":\""+rs.getString("Name")+"\",\"Age\":"+rs.getString("Age")+",\"Job\":\""+rs.getString("Job")+"\"},";

属性名也要加引号。否则前端无法用JSON.parse转

字符串值需要加引号。

Gson 的toJSON和fromJSON

Gson由google开发

Gson
gson = new Gson(); // Or use new GsonBuilder().create();

MyType target = new MyType();

//Class转Json字符串

String json = gson.toJson(target); //
serializes target to Json

//Json字符串转Class

MyType target2 = gson.fromJson(json,
MyType.class); // deserializes json into target2

jdbc

ojdbc位置:

Oracle安装目录

app\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar

放在javaProject的 src目录下。

插入 (返回最新记录)

http://blog.csdn.net/yzsind/article/details/6918506

//添加商户, 返回最新添加

public static
String InsertShop(Shop shop) throws
ClassNotFoundException, SQLException{

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "gxk", "gxk");

String vsql = "insert
into shopmbase(ID,Num,InnerNum,Name,InstallDate,Address,Active,IsActivated)
values(shm_sequence.nextval,'"+shop.Num+"','"+shop.InnerNum+"','"+shop.Name+"','"+shop.InstallDate+"','"+shop.Address+"','"+shop.Active+"','"+shop.IsActivated+"')
returning ID into :1";

OraclePreparedStatement pstmt
=(OraclePreparedStatement)conn.prepareStatement(vsql);

pstmt.registerReturnParameter(1, Types.NUMERIC);

pstmt.executeUpdate();

ResultSet
rs=pstmt.getReturnResultSet();

rs.next();

int
ID=rs.getInt(1);

rs.close();

pstmt.close();

shop.ID=ID;

return new
Gson().toJson(shop);

}

更新

//更新商户

public static
String UpdateShop(Shop[] shops) throws
ClassNotFoundException, SQLException{

Report result=new
Report();

result.Done=false;

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "gxk", "gxk");

Statement stmt=conn.createStatement();

int updated=0;

for(int
i=0;i<=shops.length-1;i++){

String sqlStr="update
shopmbase set Num='"+shops[i].Num+"',InnerNum='"+shops[i].InnerNum+"',Name='"+shops[i].Name+"',InstallDate='"+shops[i].InstallDate+"',CZDate='"+shops[i].CZDate+"',CLDate='"+shops[i].CLDate+"',Address='"+shops[i].Address+"',IsActivated='"+shops[i].IsActivated+"',Active='"+shops[i].Active+"',Longitude="+shops[i].Longitude+",Latitude="+shops[i].Latitude+"
where ID="+shops[i].ID;

int
val=stmt.executeUpdate(sqlStr);

if(val!=0){

updated++;

}

}

result.Done=true;

result.Info=updated+"
of "+shops.length+"
are updated";

stmt.close();

conn.close();

String report=new
Gson().toJson(result);

report="["+report+"]";

System.out.println(report);

return report;

}

删除

delete from where

查询

select from where

rs.close 将触发stmt.close

说明:

rs1=stmt.executeQuery(sql1);

rs2=stmt.executeQuery(sql2);

rs2.close();//stmt也将被close()

System.out.println(rs.next())  //false; stmt.close之后,rs1.close()

Connection conn =
DriverManager.getConnection(ClsDbConfig.dbUrl,ClsDbConfig.userName,
ClsDbConfig.password);

Statement 
stmt = conn.createStatement();

String sqlStr="select
distinct type from shopothattr";

/*结果

* [{attrName:"设备状态",values:[{text:'未激活',value:1}]},{attrName:"商户类型"}..]

* */

String result="[";

ResultSet rs=stmt.executeQuery(sqlStr);

while(rs.next()){

result+="{\"attrName\":\""+rs.getString("type")+"\",\"values\":[";

String sqlStr2="select
id,type,value from shopothattr where type='"+rs.getString("type")+"'";

Statement 
stmt2 = conn.createStatement();

ResultSet rs2=stmt2.executeQuery(sqlStr2);

while(rs2.next()){

result+="{\"text\":\""+rs2.getString("value")+"\",\"value\":"+rs2.getInt("id")+"},";

}

result=result.substring(0,result.length()-1);

result+="]},";

rs2.close();

stmt2.close();

}

result=result.substring(0,result.length()-1);

result+="]";

rs.close();

stmt.close();

conn.close();



数制-编码-加密

编码-数制

byte[] 和String 互相转换

摘要:

字符串转byte[]

byte[] b= str.getBytes(“UTF-8”)

byte[]转字符串

String str=new String(b);

String str="你好世界1234qwER~!@#$%^&*()_+";

byte[]
b=str.getBytes("UTF-8");

String
back=new String(b);

System.out.println(back);

char和int的转换

结论:Unicode*65535个字符。

使用0-65535这些数字,即可表示全球所有字符。

//ASCII
字符和int互相转换

for(int
i=0;i<=127;i++){       System.out.print(i+":"+(char)(i)+","+(int)((char)(i))+"
");

}

所有Unicode字符

System.out.print("\n");

for(int
i=0;i<=65535;i++){

System.out.print(i+":"+(char)(i)+"  ");

}

char和Unicode互相转换

本质:char和int的互相转换

Unicode:万国码

\uDFEF

\u 4个16进制位。

总共有65535种取值。

映射了全球所有字符。

备注:Java中int范围是 -21.47亿-21.47亿。

codePointAt(s) 的范围完全涵盖unicode所有值

摘要:

char转unicode,\\u+Integer.toHexString(char);

unicode转char,(char)Integer.parseInt(uni.subString(2),16);

/*unicode转字符

*/

public static char
unicodeToChar(String uni){

if(!uni.subSequence(0,2).equals("\\u")){

return ' ';

}

return (char)Integer.parseInt(uni.substring(2),16);

}

/*字符转Unicode

*/

public static
String charToUnicode(char c){

String
result="\\u";

result+=Integer.toHexString(c);

return
result;

}

 

 


String和int[]转换

应用:用户名加密发送

String usr="1234qwER你好世界";

//字符串转 int[]数组

int[]
intAr=new int[usr.length()];

StringBuffer
sb1=new StringBuffer();

for(int
i=0;i<=usr.length()-1;i++){

intAr[i]=usr.codePointAt(i);

sb1.append(intAr[i]).append(",");

}

System.out.println(sb1.substring(0,
sb1.length()-1));

//int数组转字符串

StringBuffer
sb=new StringBuffer();

for(int
i=0;i<=intAr.length-1;i++){

sb.append((char)intAr[i]);

}

System.out.println(sb.toString());

输出:

49,50,51,52,113,119,69,82,20320,22909,19990,30028

1234qwER你好世界

十进制-十六进制

Integer.toHexString(120);

Integer.parseInt(“8C”,16);



 

加密

备注:加密的基础是 编码转换

sha256加密

//hash是单向的...无解密方式

//破解方式只有一个, 尝试字符串,获得相同的hash序列,则表明明文

//结果:sha256的结果是64位字符串

public static
String ShaEncrypt(String mes){

String
result="";

MessageDigest
digest;

try {

digest = MessageDigest.getInstance("SHA-256");

byte[] hash = digest.digest(mes.getBytes("UTF-8"));

result = Hex.encodeHexString(hash);

return result;

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated
catch block

e.printStackTrace();

}catch (UnsupportedEncodingException e) {

// TODO Auto-generated
catch block

e.printStackTrace();

}

return result;

}


对称,unicode-偏移

摘要:

编码:将String 转成int[]数组,每个元素+10000

还原:将每个元素-10000,然后变成char

public static void
main(String[] args) throws UnsupportedEncodingException{

String
usr="1234qwER你好世界";

System.out.println(encodeUsr(usr,10000));

System.out.println(getUsr(encodeUsr(usr,10000),10000));

}

//从数组获取字符串

public static
String getUsr(int[] arInt,int
delta){

StringBuffer
sb=new StringBuffer();

for(int
i=0;i<=arInt.length-1;i++){

sb.append((char)(arInt[i]-delta));

}

return
sb.toString();

}

//将字符串编码成数组

public static int[] encodeUsr(String str,int
delta){

int[]
res=new int[str.length()];

for(int
i=0;i<=str.length()-1;i++){

res[i]=str.codePointAt(i)+delta;

}

return res;

}



Excel操作 (jxl)

写Excel

import
java.io.File;

import jxl.*;

import jxl.write.*;

import
jxl.write.biff.RowsExceededException;

public static void
main(String[] args) throws IOException,
RowsExceededException, WriteException {

WritableWorkbook
book=Workbook.createWorkbook(new File("WebContent/test.xls"));

WritableSheet
sheet=book.createSheet("fistPage", 0);

//在col0,row0添加 内容为test的cell

Label
lable=new Label(0,0,"test");

sheet.addCell(lable);

//在col1,row0添加数值789.123

jxl.write.Number
number=new jxl.write.Number(1,0,789.123);

sheet.addCell(number);

//保存book

book.write();

book.close();

System.out.println("Mission
Done");

}

备注:文件 默认输出路径是
Workspace目录


读取Excel

public static
String getShopsFromXls(String path) throws
IOException, BiffException{

String
result="[";

Workbook
book=Workbook.getWorkbook(new File(path));

Sheet
sheet=book.getSheet(0);

//遍历所有行

for(int
i=1;i<=sheet.getRows()-1;i++){

result+="{No:"+i+",Num:'"+sheet.getCell(0,i).getContents()+"',InnerNum:'"+sheet.getCell(1,i).getContents()+"',Name:'"+sheet.getCell(2,i).getContents()+"',SDDate:'"+sheet.getCell(3,i).getContents()+"',CLDate:'"+sheet.getCell(4,i).getContents()+"',CZDate:'"+sheet.getCell(5,i).getContents()+"',Activated:'"+sheet.getCell(6,i).getContents()+"',Address:'"+sheet.getCell(7,i).getContents()+"',HYSH:'"+sheet.getCell(8,i).getContents()+"'},";

}

result=result.substring(0,result.length()-1);

result+="]";

return
result;

}


导出InputStream

public static InputStream createExcel(String filePath) throws
ClassNotFoundException, SQLException, IOException, WriteException{

String[] arrCols={"身份证","姓名","教育程度","血型","工作单位","性别","曾用名","出生日期","身高(cm)","电话","地址","民族","婚姻状况"};

String[]
arrFields={"IDNUM","NAME","EDUCATION","BLOODTYPE","WORKUNIT","GENDER","OLDNAME","to_char(Birthdate,'yyyy-mm-dd')
as BIRTHDATE","TALL","PHONE","ADDRESS","PEOPLE","MARRIAGE"};

String[]
arrFields2={"IDNUM","NAME","EDUCATION","BLOODTYPE","WORKUNIT","GENDER","OLDNAME","BIRTHDATE","TALL","PHONE","ADDRESS","PEOPLE","MARRIAGE"};

String
sqlStr="select ";

for(int i=0;i<=arrFields.length-1;i++){

sqlStr+=arrFields[i]+",";

}

sqlStr=sqlStr.substring(0,
sqlStr.length()-1);

sqlStr+=" from Resident";

System.out.println(sqlStr);

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection
conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl",
"gxk", "gxk");

Statement
std=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

ResultSet
rs=std.executeQuery(sqlStr);

WritableWorkbook book=Workbook.createWorkbook(new File(filePath));

WritableSheet
sheet=book.createSheet("fistPage", 0);

//设置列宽 
此单位非像素,比值是1:7

int[]
arrWidths={23,10,10,10,32,10,10,12,11,10,10,10,10};

for(int
i=0;i<=arrWidths.length-1;i++){

sheet.setColumnView(i,
arrWidths[i]);

}

//表头 (colNum,rowNum)

WritableFont
fontBold = new WritableFont(WritableFont.TIMES,12,WritableFont.BOLD);

WritableCellFormat
headFormat=new WritableCellFormat(fontBold);

headFormat.setAlignment(jxl.format.Alignment.CENTRE);

for(int
i=0;i<=arrCols.length-1;i++){

Label
cell=new Label(i,0,arrCols[i],headFormat);

sheet.addCell(cell);

}

//表体

WritableFont
fontNormal = new WritableFont(WritableFont.TIMES,12);

WritableCellFormat
bodyFormat=new WritableCellFormat(fontNormal);

bodyFormat.setAlignment(jxl.format.Alignment.CENTRE);

int
j=1;

while(rs.next()){

for(int
i=0;i<=arrFields2.length-1;i++){

//System.out.println(arrFields2[i]+":"+rs.getString(arrFields2[i]));

//Label
cell=new Label(i,j,rs.getString(i)); rs.getString(序号) 值会变化,停用

Label
cell=new Label(i,j,rs.getString(arrFields2[i]),bodyFormat);

sheet.addCell(cell);

}

j++;

}

//保存book

book.write();

book.close();

InputStream
inStream=new FileInputStream(filePath);

return
inStream;

}

创建sheet

//获取4个区域的商户

public static
InputStream GetRegionShops(double lon,double
lat,String filePath) throws
ClassNotFoundException, SQLException, IOException, RowsExceededException,
WriteException{

WritableWorkbook book=Workbook.createWorkbook(new
File(filePath));

String[] sheetNames={"西北区","东北区","西南区","东南区"};

//第i页

for(int i=0;i<=sheetNames.length-1;i++){

WritableSheet
sheet= book.createSheet(sheetNames[i],i);

}

 book.write();  //book.write如写在循环里面,只创建1sheet

book.close();

System.out.println("Excel输出完成");

InputStream inStream=new
FileInputStream(filePath);

return inStream;

}

获取sheet

book.getSheet(i)

字体

//字体

WritableFont wf=new
WritableFont(WritableFont.TIMES,10,WritableFont.BOLD);

WritableCellFormat cf=new
WritableCellFormat(wf);

new Label(0,0,"商户内部编",cf)

设置列宽

WritableSheet.setColumnView(int i,int width);

居中

WritableFont wf=new
WritableFont(WritableFont.TIMES,10,WritableFont.BOLD);

WritableCellFormat cf=new
WritableCellFormat(wf);

cf.setAlignment(Alignment.CENTRE);


上一篇:[翻译] ASP.NET Core 利用 Docker、ElasticSearch、Kibana 来记录日志


下一篇:提升程序的特权(AdjustTokenPrivileges)