B/S架构的概念
B/S架构(Browser/Server,浏览器/服务器模式),是互联网兴起后的软件体系结构,该结构将 系统功能实现的主要业务逻辑集中到服务器端,极少数业务逻辑在浏览器实现,浏览器通常负责完 成与用户的交互任务,服务器通常负责数据的管理。
JavaWeb
使用Java语言进行动态Web资源开发技术的统称
Tomcat服务器
Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试Servlet、JSP
- bin 主要存放二进制可执行文件和脚本
- conf 主要存放各种配置文件
- lib 主要用来存放Tomcat运行需要加载的jar包
- logs 主要存放Tomcat在运行过程中产生的日志文件
- temp 主要存放Tomcat在运行过程中产生的临时文件
- webapps 主要存放应用程序,当Tomcat启动时会去加载该目录下的应用程序
- work 主要存放tomcat在运行时的编译后文件
启动服务 使用bin目录下的批处理文件startup.bat来启动Tomcat服务器
关闭服务 使用bin目录下的批处理文件shutdown.bat来关闭Tomcat服务器
启动信息乱码的处理方式
conf/logging.properties文件修改为 java.util.logging.ConsoleHandler.encoding = GBK
配置文件
server.xml文件是服务器的主配置文件,可以设置端口号、设置域名或IP、默认加载的项目、请求编码
<Connector port="8888" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
Servlet
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,是Java语言编写 的服务器端程序,换句话说,Servlet就是运行在服务器上的Java类。
Servlet用来完成B/S架构下客户端请求的响应处理,也就是交互式地浏览和生成数据,生成动态Web内容。
步骤
建立一个Java Web Application项目并配置Tomcat服务器。
自定义类实现Servlet接口或继承 HttpServlet类(推荐) 并重写service方法。
将自定义类的信息配置到 web.xml文件并启动项目
Servlet接口
javax.servlet.Servlet接口用于定义所有servlet必须实现的方法
GenericServlet类
javax.servlet.GenericServlet类主要用于定义一个通用的、与协议无关的servlet,该类实现了 Servlet接口
HttpServlet类
javax.servlet.http.HttpServlet类是个抽象类并继承了GenericServlet类。
用于创建适用于网站的HTTP Servlet,该类的子类必须至少重写一个方法
- void doGet(HttpServletRequest req, HttpServletResponse resp) 处理客户端的GET请求
- void doPost(HttpServletRequest req, HttpServletResponse resp) 处理客户端的POST请求
- void service(HttpServletRequest req, HttpServletResponse resp) 根据请求决定调用doGet还是 doPost方法
Servlet 的生命周期
- 构造方法只被调用一次,当第一次请求Servlet时调用构造方法来创建Servlet的实例。
- init方法只被调用一次,当创建好Servlet实例后立即调用该方法实现Servlet的初始化。
- service方法被多次调用,每当有请求时都会调用service方法来用于请求的响应。
- destroy方法只被调用一次,当该Servlet实例所在的Web应用被卸载前调用该方法来释放当前占用 的资源。
ServletRequest接口
主要用于向servlet提供客户端请求信息,可以从中获取到任何 请求信息
Servlet容器创建一个ServletRequest对象,并将其作为参数传递给Servlet的service方法
- String getParameter(String name) 以字符串形式返回请求参数的值,如果该参数不存在,则返回空值
- String[] getParameterValues( String name) 返回一个字符串对象数组,其中包含给定请求参数所具有的所有 ,如果该参数不存在,则返回空值 Enumeration
- Map<String, String[]> getParameterMap() 返回请求参数的键值对,一个键可以对应多个值
- String getRemoteAddr() 返回发送请求的客户端或最后一个代理的IP地址
- int getRemotePort() 返回发送请求的客户端或最后一个代理的端口号
HttpServletRequest接口
-
javax.servlet.http.HttpServletRequest接口是ServletRequest接口的子接口,主要用于提供HTTP 请求信息的功能
-
可直接通过HttpServletRequest对象提供的一系列get方法获取请求头数据
-
String getRequestURI() 返回此请求的资源路径信息
-
String getMethod() 返回发出此请求的HTTP方法的名称,例如GET、POST
-
String getQueryString() 返回路径后面请求中附带的参数
-
String getServletPath() 返回此请求中调用servlet的路径部分
ServletResponse接口
javax.servlet.ServletResponse接口用于定义一个对象来帮助Servlet向客户端发送响应。
Servlet容器创建ServletResponse对象,并将其作为参数传递给servlet的service方法。
- PrintWriter getWriter() 返回可向客户端发送字符文本的PrintWriter对象
- String getCharacterEncoding() 获取响应内容的编码方式
- void setContentType(String type) 如果尚未提交响应,则设置发送到客户端响应的内容类型。内容类型 可以包括字符编码规范,例如text/html;charset=UTF-8
HttpServletResponse接口
javax.servlet.http.HttpServletResponse接口继承ServletResponse接口,以便在发送响应时提供 特定于HTTP的功能
- void sendRedirect(String location) 使用指定的重定向位置URL向客户端发送临时重定向响应
Servlet接收中文乱码
解决POST接收乱码
request.setCharacterEncoding("utf-8")
解决GET接收乱码
// 接收到get请求的中文字符串
String name = request.getParameter("name");
// 将中文字符重新编码,默认编码为ISO-8859-1
String userName = new String(name.getBytes("ISO-8859-1"),"utf-8");
重定向
首先客户浏览器发送http请求,当web服务器接受后发送302状态码响应及对应新的location给客户浏览器,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location 地址,服务器根据此请求寻找资源并发送给客户
重定向的实现
-
void sendRedirect(String location) 用指定重定向位置URL向客户端发临时重定向响应
// 指定转发地址 response.sendRedirect("www.baidu.com");
重定向的特点
- 重定向之后,浏览器地址栏的URL会发生改变
- 重定向过程中会将前面Request对象销毁,然后创建一个新的Request对象
- 重定向的URL可以是其它项目工程
转发
一个Web组件(Servlet/JSP)将未完成的处理通过容器转交给另外一个Web组件继续处理,转发 各个组件会共享Request和Response对象
转发的实现
绑定数据到Request对象
- Object getAttribute(String name) 将指定属性值作为对象返回,若给定名称属性不存在,则返回空值
- void setAttribute(String name,Object o) 在此请求中存储属性值
获取转发对象 转发
-
RequestDispatcher getRequestDispatcher(String path) 返回一个RequestDispatcher对象,该对象充当位于给定路径上的资源的包装器
-
void forward(ServletRequest request, ServletResponse response) 将请求从一个servlet转发到服务器上的另一个资 源(Servlet、JSP文件或HTML文件)
// request对象中设置属性信息 request.setAttribute("key1", "value1"); // 获取转发对象 指定目标组件 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/targetServlet"); // 转发 requestDispatcher.forward(request, response);
转发的特点
- 转发之后浏览器地址栏的URL不会发生改变
- 转发过程中共享Request对象
- 转发的URL不可以是其它项目工程
重定向和转发的比较
状态管理
Web程序基于HTTP协议通信,而HTTP协议是”无状态”的协议,一旦服务器响应完客户的请求之后,就断开连接,而同一个客户的下一次请求又会重新建立网络连接。
服务器程序有时是需要判断是否为同一个客户发出的请求,多次交互作为一个整体,将多次交互所涉及的数据保存下来,即状态管理
- 客户端管理:将状态保存在客户端。基于Cookie技术实现。
- 服务器管理:将状态保存在服务器端。基于Session技术实现。
Cookie
客户端以“名-值”形式进行保存的一种技术
浏览器向服务器发送请求时,服务器将数据以Set-Cookie消息头的方式响应给浏览器,然后浏览器 会将这些数据以文本文件的方式保存起来
当浏览器再次访问服务器时,会将这些数据以Cookie消息头的方式发送给服务器
-
Cookie(String name, String value) 创建Cookie
-
void addCookie(Cookie cookie) 添加Cookie对象到响应
-
Cookie[] getCookies() 返回此请求中包含的所有Cookie对象
-
String getName() 返回此Cookie对象中的名字
-
String getValue() 返回此Cookie对象的数值
-
void setValue(String newValue) 设置Cookie的数值
// 获取客户端发来的Cookie Cookie[] cookies = request.getCookies(); for (Cookie tc : cookies) { System.out.println(tc.getName() + "值为:" + tc.getValue()); tc.setValue("新的值"); } // 创建Cookie对象并添加到响应信息中 Cookie cookie = new Cookie("name", "zhangfei"); response.addCookie(cookie);
Cookie的生命周期
默认情况下,浏览器会将Cookie信息保存在内存中,只要浏览器关闭,Cookie信息就会消失
-
int getMaxAge() 返回cookie的最长使用期限(以秒为单位)
-
void setMaxAge(int expiry) 设置cookie的最长保留时间(秒)
// 获取Cookie信息的默认使用期限 int maxAge = cookie.getMaxAge(); // 设置Cookie有效期 // 负数表示浏览器关闭后失效 0表示马上失效 cookie.setMaxAge(60*10); // 秒 600秒
Cookie的路径问题
浏览器在访问服务器时,会比较Cookie的路径与请求路径是否匹配,访问的请求地址必须符合Cookie的路径或者其子路径时,浏览器才会发送Cookie信息
-
void setPath(String uri) 设置cookie的路径信息
cookie.setPath(request.getContextPath() + "/hello")
Cookie的特点
- 只用于存储少量、非敏感信息
- 将状态数据保存在浏览器端,不安全
- 保存数据量有限制,大约4KB左右
- 只能保存字符串信息
- 用户可以通过浏览器设置为禁止使用
Session
Session本意为"会话"的含义,是用来维护一个客户端和服务器关联的一种技术
浏览器访问服务器时,服务器会为每一个浏览器都在服务器端的内存中分配一个空间,用于创建一个Session对象,该对象有一个id属性且该值唯一,称为SessionId,并且服务器会将这个 SessionId以Cookie方式发送给浏览器存储
浏览器再次访问服务器时会将SessionId发送给服务器,服务器可以依据SessionId查找相对应的Session对象
-
HttpSession getSession() 返回此请求关联的当前Session,若此请求没有则创建一个
-
boolean isNew() 判断是否为新创建的Session
-
String getId() 获取Session的id
-
Object getAttribute(String name) 返回在此会话中用指定名称绑定的对象,如果没有对象在 该名称下绑定,则返回空值
-
void setAttribute(String name, Object value) 使用指定的名称将对象绑定到此会话
-
void removeAttribute(String name) 从此会话中删除与指定名称绑定的对象
// 获取session对象 HttpSession session = request.getSession(); // 判断是否为新对象 boolean isNew = session.isNew(); // 获取id String id = session.getId(); // 设置属性 session.setAttribute("name", "hello"); // 获取属性 session.getAttribute("name"); // 删除 session.removeAttribute("name");
Session的生命周期
为了节省服务器内存空间资源,服务器会将空闲时间过长的Session对象自动清除掉,服务器默认的超时限制一般是30分钟
int getMaxInactiveInterval() 获取失效时间
void setMaxInactiveInterval(int interval) 设置失效时间
// 获取Session对象
HttpSession session = request.getSession();
// 获取对象的默认失效时间并打印
int maxInactiveInterval = session.getMaxInactiveInterval();
System.out.println("默认失效时间为:" + maxInactiveInterval); // 1800
// 修改失效时间
session.setMaxInactiveInterval(1200); // 秒
也可以通过配置web.xml文件修改失效时间
<session-config>
<session-timeout>30</session-timeout>
</session-config>
Session的特点
- 数据比较安全。 能够保存的数据类型丰富,而Cookie只能保存字符串
- 能够保存更多的数据,而Cookie大约保存4KB
- 数据保存在服务器端会占用服务器的内存空间,如果存储信息过多、用户量过大,会严重影响服务器的性能