509 Servlet进行动态网页的开发
Myservlet:
package com.bjsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class Myservlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.print("<html>");
out.print("<head>");
out.print("</head>");
out.print("<body>");
out.print("<h3>This is my first servlet 哈哈</h3>");
out.print("</body>");
out.print("</html>");
}
}
如何把Myservlet写的网页在浏览器中显示?
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>a</servlet-name>
<servlet-class>com.bjsxt.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>a</servlet-name>
<url-pattern>/abc</url-pattern>
</servlet-mapping>
</web-app>
结果中文出现乱码,如何解决?
加上:服务器响应编码!
resp.setContentType(“text/html;charset=utf-8”);
package com.bjsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.print("<html>");
out.print("<head>");
out.print("</head>");
out.print("<body>");
out.print("<h3>This is my first servlet 哈哈</h3>");
out.print("</body>");
out.print("</html>");
}
}
使用这种方式开发动态网页!太麻烦了!
510 Servlet进行流程控制
Login和doLogin的缺点是什么?
- 成功应该跳转新的界面!失败返回原来页面!
解决方案: request.getRequestDispatcher(“success.jsp”).forward(request,response);
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>处理登录操作</title>
</head>
<body>
<%--http://localhost:8080/jsp01/doLogin.jsp?uname=2&pwd=4--%>
<%
//[A]接收Login.jsp传过来的数据
String u = request.getParameter("uname");
String p = request.getParameter("pwd");
//[B]数据处理--拿着用户和密码去数据库作比较
boolean flag = false;
if("sxt".equals(u)&&"123".equals(p)){
flag =true;
}
//[C]给用户做出响应
if(flag){
//out.print("登陆成功");
//可以实现页面的跳转--转发
request.getRequestDispatcher("success.jsp").forward(request,response);
}else {
//out.print("登录失败");
request.getRequestDispatcher("Login.jsp").forward(request,response);
}
%>
</body>
</html>
- JSP本身是负责内容显示的,但是现在却用jsp进行流程控制
如何解决?
package com.bjsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class DoLogin extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//[A]接收Login.jsp传过来的数据
String u = request.getParameter("uname");
String p = request.getParameter("pwd");
//[B]数据处理--拿着用户和密码去数据库作比较
boolean flag = false;
if("sxt".equals(u)&&"123".equals(p)){
flag =true;
}
//[C]给用户做出响应
if(flag){
//out.print("登陆成功");
//可以实现页面的跳转--转发
request.getRequestDispatcher("success.jsp").forward(request,response);
}else {
//out.print("登录失败");
request.getRequestDispatcher("Login.jsp").forward(request,response);
}
}
}
<servlet>
<servlet-name>doLogin</servlet-name>
<servlet-class>com.bjsxt.servlet.DoLogin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>doLogin</servlet-name>
<url-pattern>/doLogin</url-pattern>
</servlet-mapping>
小节:什么是Servlet
Servlet是一个基于Java技术的动态网页技术,运行在服务器端,由Servlet容器管理,用于生成动态的内容。是JSP的前身
Servlet是平台独立的符合特定规范的java类,编写一个Servlet,实际上就是按照Servlet规范编写一个java类。
Servlet不是由用户或程序员直接调用,而是由容器(Tomcat)管理,没有main()方法。
Servlet和JSP的关系
所有的JSP都要先翻译成Servlet,然后编译成class,最后执行
JSP本质上就是一个Servlet
JSP的执行过程
.jsp—翻译–à.java(Servlet)----编译–.class-----执行—
JSP出现后,Servlet被淘汰了吗?
没有
不再使用Servlet实现动态网页
现在的Servlet用于控制操作
511 Servlet生命周期
1、生命周期
servlet是一个单实例 多线程的程序
servlet的生命周期
【1】类加载
“com.bjsxt.servlet.LifeServlet”
Class clazz= Class.forName(“com.bjsxt.servlet.LifeServlet”);
【2】实例化 (离不开反射)
Object obj= clazz.newInstance();
【3】 初始化(离不开反射)
【4】服务请求(service)(离不开反射)
【5】 销毁操作(离不开反射)
类加载的时机
【1】默认的情况是第一次访问servlet的时候进行类加载
【2】0(当启动服务器时候加载) 数字越小加载的时机越往前
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
- Servlet 初始化后调用 init () 方法。
- Servlet 调用 service() 方法来处理客户端的请求。
- Servlet 销毁前调用 destroy() 方法。
- 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
https://www.runoob.com/servlet/servlet-life-cycle.html
下图显示了一个典型的 Servlet 生命周期方案。
- 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。
- Servlet 容器在调用 service() 方法之前加载 Servlet。
- 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。
512 Servlet API的内容
web.xml进行配置
<servlet>
<servlet-name>myServlet2</servlet-name>
<servlet-class>com.bjsxt.servlet.MyServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet2</servlet-name>
<url-pattern>/MyServlet2</url-pattern>
</servlet-mapping>
直接运行查看结果:
HTTP Status 405 - HTTP method GET is not supported by this URL
结合源码查找原因:
public interface Servlet {
//init居然是有参数的!
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
//参数是ServletRequest ServletResponse!可以猜测与HttpServletRequest HttpServletResponse
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
GenericServlet
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
//没有重写
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
HttpServlet
public abstract class HttpServlet extends GenericServlet implements Serializable {
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
//跳到自己重载的service方法
this.service(request, response);
}
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得提交的方式 get 或者 post
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
//调用自己的doGet
this.doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获得协议 http协议1.1 https协议。。。
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
//就是上图报的错误!
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(405, msg);
} else {
resp.sendError(400, msg);
}
}
从源码可知,不重写service方法,会报错!
重写doGet() 和 doPost()也可以!
513 Servlet 读取初始化值和全局参数
问题:编码改变,需要修改所有的servlet中service方法的utf-8—>GBK!
resp.setContentType(“text/html;charset=utf-8”);
参数提取:
package com.bjsxt.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ParamServlet extends HttpServlet {
String enc ;
@Override
public void init() throws ServletException {
//读取属性文件
//读取初始化参数
enc = this.getInitParameter("abc");
//方式二 相当于只作用一个servlet类
// enc=this.getServletConfig().getInitParameter("abc");
System.out.println("初始化参数"+enc);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset="+enc);
}
}
<servlet>
<servlet-name>paramServlet</servlet-name>
<servlet-class>com.bjsxt.servlet.ParamServlet</servlet-class>
<!--初始化参数-->
<init-param>
<param-name>abc</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>paramServlet</servlet-name>
<url-pattern>/ParamServlet</url-pattern>
</servlet-mapping>
<!--全局参数 可以被多个servlet读取-->
<context-param>
<param-name>ab</param-name>
<param-value>utf-8</param-value>
</context-param>
/读取全局参数
ab = this.getServletContext().getInitParameter("ab");
514 Servlet 中文乱码的处理
1. 请求乱码如何解决?
2. get方式和Post提交方式的区别
[1]get数据的传输是不安全的 ,post数据传递更加安全
[2]get方式数据传递有大小限制 post传输数据没有限制
[3]get传输的数据速度比较快 post比较慢
post提交中文如何解决?
request.setCharacterEncoding(“utf-8”);
public class DoLogin extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//[A]接收Login.jsp传过来的数据
request.setCharacterEncoding("utf-8");
get提交中文如何解决?方式一:
//解决get方式乱码
//1.获得元素编码的自己数组
byte[] bytes = u.getBytes("ISO-8859-1");
//2.把原始编码的字节数组转成UTF-8编码格式
String str = new String(bytes,"utf-8");
System.out.println("后"+str);
//[B]数据处理--拿着用户和密码去数据库作比较
boolean flag = false;
if("尚学堂".equals(str)&&"123".equals(p)){
flag =true;
}
方式二:
在server.xml中指定对应的服务器编码
URIEncoding=“utf-8”