Servlet
一、生命周期
1、servlet类的加载
2、servlet类的实例化
3、执行init方法
4、执行service方法
5、执行destroy方法
二、开发servlet的三种方式
1、实现Servlet接口
类代码
package sy.cn;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ServletDemo_01 implements Servlet{
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy");
}
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub
System.out.println("init");
}
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
arg1.setContentType("text/html;charset=gbk");//中文乱码问题解决
OutputStream out = arg1.getOutputStream();
//PrintWriter pw = arg1.getWriter();//获取可以向浏览器传递信息的对象
out.write("haha".getBytes());
//pw.write("方法一:实现servlet接口!!");//把字符串传递给浏览器
//pw.close();
out.close();
System.out.println("service");
}
}
web.xml配置
<?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"
id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>ServletDemo_01</servlet-name>
<servlet-class>sy.cn.ServletDemo_01</servlet-class>
</servlet>
<servlet-mapping>
<!-- 这个必须与上面名字一样 ,最好写类名 -->
<servlet-name>ServletDemo_01</servlet-name>
<url-pattern>/sy</url-pattern>
</servlet-mapping>
</web-app>
最后部署到tomcat
浏览器访问:http://localhost:8080/servlet_01/sy
2、继承GenericServilet类
类代码
package sy.cn;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.PrintWriter;
public class ServletDemo_02 extends GenericServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
arg1.setContentType("text/html;charset=gbk");
PrintWriter pw = arg1.getWriter();
pw.write("方法二:继承GenericServlet类");
System.out.println("GenericServlet");
}
}
web.xml配置
<?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" id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>ServletDemo_02</servlet-name>
<servlet-class>sy.cn.ServletDemo_02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo_02</servlet-name>
<url-pattern>/sy</url-pattern>
</servlet-mapping>
</web-app>
浏览器访问:localhost:8080/servlet_02/sy
三、继承HttpServlet
这里写了简单的用户登入处理
三个类
LoginClServlet
LoginServlet
MainServlet
LoginServlet类
package sy.cn.view;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sy.cn.bean.User;
public class LoginServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/html;charset=utf-8"); //告诉浏览器用这种格式访问
resp.setCharacterEncoding("utf-8"); //设置字符格式
PrintWriter pw = resp.getWriter();
User user = (User)req.getSession().getAttribute("user");
if(user != null){
pw.println(user.pwd);
}
pw.println("<h1>用户登入</h1>");
pw.println("<form action='/servlet_03/LoginClServlet' method='post'>");
pw.println("用户名:<input type='text' name='username'/><br/>");
pw.println("密码:<input type='password' name='password'/><br/>");
pw.println("<input type='submit' value='登入'/><br/>");
pw.println("</form>");
}
}
LoginClServlet类
package sy.cn.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sy.cn.bean.User;
public class LoginClServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/htmp;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
User user = new User();
user.pwd = password;
if(username.equals("yansg") && password.equals("123456")){
req.getSession().setAttribute("user", user);
resp.sendRedirect("/servlet_03/MainServlet?uname=" + username);
}else{
//resp.sendRedirect("/servlet_03/LoginServlet"); //重定向
req.getSession().setAttribute("user", user);
req.getRequestDispatcher("/LoginServlet").forward(req, resp);//转发
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
MainServlet类
package sy.cn.view;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sy.cn.bean.User;
public class MainServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
resp.setContentType("text/html;charset=utf-8");
PrintWriter pw = resp.getWriter();
String uname = req.getParameter("uname");
User user = (User)req.getSession().getAttribute("user");
pw.println("<h1>主界面</h1>" + uname + user.pwd);
pw.println("<a href='/servlet_03/LoginServlet'>返回登入界面</a>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
this.doGet(req, resp);
}
}
web.xml配置
<?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" id="WebApp_ID" version="2.5">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>sy.cn.view.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginClServlet</servlet-name>
<servlet-class>sy.cn.controller.LoginClServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginClServlet</servlet-name>
<url-pattern>/LoginClServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>MainServlet</servlet-name>
<servlet-class>sy.cn.view.MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>/MainServlet</url-pattern>
</servlet-mapping>
</web-app>
浏览器访问:http://localhost:8080/servlet_03/LoginServlet
三、页面跳转:
转发:
1、java代码中: req.getRequestDispatcher("/LoginServlet").forward(req, resp);
context.getRequestDispatcher("/LoginServlet").forward(req, resp); //用ServletContext也能实现二者一样
2、jsp中: <jsp:forward page="new.jsp">
3、传值方式:
1、req.setAttribute("user",user);
2、req.getSession().setAttribute("user",user);
重定向:
1、java代码中:resp.sendRedirect("/servlet_03/MainServlet?uname=" + username);
2、jsp中:<%response.sendRedirect("new.jsp")>
3、传值方式:
1、url后面加? 多个用& 隔开 只能传字符串类型
2、req.getSession().setAttribute("user",user);
二者区别:
1,重定向发生在浏览器,转发发生在服务器
四、中文乱码的几种情况
1、表单提交(form)
post:
解决:req.setCharacterEncoding("utf-8");
get:一般不会乱码 如果乱码(不乱码时不要多此一举,反而会乱码) 当html本身utf-8时不会乱码
解决:String str = new String(req.getParameter("uname").getBytes("iso-8859-1"),"utf-8");
2、超链接:<a href="" /> 本质上是get提交
3、response.sendRedirect();
解决步骤:
1、传递前保证url传的是utf-8
String u = URLEncoder.encode(uname, "utf-8");
resp.sendRedirect("/servlet_05/NewServlet?u="+u);
2、接收到后,以utf-8格式传给浏览器
resp.setContentType("text/html;charset=utf-8");
五、HttpServletResponse
response.setCharacterEncoding("utf-8"); //设置编码响应浏览器格式
response.setContentType("text/html;charset=utf-8");//跟上面的类似 这个用的多些
System.out.println(response.getCharacterEncoding());//获取编码格式 默认:ISO-8859-1
PrintWriter pw = response.getWriter(); //获取对象打印对象 用于打印数据在浏览器上
OutputStream out = response.getOutputStream();//与上面类似 不能一起用
response.sendRedirect("");//重定向
六、HttpServletRequest
System.out.println(request.getRequestURL().toString()); // 返回这个url
System.out.println(request.getRequestURI()); // 只返回端口号后面的url
System.out.println(request.getQueryString()); // 获取请求数据 ?后面的
System.out.println(request.getRemoteAddr()); // 获取访问者的ip
System.out.println(request.getRemoteHost()); // 获取主机名 因为没有在dns上注册 所以返回ip
System.out.println(request.getRemotePort()); // 获取客户端的端口,这个是随机的,每次访问不一定一样
System.out.println(request.getLocalPort()); // 获取服务器的端口
System.out.println(request.getHeader("Host")); //获取消息头 里面的主机和端口
System.out.println(request.getParameter("name"));//获取浏览器表单过来的信息
System.out.println(request.getParameterValues("hobby"));//获取浏览器表单过来的信息(放回字符串数组,复选框时)
request.setAttribute("username",username); //把username属性或者对象放入request域对象中
request.getRequestDispatcher("/LoginServlet").forward(req, resp);//请求转发 转发的同时把request和response传了过去
//获取整个消息头
Enumeration<String> en = request.getHeaderNames();
while(en.hasMoreElements()){
String s = en.nextElement();
System.out.println(s + ":" + request.getHeader(s));
}
七、ServletConfig
是一个接口 获取方法:public ServletConfig getServletConfig();
作用:用于获取web里面servlet配置的信息 只在该servlet里
实例:
<servlet>
<servlet-name>ServletConfigDemo</servlet-name>
<servlet-class>sy.cn.ServletConfigDemo</servlet-class>
<init-param> <!-- 可以配置一些信息,用ServletConfig获取 -->
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param> <!-- 配置多个 -->
<param-name>haha</param-name>
<param-value>哈哈</param-value>
</init-param>
</servlet>
获取一个: String encoding = config.getInitParameter("encoding") //encoding的结果:utf-8
获取多个: Enumeration<String> str = config.getInitParameterNames(); //获取所以配置信息的名称 再通过上面获取对应的值
while(str.hasMoreElements()){ //枚举遍历
System.out.println(str.nextElement());
}
八、ServletContext
代表当前web应用 存在服务器端 对所有客户端共享
当web应用启动时创建,关闭时消亡
有什么用?
问题一:在访问某个网站时,往往都会看到网站的首页面显示你是第几问浏览者,这个怎么实现
问题二:在线用户人数显示
如何获取:
ServletContext context = this.getServletContext();
ServletContext context = req.getServletContext();
如何使用:
context.setAttribute("name", "sy");
context.removeAttribute("name");
System.out.println(context.getAttribute("name"));
web.xml里面配置 (配在servlet外面 公共的)
<context-param>
<param-name>uname</param-name>
<param-value>ahah</param-value>
</context-param>
获取方法:context.getInitParameter("uname");
实现转发:
context.getRequestDispatcher("/LoginServlet").forward(req, resp);
读取配置文件 在webContent目录下(dbinfo.properties)
InputStream in = context.getResourceAsStream("dbinfo.properties");//拿到文件
Properties pp = new Properties(); //创建属性对象
pp.load(in); //读取文件
System.out.println(pp.getProperty("username"));
获取文件的全路径 在web服务器下的
context.getRealPath("dbinfo.properties");
ServletContext相对于会话技术 是公用的大家都能看到的,都能访问
九、会话技术 cookie session
什么是会话:用户开一个浏览器访问某一个网站,点击多个超链接,访问服务器的多个资源,关闭浏览器。
注:服务器在接受客户端第一次请求时,会给客户端分配一个session(该session包含一个sessionId),
并且服务器会在第一次响应客户端时将该sessionId赋值给JSESSIONID传递给客户端
1、cookie cookie
有什么用?(一个Web站点最多存放20个cookie大小限制4k)(只能存放字符串)
用户登入记住帐号密码、用户上次登入时间、用户浏览商城历史
如何创建
Cookie cookie = new Cookie("key","value");
response.addCookie(cookie);
如何获取
Cookie [] cookies = request.getCookies();
生命周期
cookie默认的生命周期是会话级别(用户打开一次浏览器到关闭这次浏览器称为一次会话);
setMaxAge()可以设置生命周期 整数表示秒 0表示删除该cookie 负数表示一次会话
cookie存放中文问题
存放:
String val= java.net.URLEncoder.encode("你好","utf-8");
Cookie cookie = new Cookie("name",val);
读取:
Cookie [] cookies = request.getCookies();
java.net.URLDecoder.decode(cookies[0].getValue(),"utf-8")
2、session session
有什么用?(存在服务器中,一个用户浏览器独立一个session域对象)(可以存放字符串、对象)
不同页面查看信息如(购物车),不同的用户看到自己的信息,用于登入验证码校验
如何创建获取(用户访问服务器时自动给该用户创建一个独立的session)
HttpSession session = request.getSession(); //session不存在时会自动创建
session.setAttribute("name","李斯");
session.setAttribute("user",user);
User user = (User)session.getAttribute("user");
session.removeAttribute("user");
生命周期(重启tomcat或reload web或关机session会失效,session.invalidate()让所有session属性失效)
session默认生命周期为30min
在tomcat/conf/web.xml或单个项目的web.xml里面设置
<session-config>
<session-timeout>10</session-timeout> //表示10分钟
</session-config>
java代码中设置
session.setMaxInactiveInterval(60);//这60秒表示发呆时间及60秒内没有使用该session就会失效
3、cookie与session关系
每个session在cookie有个对应的Jsessionid 这样可以保证不同的servlet获取的是同一session
如果浏览器不小心关闭了 session在生命周期内 如何保存
手动添加一个 Cookie cookie = new Cookie("JSESSIONID",session.getId()); 这个一个按规范写
如果禁用cookie又该怎么办
在访问url后添加属性 JSESSIONID
如何添加
request.getSession(); //重写前获取下session
url重写 String url = response.encodeURL("/user/ShowUser"); //这样url就会自动添加JSESSIONID