1、静态页面(html)
2、动态
用户可以输入数据,和页面交互。
3 BS和CS的区别
BS :Browser Server(WEB 服务器) CS : Client(qq tcp/ip协议) Server
写一个WEB服务器.
package 细说Servlet;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class MyWebServer {
public static void main(String[] args) {
ServerSocket ss;
Socket s = null;
OutputStream os = null;
BufferedReader br = null;
try {
ss = new ServerSocket();
System.out.println("在9999端口等待...");
s = ss.accept();
//提示一句话
System.out.println("连接成功");
os = s.getOutputStream();
br = new BufferedReader(new FileReader("E:/hello.html")); String buf = "";
while ( (buf = br.readLine()) != null) {
//系统使用默认的字符集转换
os.write(buf.getBytes());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
br.close();
os.close();
s.close(); } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
Tomcat本身也是java程序,必须配置jdk
netstat -an 查看
netstat -anb
可以在setup.bat 中添加JAVA_HOME= jdk的目录 ,来配置电脑的jdk
conf配置文件:
server.xml
web.xml:该文件配置与web应用相关的信息,web应用相当于一个web站点
tomcat-users.xml:配置用户密码
lib:存放存放tomcat所需要的jar包
log:存放日志,
webapps该目录放置web站点
work:存放jsp被访问后生成对应的servlet文件
----------------------------------------------------------
Tomcat怎么管理虚拟目录:我们希望tomcat管理其他目录的站点
在conf文件中配置server.xml中</host>上一行添加该语句
context有几个属性:
path:
docBase:
reloadable:若设置true,表示tomcat会自动更新web应用,这个开销大,建议在开发过程中设为true,发布后设为false
如何配置自己主机名,我们在访问一个网站时,不可能使用 http://localhost:8080/应用/资源名 的方式去访问网站,实际上使用 www.taobao.com 的方式,如何实现呢?
实现的步骤如下:
(1)修改 C:\Windows\System32\drivers\etc 下hosts文件,添加这么一条语句: 127.0.0.1 www.taobao.com
(2)在tomcat 的server.xml文件添加主机名
<Host name="www.taobao.com" appBase="d:\web3”> <Context path="/" docBase="d:\web3" /> </Host>
(3)在d:/web3添加一个/WEB-INF/web.xml 把 hello2.html设为首页面 如果连端口都不希望带,则可以吧tomcat的启动端口设为80即可
当使用http://127.0.0.1:8080时会自动跳转到localhost,如何修改主机名不跳转到localhost
如何配置默认主机:
在tomcat/conf/server.xml 文件
<Engine name="Catalina" defaultHost="主机名">
如:<Engine name="Catalina" defaultHost="www.show.com">
继承HttpServlet 需要实现doPost和doGet
安全性看,get弱于post;提交的内容来看,post理论上不限制,在实际开发中不要太大;
Servlet的一些细节:
(1)对一个注册的servlet可以多次映射
(2)通配符:
Servlet通过对外路径访问可以通过通配符替换,一是 匹配 *. 匹配.do结尾的(这种级别最低) 二是 /abc/* 表示当前路径下的所有
(3)Servlet的单例问题,当servlet被第一次访问后就会被加载到内存,以后该实例对各个请求服务,即在使用中是单例(多个服务共享一个变量)
因为Servlet是单例模式,因此会出现线程安全问题,比如售票系统(成员变量),如果不加同步机制会出现问题。
这里有一个原则: 1. 如果一个变量需要多个用户共享,则应该在访问该用户变量时,加同步机制 synchronized(对象) {}
2. 如果一个变量不需要共享,只需在doGet和doPost中定义(局部变量)即可,这样不会存在线程不安全问题
(4) <load-on-setup>num</load-on-setup> 其中num表示servlet被init的顺序
(5) servletConfig
-------------------------------------------------------------
HTTP协议
http是建立在tcp/ip协议之上的,全称是超文本传输协议
http1.0短连接,http1.1长连接(就像打电话一样,短连接是指打完就挂掉了,长连接会保存一段时间),所谓的长和短是指持续的时间,长连接大概是30秒
http的请求:
结构:
请求行;消息头,并不是消息头都一样;内容
referer:用来记录是从哪个页面进来的,当直接在浏览器中输入url时,返回值为null。所以可用来做防盗链
String referer = request.getHeader("referer");
if (referer == null || !referer.startsWith("http://localhost:8888/ServletPro/")) {
response.sendRedirect("/ServletPro/Error");
}
http的响应状态行举例说明
2200 就是整个请求和响应没有错误,这个最常见
302 当你请求一个资源时,服务器返回302表示,让浏览器转向另一个资源。比如request.sendRedirect("/web应用名/资源名");
response.sendRedirect("/ServletPro/Error"); // 和下面两句等价
response.setStatus(302);
response.setHeader("Location", "/ServletPro/Error");
404 not found
500 服务器出错
举例说明refresh的作用:
response.setHeader("Refresh", "5;url=http://www.baidu.com"); //5秒之后跳转到百度
下载文件 原理:先由服务器读取,然后再从服务器写入浏览器
//1、设置参数
response.setHeader("Content-Disposition", "attachment; filename=abc.png");
//2、获得全路径
String path = this.getServletContext().getRealPath("/images/abc.png");
//System.out.println(path);
FileInputStream fis = new FileInputStream(path); //读取到服务器
byte buff[] = new byte[1024];
int len = 0;
OutputStream os = response.getOutputStream();
while ( (len = fis.read(buff)) > 0) {
os.write(buff, 0, len); //读取到服务器,并由服务器写入浏览器
}
os.close();
fis.close();
缓存页面举例:
我们的浏览器在默认情况下,会缓存我们的页面,这样会出现一个小问题:当我们把光标停在地址栏,然后回车去取页面就会默认从cache中获得
(1)有些网址对及时性要求很高,因此不需要缓存
三种禁止浏览器缓冲
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
httpServletResponse的在说明
getWriter()和getOutputStream()区别:
1、getWriter()用于向客户端返回字符数据
2、getOutputStream()可以回送字符数据,也可以回送字节数据(二进制数据)
OutputStream os = response.getOutputStream();
os.write("hello world".getBytes()); //字符串变成二进制数据
如何选择
我们回送的是字符数据,用getWriter()效率高
我们回送的是字节(binary data) 只能用OutputStream,
---这两个流不能同时使用
sendRedirect()的使用方法:
问题:登录成功时,将用户名显示在登录成功页面
解决方法: 1; 设置静态变量
2;sendRedirect("welcom?uname="+username+"&参数名="+参数值); 参数名为字母组合,参数值为String
在接收方时,String 参数 = request.getParaMeter
3;使用session, session可以传递对象
中文乱码处理
(1).表单
post: 浏览器(utf-8编码方式)提交给web服务器(以iso-8859-1接受) ; request.setCharacterEncoding("utf-8") // 这个还是不好
get:将信息放入请求行中,new String(request.getParameter("userName").getByte("iso-8859-1"), "utf-8")
(2) 超链接 默认是get方式,所以解决同表单中get的处理方式
HttpServletRequest对象的详解:
request.getQueryString() 可以获得请求的数据;
url:是全部的网址 uri 是包含 web层和资源层
request.getRemoteAddr() //获得请求方的ip
request.getRemoteHost() //获得请求仿的主机名
补充一个知识点:当我们下载一个文件时,可能提示框是中文乱码
String temp = java.net.URLEncoder.encode("传奇.mp3", "utf-8");
HttpServletRequest常用方法:
1、获得客户机请求头: getHeader(), getHeaderNames()
2、获取到客户机请求参数
sendRedirect()和forward()区别:
1 叫法不同,sendRedirect()是重定向,转发, forward是转向
2、实际发生的位置不一样,sendRedirect发生在浏览器,forward发生在web服务器
3、用法不一样
request.getRequestDispatche("资源/uri").forward(request, response)
response.sendRedirect("/web应用")
4、能够跳转的地方不同
sendRedirect可以进入任何(包括外边)url, forward只能访问该web应用下的资源
什么叫一次http请求
只要没有停止,也没有回到浏览器重定向,就是一次请求。
如果转发多次,我们浏览器地址栏保留的是第一次转向的那个Servlet URL