1. 使用 JavaEE 版的 Eclipse 开发动态的 WEB 工程(JavaWEB 项目)
1). 把开发选项切换到 JavaEE
2). 可以在 Window -> Show View 中找到 Package Explorer, 并把其拖拽到开发区的左边
3). 在 Servers 面板中新建 Tomcat 服务器. 一定要关联到 Tomcat 安装的根目录
4). 新建一个 Dynamic Web Project. 其中 Target Runtime 需选择 Tomcat6.0
5). 开发 Java WEB 应用
6). 可以通过 run on server 来运行 WEB 项目.
2. Servlet 的 HelloWorld
1). 创建一个 Servlet 接口的实现类.
public class HelloServlet implements Servlet
2). 在 web.xml 文件中配置和映射这个 Servlet
<!-- 配置和映射 Servlet -->
<servlet>
<!-- Servlet 注册的名字 -->
<servlet-name>helloServlet</servlet-name>
<!-- Servlet 的全类名 -->
<servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 需要和某一个 servlet 节点的 serlvet-name 子节点的文本节点一致 -->
<servlet-name>helloServlet</servlet-name>
<!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录. -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
3. Servlet 容器: 运行 Servlet、JSP、Filter 等的软件环境.
1). 可以来创建 Servlet, 并调用 Servlet 的相关生命周期方法.
2). JSP, Filter, Listener, Tag ...
4. Servlet 生命周期的方法: 以下方法都是由 Serlvet 容器负责调用.
1). 构造器: 只被调用一次. 只有第一次请求 Servlet 时, 创建 Servlet 的实例. 调用构造器.
这说明 Serlvet 的单实例的!
2). init 方法: 只被调用一次. 在创建好实例后立即被调用. 用于初始化当前 Servlet.
3). service: 被多次调用. 每次请求都会调用 service 方法. 实际用于响应请求的.
4). destroy: 只被调用一次. 在当前 Servlet 所在的 WEB 应用被卸载前调用. 用于释放当前 Servlet 所占用的资源.
5. load-on-startup 参数:
1). 配置在 servlet 节点中:
<servlet>
<!-- Servlet 注册的名字 -->
<servlet-name>secondServlet</servlet-name>
<!-- Servlet 的全类名 -->
<servlet-class>com.atguigu.javaweb.SecondServlet</servlet-class>
<!-- 可以指定 Servlet 被创建的时机 -->
<load-on-startup>2</load-on-startup>
</servlet>
2). load-on-startup: 可以指定 Serlvet 被创建的时机. 若为负数, 则在第一次请求时被创建.若为 0 或正数, 则在当前 WEB 应用被
Serlvet 容器加载时创建实例, 且数组越小越早被创建.
6. 关于 serlvet-mapping:
1). 同一个Servlet可以被映射到多个URL上,即多个 <servlet-mapping> 元素的<servlet-name>子元素的设置值可以是同一个
Servlet的注册名。
2). 在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
OR
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注意: 以下的既带 / 又带扩展名的不合法.
<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>/*.action</url-pattern>
</servlet-mapping>
7. ServletConfig: 封装了 Serlvet 的配置信息, 并且可以获取 ServletContext 对象
1). 配置 Serlvet 的初始化参数
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.atguigu.javaweb.HelloServlet</servlet-class>
<!-- 配置 Serlvet 的初始化参数。 且节点必须在 load-on-startup 节点的前面 -->
<init-param>
<!-- 参数名 -->
<param-name>user</param-name>
<!-- 参数值 -->
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>1230</param-value>
</init-param>
<load-on-startup>-1</load-on-startup>
</servlet>
2). 获取初始化参数:
> getInitParameter(String name): 获取指定参数名的初始化参数
> getInitParameterNames(): 获取参数名组成的 Enumeration 对象.
String user = servletConfig.getInitParameter("user");
System.out.println("user: " + user);
Enumeration<String> names = servletConfig.getInitParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
String value = servletConfig.getInitParameter(name);
System.out.println("^^" + name + ": " + value);
}
3). 获取 Serlvet 的配置名称(了解)
8. ServletContext
1). 可以由 SerlvetConfig 获取:
ServletContext servletContext = servletConfig.getServletContext();
2). 该对象代表当前 WEB 应用: 可以认为 SerlvetContext 是当前 WEB 应用的一个大管家. 可以从中获取到当前 WEB 应用的各个方面的信息.
①. 获取当前 WEB 应用的初始化参数
设置初始化参数: 可以为所有的 Servlet 所获取, 而 Servlet 的初始化参数只用那个 Serlvet 可以获取.
<!-- 配置当前 WEB 应用的初始化参数 -->
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
方法:
getInitParameter
getInitParameterNames
代码:
ServletContext servletContext = servletConfig.getServletContext();
String driver = servletContext.getInitParameter("driver");
System.out.println("driver:" + driver);
Enumeration<String> names2 = servletContext.getInitParameterNames();
while(names2.hasMoreElements()){
String name = names2.nextElement();
System.out.println("-->" + name);
}
②. 获取当前 WEB 应用的某一个文件在服务器上的绝对路径, 而不是部署前的路径
getRealPath(String path);
代码:
String realPath = servletContext.getRealPath("/note.txt");
System.out.println(realPath);
③. 获取当前 WEB 应用的名称:
getContextPath()
代码:
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
④. 获取当前 WEB 应用的某一个文件对应的输入流.
getResourceAsStream(String path): path 的 / 为当前 WEB 应用的根目录.
代码:
InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
⑤. 和 attribute 相关的几个方法:
9. GET 请求和 POST 请求:
1). 使用GET方式传递参数:
①. 在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。
②. 如果网页中的<form>表单元素的 method 属性被设置为了“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。
③. 使用GET请求方式给WEB服务器传递参数的格式:
http://www.atguigu.com/counter.jsp?name=lc&password=123
④. 使用GET方式传送的数据量一般限制在 1KB 以下。
2). 使用 POST 方式传递参数:
①. POST 请求方式主要用于向 WEB 服务器端程序提交 FORM 表单中的数据: form 表单的 method 置为 POST
②. POST 方式将各个表单字段元素及其数据作为 HTTP 消息的实体内容发送给 WEB 服务器,传送的数据量要比使用GET方式传送的数据量大得多。
POST /counter.jsp HTTP/1.1
referer: http://localhost:8080/Register.html
content-type: application/x-www-form-urlencoded
host: localhost:8080
content-length: 43
name=zhangsan&password=123 --请求体中传递参数.
10. 如何在 Serlvet 中获取请求信息:
1). Servlet 的 service() 方法用于应答请求: 因为每次请求都会调用 service() 方法
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException
ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现.
这两个接口的实现类都是服务器给予实现的, 并在服务器调用 service 方法时传入.
2). ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
①. 获取请求参数:
> String getParameter(String name): 根据请求参数的名字, 返回参数值.
若请求参数有多个值(例如 checkbox), 该方法只能获取到第一个提交的值.
> String[] getParameterValues(String name): 根据请求参数的名字, 返回请求参数对应的字符串数组.
> Enumeration getParameterNames(): 返回参数名对应的 Enumeration 对象,
类似于 ServletConfig(或 ServletContext) 的 getInitParameterNames() 方法.
> Map getParameterMap(): 返回请求参数的键值对: key: 参数名, value: 参数值, String 数组类型.
②. 获取请求的 URI:
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String requestURI = httpServletRequest.getRequestURI();
System.out.println(requestURI); // /day_29/loginServlet
③. 获取请求方式:
String method = httpServletRequest.getMethod();
System.out.println(method); //GET
④. 若是一个 GET 请求, 获取请求参数对应的那个字符串, 即 ? 后的那个字符串.
String queryString = httpServletRequest.getQueryString();
System.out.println(queryString); //user=atguigu&password=123456&interesting=game&interesting=party&interesting=shopping
⑤. 获取请求的 Serlvet 的映射路径
String servletPath = httpServletRequest.getServletPath();
System.out.println(servletPath); // /loginServlet
⑥. 和 attribute 相关的几个方法:
3). HttpServletRequest: 是 SerlvetRequest 的子接口. 针对于 HTTP 请求所定义. 里边包含了大量获取 HTTP 请求相关的方法.
4). ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现.
①. *getWriter(): 返回 PrintWriter 对象. 调用该对象的 print() 方法, 将把 print() 中的参数直接打印
到客户的浏览器上.
②. 设置响应的内容类型: response.setContentType("application/msword");
③. void sendRedirect(String location): 请求的重定向. (此方法为 HttpServletResponse 中定义.)
-----------------------------------------------------------------------------
在 web.xml 文件中设置两个 WEB 应用的初始化参数, user, password.
定义一个 login.html, 里边定义两个请求字段: user, password. 发送请求到 loginServlet
在创建一个 LoginServlet, 在其中获取请求的 user, password. 比对其和 web.xml 文件中定义的请求参数是否一致
若一致, 响应 Hello:xxx, 若不一致, 响应 Sorry: xxx xxx 为 user.
-----------------------------------------------------------------------------
7. MVC 设计模式.
6. 和属性相关的方法:
1). 方法
void setAttribute(String name, Object o): 设置属性
Object getAttribute(String name): 获取指定的属性
Enumeration getAttributeNames(): 获取所有的属性的名字组成的 Enumeration 对象
removeAttribute(String name): 移除指定的属性
2). pageContext, request, session, application 对象都有这些方法!
这四个对象也称之为域对象.
pageContext: 属性的作用范围仅限于当前 JSP 页面
request: 属性的作用范围仅限于同一个请求.
session: 属性的作用范围限于一次会话: 浏览器打开直到关闭称之为一次会话(在此期间会话不失效)
application: 属性的作用范围限于当前 WEB 应用. 是范围最大的属性作用范围, 只要在一处设置属性, 在其他各处的 JSP 或 Servlet 中
都可以获取到.
5. JSP:
1). WHY:
JSP 是简 Servlet 编写的一种技术, 它将 Java 代码和 HTML 语句混合在同一个文件中编写,
只对网页中的要动态产生的内容采用 Java 代码来编写,而对固定不变的静态内容采用普通静态 HTML 页面的方式编写。
2). Java Server Page: Java 服务器端网页. 在 HTML 页面中编写 Java 代码的页面.
2). helloworld:
新建一个 JSP 页面, 在 body 节点内的 <% %> 即可编写 Java 代码.
<body>
<%
Date date = new Date();
System.out.print(date);
%>
</body>
3). JSP 可以放置在 WEB 应用程序中的除了 WEB-INF 及其子目录外的其他任何目录中,
JSP 页面的访问路径与普通 HTML 页面的访问路径形式也完全一样。
4). JSP的运行原理: JSP 本质上是一个 Servlet.
每个JSP 页面在第一次被访问时, JSP 引擎将它翻译成一个 Servlet 源程序, 接着再把这个 Servlet 源程序编译成 Servlet 的 class 类文件.
然后再由WEB容器(Servlet引擎)像调用普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的Servlet程序。
5). JSP 页面的隐含变量: 没有声明就可以使用的对象. JSP页面一共有 9 个隐含对象.
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
//...
//使用 <% %> 编写的代码在此位置. 可以用到 request, response, pageContext, session
//application, config, out, page 这 8 个隐含对象. (实际上还可以使用一个叫 exception 的隐含对象)
}
①. request: HttpServletRequest 的一个对象. *
②. response: HttpServletResponse 的一个对象(在 JSP 页面中几乎不会调用 response 的任何方法.)
③. pageContext: 页面的上下文, 是 PageContext 的一个对象. 可以从该对象中获取到其他 8 个隐含对象. 也可以从中获取到当前
页面的其他信息. (学习自定义标签时使用它) *
④. session: 代表浏览器和服务器的一次会话, 是 HttpSession 的一个对象. 后面详细学习. *
⑤. application: 代表当前 WEB 应用. 是 ServletContext 对象. *
⑥. config: 当前 JSP 对应的 Servlet 的 ServletConfig 对象(几乎不使用). 若需要访问当前 JSP 配置的初始化参数,
需要通过映射的地址才可以.
映射 JSP:
<servlet>
<servlet-name>hellojsp</servlet-name>
<jsp-file>/hello.jsp</jsp-file>
<init-param>
<param-name>test</param-name>
<param-value>testValue</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hellojsp</servlet-name>
<url-pattern>/hellojsp</url-pattern>
</servlet-mapping>
⑦. out: JspWriter 对象. 调用 out.println() 可以直接把字符串打印到浏览器上. *
⑧. page: 指向当前 JSP 对应的 Servlet 对象的引用, 但为 Object 类型, 只能调用 Object 类的方法(几乎不使用)
⑨. exception: 在声明了 page 指令的 isErrorPage="true" 时, 才可以使用. *
<%@ page isErrorPage="true" %>
pageContext, request, session, application(对属性的作用域的范围从小到大)
out, response, config, page
exception
6). JSP模版元素: JSP页面中的静态HTML内容称
7). JSP表达式(expression)提供了将一个 java 变量或表达式的计算结果输出到客户端的简化方式,
它将要输出的变量或表达式直接封装在<%= 和 %>之中。
<%
Date date = new Date();
out.print(date);
%>
<%= date %>
8). JSP脚本片断(scriptlet)是指嵌套在<% 和 %>之中的一条或多条Java程序代码。
多个脚本片断中的代码可以相互访问
<%
String ageStr = request.getParameter("age");
Integer age = Integer.parseInt(ageStr);
if(age >= 18){
%>
成人...
<%
}else{
%>
未成人...
<%
}
%>
9). JSP 声明: JSP 声明将 Java 代码封装在<%!和 %>之中,它里面的代码将被插入进 Servle t的 _jspService 方法的外面
(在 JSP 页面中几乎从不这样使用)
10). JSP注释的格式:<%-- JSP 注释 --%> <!-- HTML 注释 -->
区别: JSP 注释可以阻止 Java 代码的执行.
4. 请求的转发和重定向:
1). 本质区别: 请求的转发只发出了一次请求, 而重定向则发出了两次请求.
具体:
①. 请求的转发: 地址栏是初次发出请求的地址.
请求的重定向: 地址栏不再是初次发出的请求地址. 地址栏为最后响应的那个地址
②. 请求转发: 在最终的 Servlet 中, request 对象和中转的那个 request 是同一个对象.
请求的重定向: 在最终的 Servlet 中, request 对象和中转的那个 request 不是同一个对象.
③. 请求的转发: 只能转发给当前 WEB 应用的的资源
请求的重定向: 可以重定向到任何资源.
④. 请求的转发: / 代表的是当前 WEB 应用的根目录
请求的重定向: / 代表的是当前 WEB 站点的根目录.
3.
-----------------------------------------------------------------------------
在 MySQL 数据库中创建一个 test_users 数据表, 添加 3 个字段: id, user, password. 并录入几条记录.
定义一个 login.html, 里边定义两个请求字段: user, password. 发送请求到 loginServlet
在创建一个 LoginServlet(需要继承自 HttpServlet, 并重写其 doPost 方法),
在其中获取请求的 user, password.
利用 JDBC 从 test_users 中查询有没有和页面输入的 user, password 对应的记录
SELECT count(id) FROM test_users WHERE user = ? AND password = ?
若有, 响应 Hello:xxx, 若没有, 响应 Sorry: xxx xxx 为 user.
-----------------------------------------------------------------------------
2. HttpServlet:
1). 是一个 Servlet, 继承自 GenericServlet. 针对于 HTTP 协议所定制.
2). 在 service() 方法中直接把 ServletReuqest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse.
并调用了重载的 service(HttpServletRequest, HttpServletResponse)
在 service(HttpServletRequest, HttpServletResponse) 获取了请求方式: request.getMethod(). 根据请求方式有创建了
doXxx() 方法(xxx 为具体的请求方式, 比如 doGet, doPost)
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1. 获取请求方式.
String method = request.getMethod();
//2. 根据请求方式再调用对应的处理方法
if("GET".equalsIgnoreCase(method)){
doGet(request, response);
}else if("POST".equalsIgnoreCase(method)){
doPost(request, response);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException{
// TODO Auto-generated method stub
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
}
3). 实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可.
4). 好处: 直接由针对性的覆盖 doXxx() 方法; 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要强转.
1. GenericServlet:
1). 是一个 Serlvet. 是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法为抽象方法
2). 如果新建的 Servlet 程序直接继承 GenericSerlvet 会使开发更简洁.
3). 具体实现:
①. 在 GenericServlet 中声明了一个 SerlvetConfig 类型的成员变量, 在 init(ServletConfig) 方法中对其进行了初始化
②. 利用 servletConfig 成员变量的方法实现了 ServletConfig 接口的方法
③. 还定义了一个 init() 方法, 在 init(SerlvetConfig) 方法中对其进行调用, 子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化.
④. 不建议直接覆盖 init(ServletConfig), 因为如果忘记编写 super.init(config); 而还是用了 SerlvetConfig 接口的方法,
则会出现空指针异常.
⑤. 新建的 init(){} 并非 Serlvet 的生命周期方法. 而 init(ServletConfig) 是生命周期相关的方法.
public abstract class GenericServlet implements Servlet, ServletConfig {
/** 以下方法为 Servlet 接口的方法 **/
@Override
public void destroy() {}
@Override
public ServletConfig getServletConfig() {
return servletConfig;
}
@Override
public String getServletInfo() {
return null;
}
private ServletConfig servletConfig;
@Override
public void init(ServletConfig arg0) throws ServletException {
this.servletConfig = arg0;
init();
}
public void init() throws ServletException{}
@Override
public abstract void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException;
/** 以下方法为 ServletConfig 接口的方法 **/
@Override
public String getInitParameter(String arg0) {
return servletConfig.getInitParameter(arg0);
}
@Override
public Enumeration getInitParameterNames() {
return servletConfig.getInitParameterNames();
}
@Override
public ServletContext getServletContext() {
return servletConfig.getServletContext();
}
@Override
public String getServletName() {
return servletConfig.getServletName();
}
}
网友评论