文章目录
第一部分:Servlet
servlet简介
-
servlet 是什么?
a)就是一个java 类。.
b)服务器端的小程序。
c)作用是处理用户请求
-
servlet 的三种实现方式:
a)实现 Servlet接口
b)继承 GenericServlet类
c)继承 HttpServlet类
-
Servlet的部署
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<servlet>
<!--servlet-name可以任意,但必须唯一 建议和类名一致-->
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
</servlet>
<!-- 一个Servlet可以对应对个servlet-mapping -->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!-- 访问名称,也叫请求路径 一般是给前端开发人员使用的 必须有/, /表示上下文-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
- 请求流程
描述:
用户发起一个请求后,由服务器接收处理,根据web.xml文件中的配置信息,查找所请求的资源是否存在,如果不存在则返回错误(404)。当找到资源后(servlet),检查该Servlet对象是否存在,如果不存在则创建该对象,如果存在则执行相应的处理方法。处理方法执行以后将返回处理结果给web服务器,web服务器根据结果进行相关处理后,返回给浏览器。浏览器显示相应的处理结果。
Servlet的生命周期:
对象是由容器通过反射产生的
Servlet类的实例化时机:
-
配置了容器启动时调用(容器启动的时就会实例化)
在servlet标签中进行如下配置。(数字越大,优先级越高)
-
当请求时,该serviet对象不存在时
HttpServletResponse
-
HttpServletResponse 对象的产生:
当服务器接收到请求后会产生两个对象:请求对象,响应对象,并且将这两个对象给Servlet. -
响应数据:
getOutputStream(): 字节流数据
getWriter(): 字符流数据
getOutputStream和getWriter互斥;同时调用会出错。原因:当调用getOutputStream或getWriter后,服务器接收后会将数据进行处理。处理完成后会检查流对象是否关闭,如果没有关闭,服务器会自动关闭。流关闭后就无法再使用。
-
setContentType( "text/html; charset=UTF-8")
指定响应内容的编码格式(浏览器的编码)。
HttpServetRequest:
HttpServetRequest. 请求对象。 从客户端发送请求,服务将会创建该对象
有哪些请求?
- a)在浏览器地址栏,直接输入l地址。
- b)超链接
<a href="rI!"><a>
- c)Js中: locationhref-“url”;
- d)Form表单的提交
注:
如果使用get提交,那么所提交的参数时追加到url后的;以?name=ovalue ;这样的方式追加a,b,c都是 get 方式。d如果method=“get”,也是get提交。.如果使用post提交,那么数据将会被封装到form datao
Get和post的区别:
-
Get提交:
长度有限
安全性较差
效率相对比post高 -
Post提交:
长度没有限制
安全性较get好
效率相对get差。
;
放在webroot下面的HTML文件是可以直接访问的,但是在WEB-IN下的不能直接访问。
HttpServletRequest 有getParameter (“feldName”) :获取提交的数据。
重定向:
- 由
resp.sendRedirect("url");
实现。 - 当使用重定向时,服务器会将重定向的地址(“URL")交给浏览器。浏览器根据新的url,重新发起一个新的请求。
解决乱码:
request的常用方法:
getConotextPath()
获取上下文路径getRequestURI()
获取URI(URL中端口号后的那一部分)getRequestURL()
获取URLgetRemoteAddr()
获取请求来源的IP地址getRemoteHost()
获取请求来源的主机名
对修改和查询功能的实现
以上操作须有两个步骤来完成:
- 第一步,点击修改按钮进行查询的Servlet 在查询的Servlet中,要根据被点击的书籍的id去数据
库中查询该id所对应的书籍记录。
分析查询Servlet:
由于查询Servlet需要id去查询指定的书籍记录,那么要将id传给查询Serylete
将数据提交到Servlet中有两种方式: post 和getpost方式需要表单, get方式可以
指定超链接。
如果是post方式:
修改按钮代码为:
如果是get方式:
将form中的method设为get
<a href-"selectByld?id=2">修改</2>
如果有多个参数可以用&符号链接起来
- 将查询结果展示浏览器:
在编辑修改页面时,需要将书籍对象的值设入表单域中。
注意:需要将id以隐藏域的方式进行设置。因为在修改数据时,需要根据id来修改。之所以隐藏是因为在修改界面中并不需要显示id
Session
- Session:是浏览器与服务器之间的一次会话。包含多个请求。
- Session 是服务器为每个客户在服务端开辟一块空间。我们客户端的发过来的信息存储在这一片空间,方便我们需要使用的时候取出使用。因为一次会话会有很多次请求,在之后的请求中我们可能需要用到第一次请求的(之前的请求都有可能)参数信息,如果我们能在第一次请求的时候存储参数信息,这时我们便能将参数取出使用。
- 这个使用场景很常见,比如我们登录一个网站后,在站内不断跳转页面的同时使用户的名字和登录时间一直显示在页面的上方。
使用方法:
- 获取Session:
reg.getSession();
- 向Session放数据:
session.setAttribut("key",value);
value可以是任意类型,包括对象。与cookie只能存储字符串不同。 - 从session中取数据
HttpSession session = req.getSession();
String name= (String)session.getAttribute("username") ;
- 从session中移除值:
session.temoveAttribute(key);
常见问题:
-
每个用户都有自己的session,服务器是根据sessionld来区分的。那么服务器是如何知道不同客户的sessionId的呢?
客户端和服务器“第一次”建立请求时(其实不一定是第一次,因为第一次可能请求的只是一个HTML文件,并不需要返回数据),服务器为该客户分配一个session对象,并且指派个sessionld,当服务器响应客户端时,会将这个sessionld以cookie的方式写入浏览器的内存中。当该客户再一次发起请求时,会将该ssionId传给服务器。服务器根据接收到的sessionId,去查找该客户对应的session. -
Session 的建立时机:
request getSession(true)时。(一般情况请求servletisp)时。 -
浏览器关闭时,session 是否被删除?
不会;因为session是存储在服务器端的;浏览器被关并不会导致session马上被删除。 -
浏览器关闭时,是否能找到原来的session?
默认情况下,不能;因为ssionId是存储在浏览器内存中(Cookie),没有了ssionld就无法查找对应的session。但是可以通过设置cookie的保留时间使得ssionId被保留下来。从而能找到原来的session。 -
session 何时被删除?
- 超时;
设置session失效时间;
指定在servlet容器使此会话失效之前客户端请求之间的时间间隔,以秒为单位。负数时间指示会话永远不会超时。
ion.setMaxInactiveInterval(10*60) ;
- 手动调用
Session.invalidate();
/使session失效 - 服务器关闭或停止.
Cookie
- Cookie(小甜饼);服务端将文本信息存储在客户端。注意只能存储文本信息,cookie可以存储在磁盘中。
- sessionId就是存储在cookie中; 一些网站的记住密码功能往往就用cookie实现
- cookie中的信息以键值对存储
服务器如何将数据写入客户端(cookie):
//新建cookie对象
Cookie ck = new Cookie("name","siggy");
//通过response对象,将cookie写入客户端;
response.addCookie(ck);
cookie 不去设置失效时间,默认用完删除。
setMaxAge(int expiry)
设置cookie的失效时间。如果等于0,那么是删除。如果是小于0,那么不存储。如果大于0,是所设置的秒数。
- 当seMaxAge(-1):不存储指的是不存磁盘,但是在浏览器中存在。当关闭浏览器就没有了。
- 当等于0的时候,cookie会回写到客户端,但是会被删除。(立即删除),下一次请求将不会把该cookie携帶到服务器端。
- 当大于0的时候,会存在磁盘上,当浏览器关闭,下一次请求时一样会携带到服务器上。
- 当不去设置setMaxAge时, cookie存入内存中。
取出cookie中的值:
//获取cookie值
Cookie[] cks = reg.getCookies();
if(cks !=nu11)
for(Cookie ck:cks){
System.out.print1n( ck.getName()+-"---------"+ck.getValue());
}
Cookie的name和value;会随着请求到服务器端。
Cookie的其它信息由浏览器管理。
cookie的注意点:
- cookie没有修改;如果想修改某个cookie的值,只需新建一个name相同的cookie,即可将原来的覆盖。Cookie 也不需要删除,当cookie到期有浏览器来维护。
- Cookie是带有domain(域名)的,每个web应用只能读取自己的cookie; cookie和浏览器有关,不同浏览器cookie是不能共享的。
- Cookie是由浏览器管理,那么cookie是可以被禁用的。
Cookie 和 Session的比较
Cookie:
- 可以存放大量的文本数据。
- 安全性低,效率低
Session:
- 数据量小,安全性高,效率高。
在cookie中可以存储对象,但是需要转换为字符串形式。
Student stu = new Student(1,"张安","男",23);
session.setAttribute("stu",stu);
Cookie ck = new Cookie ("stu","1_张安男_23");
session与Cookie的区别总结:
- session存储数据在服务器端,Cookie在客户端
- session没有数据大小限制,Cookie有
- session数据安全,Cookie相对于不安全
cookie中文处理
Cookie写的时候需要编码:
resp.setCharacterEncoding("utf-8");
String name="姓名";
String value="张三";
//URLEncoder--编码的过程URLEncoder.encode(name, "utf-8")
Cookie ck = new Cookie(URLEncoder.encode(name, "utf-8") ,URLEncoder.encode(value, "utf-8"));
resp.addCookie(ck);
resp.sendRedirect("index.jsp");
读取cookie中的中文的时候需要解码:
Cookie[] cks = request.getCookies();
for(Cookie ck:cks){
//对中文需要进行解码URLDecoder . decode(ck. getName(),"utf-8")
out.print(URLDecoder.decode(ck.getName(), "utf-8")+"----"+URLDecoder.decode(ck.getvalue(), "utf-8"));
}
ServletContext
ServletContext是服务器端的一块公共的存储区域。可供所有客户存取数据。全局区域。一个web应用程序只有一个ServletContext.
在Servlet中获取ServletContext的两种方法:
ServletContext servletContext = this.getSeryletContext();
ServletContext servletContext1 = reg.getSession().getServletContext();
ServletContext的设值,取值,和删除:
servletContext.setAttribute("count", 1);
servletContext.getAttribute("count");
servletContext.removeAttribute("count");
ServletContext用处:
可以读取全局配置文件:
<!--配置全局变量所有servlet都能访问-->
<context -param>
<param-name>teachername</param-name>
<param-value>siggy</param-value>
</context -param>
Servlet中代码
String value = this.getServletContext( ).getInitParameter("teachername");
读取资源文件:
资源文件放于:根目录下和(WEB-INF)同级
InputStream is=this.getServletContext().getResourceAsStream(" db.properties");
Properties pros = new Properties();
pros.load(is);
resp.getWriter().print(" driver:"+pros.getProperty(" driver")+"<br/>");
resp.getWriter().print("ur1:" +pros.getProperty("ur1")+"<br/>");
如果资源文件在src下:
InputStream is =
ContextServlet.class.getClassLoader().getResourceAsStream("db.properties");
作为全局变量的运用;网站计算器,网络聊天室
//网站计数器;
ServletContext sc = this.getServletContext();
if(sc.getAttribute("count")==nu11){//第一个访问者
sc.setAttribute("count", 1);
}else{
int count= (Integer)sc. getAttribute("count");
sc.setAttribute("count", ++count) ;
}
resp.getWriter().print("您是第"+sc. getAttribute (" count ")+ "位访问者");
ServletContext生命周期:和服务器同生共死。
Request,session,ServletContext 存放时间的长短比较:
ServletContext
最长,和服务器一样Session
次之,在一个会话范围失效时间Request
最短,在请求范围
第二部分:JSP
JSP简介
JSP:java server page,动态页面;指数据是动态改变。
Jsp本质上是一个Servlet。运行时,会自动转化为Servlet。
常见的动态页面技术:
- JSP:应用广
- php( php+apachemysl+linux)
- asp.net (微软,学习成本低)
JSP的执行流程:
JSP组成部分:
简单的JSP案例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
This is my JSP page. <br>
<%
//姓名
String name = "张三";
%>
<%! String getStudentName(){
return "李四";
} %>
<h1>hello:<%=name %>></h1>
<h2>学生姓名:<%=getStudentName() %></h2>
</body>
</html>
jsp9大内置对象:
request
请求response
响应对象session
会话application
相当于ServletContextout
输出config
取配置信息ServletConfigpageContext
page
页面对象exception
异常对象
静态导入指令:
<%@include file="validate.jsp"%>
将被导入页面和导入页面合在一起进行翻译,编译。最后产生一个Servlet;那么两个页面的变量名不能重复。类似于函数的调用。
jsp 的动态导入:
<isp: include page= "val idate.jsp "></isp: include>
动态导入:被导入页面和导入页面分别翻译,编译,产生二个servlet。所以两个页面的变量名可以重复。都会被执行。
注意:
静态导入只会执行一次,动态导入执行2次。那么如果导入页面需要用被导入页面的结果来判断是否执行,那么应该用静态导入。
第三部分:软件架构模式(MVC)
Javabean简介:
Javabean; 分为两类:实体Bean,业务Bean
- 实体Bean:实体类,特指属性是private修饰,然后提供getset方法。不提供业务方法。一个实体类一般对应数据库里的一张表。
- 业务Bean:除实体bean以外,都是业务Bean.
常见软件架构模式:
-
jsp + javaban(Mdell模式):
特点:效率高,逻辑混乱,适合小项目 -
JSP + Servlet + javaben(ModelI模式 ,MVC模式的前身)
jsp:数据的展示(视图)
Servlet:逻辑控制(控制器)
Javabean:业务处理(模型) -
MVC设计模式: Model (模型), View (视图), Controller (控制器)
好处:便于分工,适合大项目,易于维护和扩展。
使用JSP + Servlet + javaben设计模式的开发要点:
- jsp只做数据的展示。尽量不写java小脚本。
- Servlet;对用户输入数据的封装(
request.getParamer ()
),对业务处理结果的设置(request.setAttribute()
) ;控制页面的流向(重定向,转发)。 - javaBean:做相关的业务处理。
JSP:
<body>
<form action="LoginServlet" method="post">
用户名:<input type="text" name="name"></input> <br>
密码:<input type="password" name="pwd"></input> <br>
<input type="submit" value="提交"></input>
</form>
</body>
Servlet:
package cn.siggy.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.siggy.dao.UserDao;
import cn.siggy.entity.User;
public class LoginServlet extends HttpServlet {
private UserDao userDao = new UserDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
//数据封装
User user = new User();
user.setName(req.getParameter("name"));
user.setPwd(req.getParameter("pwd"));
//调用相应业务进行处理
user = userDao.login(user);
//控制页面流向,并且处理结果
if(user!=null){ //登录成功
req.getSession().setAttribute("user", user);
resp.sendRedirect("list"); //重定向
}else{ //登录失败
req.setAttribute("msg", "密码或用户名错误!!!");
req.getRequestDispatcher("login.jsp").forward(req, resp); //转发
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
this.doGet(req, resp);
}
}
JavaBean:
public class UserDao {
//登录
public User login(User user){
if("huicheng".equals(user.getName()) && "12345".equals( user.getPwd() ) ){
return user;
}else{
return null;
}
}
}
EL表达式:
EL全名为Expression Language
EL语法很简单,它最大的特点就是使用,上很方便。接下来介绍EL主要的语法结构:
${sessionScope.user.sex}
如果不填scope;那么默认的查找顺序是:
pageScope--->reguestScope--->sessionScop---->applicationScope
所有EL都是以$ {为起始;以}为结尾的。上述EL范例的意思是:从Session的范围中,取得用户的性别。假若依照之前JSP Scriptlet的写法如下:
User user = (User)session.getAttribute("uer");
String sex = user.getSex();
两者相比较之下,可以发现EL的语法比传统JSP Scriptlet 更为方便、简洁。
在JavaScript中也可以使用EL表达式。
JSTL
jstl:JSP Standard Tag Library(JSP标准标记库)
使用步骤:
- a)导入相关ja包
- b)在JSP中导入标签库
<%@taglib uri="http://java.sun.com/isp/istl/core" prefix="c"%>
迭代标签的使用:
<!--迭代标签--items中填e1表达式(要遍历的数组) var迭代变量-->
<c:forEach items="${list }" var="bean">
<tr>
<td>${bean.id}</td>
<td>${bean.name }</td>
<td>${bean.price }</td>
<td>${bean.author }</td>
<td>${bean.pubDate }</td>
</tr>
</c:forEach>
jstl的条件标签判断:
<c:if test="${1 == 1 }">
真
</c:if>
多个条件当when中的条件为真,执行when中的代码,当when中的条件为false时,执行oterwise中的代码。
<c: choose>
<c:when test="${1 eg 2 }">
1==2
</c :when>
<c:otherwise>
1!=2
</c: otherwise>
</c:choose>
通用标签:
<!--设置参数-->
<c:set var="t" scope= "session" value= "23"></c:set>
<!--输出参数-->
<c:out value="${t }"></c :out>
<hr>
<!--删除-->
<c:remove var= "t"/>
<!--输出参数-->
<c:out value="${t }"></c:out>
Filter
Filter过滤器:对用户请求进行预处理;对web应用进行资源控制。
Filter 工作流程:
类似于递归调用
filter 生命周期:
Filter是在服务器启动就已经完成了实例化和初始化的。由服务器来管理。
文件上传:
1、注意的要点:
- 表单的提交方式一定是post
- 在表单中要设置
enctspe=" multipatfrm-dta"
以二进制流的方式传数据给服务器
2、浏览器上传文件信息,会掺杂其他请求信息,如果直接读取文件并不能得到文件本身。需要进行单独解析处理。
有公共类库来处理这个事情。比如:Smartupload(过时),apache 下的Commons fileupload来处理。
AJAX
AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。通过AJAX你的JavaScript可使用JavaScript的XMLHttpRequest对象来直接与服务器进行通信。通过这个对象,你的JavaScript可在不重新加载页面的情况与Web服务器交换数据。
AJAX在浏览器与Web服务器之间使用异步数据传输( HTTP请求) ,这样就可使网页从服务器请求少量的信
息,而不是整个页面。
AJAX可使因特网应用程序更小更快、更友好。
AJAX是一种独立于Web服务器软件的浏览器技术。
AJAX是浏览器支持的,AJAX的要点是XMLHttpRequest对象。不同的浏览器创建XMLHttpRequest对象的方法是有差异的。
使用xmlHttpRequest对象3个步骤:
- 创建xmlHttpRequest对象
- 发送异步请求open(), send()
- 编写回调函数onreadystatechange()
ajax的特点:
-
页面没有改变
-
异步发送请求,获取数据
-
由于异步,所以数据响应时间不确定
-
不能与同步一起使用(同步的业务数据不能通过异步来得到)
总结:
局部刷新数据。在不改变页面的情况下,获取服务器数据信息。
应用场景:
- 注册用户名的验证
- 自动补全
- CURD
监听器:
Servlet有6个事件和8个监听器,主要提供了ServletContext HttpSession,ServletRequest的监听。.
注意: servlet filter listener的初始化顺序:
listener–>filter—>servlet
代码:
public class ContextListener imp1ements ServletContextListener{
//应用销毁---服务器停止触发
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println( "服务器停止");
}
/ /应用启动时将触发
public void contextInitialized(ServletContextEvent, arg0) {
System.out.print1n( "服务器启动");
}
}
配置文件:
<listener>
<listener-class>cn.siggy.listener.Contextlistener</listener-class>
</listener>