【高编 5】 北邮 高级网络程序设计 5. Servlet

【高编 5】 北邮 高级网络程序设计 5. Servlet,第1张

【高编 5】 北邮 高级网络程序设计 5. Servlet Servlet Basic Servlet标准代码
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class HelloServlet extends HttpServlet{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletExcpetion{
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println();
        out.close;
    }
}
获取HTML form中的输入参数

方法

String request.getParameter()

输入的参数为HTML中的name=“frame”对应的

返回值:String

String userName = request.getParameter("fname");
Servlet关键点
  1. 没有main方法public static void main(String[] args)
  2. 没有构造器
  3. 两个关键的方法
    • doGet()
    • doPost()
Serlvet 源码

init():在servlet第一次创建或者load的时候调用,只调用一次

service():每次有request都会被调用

destroy():当用完了servlet调用

Servlet创建过程

当程序收到HTTP请求时:

  • 寻找servlet(如果找不到servlet,loads,调用构造器以及init())
  • 创建或者重复使用Thread,这个Thread会调用service()方法
  • 创建或传递request以及response对象
  • 向请求端返回response对象
Life cycle of servlet

init()

service()

destroy()

ServletConfig

ServletConfig对象由container创建

  • 每个Servlet有且仅有一个ServletConfig
  • 这些参数是写web.xml里面的

web.xml


    ourz
    yes

Servlet中调用

out.println(getServlerConfig.getInitParameter("ourz"));
// yes
ServletContext

Servlet

  • 每一个Servlet或者每一个JSP都有一个ServletConfig对象
  • 包含了所有初始参数

Web Application

  • 每个Web application都有一个ServletContext对象
  • 写在Web xml中

web.xml


	ourz
    yes

Servlet中调用

ServletContext ctx = getServletContext();
out.println(ctx.getInitParameter("ourz"));
Attribute

两个重要的方法

  1. getAttribute(String)

  2. setAttribute(String, Object)

getParameter()
String getParameter(String)
  • 返回null表明unknown parameter
  • 返回**""**表明这个parameter没有值
getParameterNames()
String[] Enumeration getParameterNames(String)
  • 返回null表明unknown parameter
  • 返回**""**表明这个parameter没有值
例子:读取Checkbox

 

Servlet

// More code here ...
out.println("");
// Obtain all the form’s parameters from the request object.
Enumeration paramNames = req.getParameterNames();
while (paramNames.hasMoreElements()) {
	String paramName = (String) paramNames.nextElement();
	// Obtain values for this parameter and check how many there are.
	String[] paramValues = req.getParameterValues(paramName);
	if (paramValues.length == 1) 
    { // a single value
		String paramVal = req.getParameter(paramName);
		out.println("" + paramName +"" + paramVal + "		");
	} else { // If several values print a list in the table.
	out.println("" + paramName +"
    "); for (int i = 0; i < paramValues.length; i++) out.println("
  • " + paramValues[i] + "
  • "); out.println("
"); } } out.println(""); out.close();
Advanced Servlet

包含:

Getting another file to do work

  • Redirect
  • Forward(RequestDispatcher)

Request and Response headers

Conversation

  • Sessions
  • URL writing

JavaBeans

Redirect & Forwarding Redirect与Forwarding的概念

Redirect

只能写在GET中

Servlet方法:必须写在全部的response之前

response.sendRedirect("url");

回复状态码:

  • 302:暂时移动
  • 301:永久移动

结果:浏览器读取Response中的header,然后向新的URL发请求

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class TestRedirect extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String userName = request.getParameter("uname");
		// validate
		// another file is responsible for doing something with this
		response.sendRedirect("www.security.co.uk/checkUserName.do");
		// more servlet code ...
	}
}
Forwarding

利用Object RequestDispatcher

Servlet方法:

RequestDispatcher view = request.getRequestDispatcher("display.jsp");
view.forward(request, response);
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class TestForward extends HttpServlet{
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String userName = request.getParameter(“uname”);
		// validate
		// another file is responsible for displaying this
		RequestDispatcher view = request.getRequestDispatcher(“display.jsp”);
		view.forward(request, response);
		// more servlet code ...
	}
}
Request Headers 获取请求Header
String getHeader(String) // 大小写不敏感
常用的header自己的方法
getContentLength();
getContentType();
获取所有的Headers的可遍历对象
Enumeration getHeaderNames();
获取请求中的其他信息
getMethod()
getRequestURL()
getProtocol()

服务器端的回复格式

包含:

  • 状态栏(包含HTTP版本号 状态码 信息 (HTTP/1.1 200 OK))
  • Response Header (Content-type: text/plain)
  • 空白行
  • document

Servlet能做的

通过设置不同的状态栏和Response Header

  • 告诉用户要输密码
  • 提示attached document的类型
  • forward到其他的网页
HTTP状态码

设置状态码

Servlet只需要去设置状态码,HTTP版本是已经定义好的了

Servlet方法:

response.setStatus(int)

必须在PrintWriter之前使用此方法

特殊的状态码

一些特殊的状态码以文本的形式定义在HttpServletResponse类中,可以直接调用

  • HttpServletResponse.SC_NOT_FOUND来使用 404码

两个常用的方法:

  • public void sendError(int sc, String message)
    
  • public void sendRedirect(String url)
    

    会同时返回 301 状态码

设置Response Header

Servlet方法:

res.setHeader(String header, String value);

有以下例子:

对于常用的Header来说,有以下的方法可使用:常用

  • 重要 setContentType(String type)
  • 重要 sendRedirect(String encodedURL)
  • setContentLength(int length)
  • addcookie(String cookie)
设置Refresh Header

用法1:设置浏览器多久会重新请求页面

servlet方法:30s刷新一下

res.setHeader("Refresh", "30");

终止浏览器刷新:发送204(SC_NO_CONTENT)状态码

res.setStatus(204);
res.setStatus(response.SC_NO_CONTENT);

204状态码:请求成功但是没有任何东西返回

用法2:设置浏览器多久会去到下一个页面

Servlet方法:5秒后到URL的页面

res.setHeader(“Refresh”, “5; URL=http://host/path”);
Content-Type包含的Header

常用text/html(默认为text/plain)

setContentType();

该方法必须要在OutputStream之前使用


有以下可用的

检查是否可接收特定的Content-Type

Servlet方法:

String req.getHeader("Accept")

例子:如果能接收image/jpeg就发

Session

概述:服务器传SessionID给新客户端,客户端会随Request发SessionID给服务器,服务器根据SessionID去找该客户端在服务器存了的东西和属性

Servlet端的Session追踪

HttpSession API是高层的接口,建立与cookies和URL-rewriting之上

  • 浏览器能支持cookies就用cookies,不支持cookies就使用URL-rewriting
  • Servlet不担心使用哪个方法

要经常使用URL-rewriting方法


如何跟踪?

服务器端使用session ID来匹配全部的Session object

  • session ID是一个String,当客户端第一次访问服务器时,以cookies的形式发送回客户端

  • 如果客户端不支持cookies或者客户disabled cookies的话

    • Session Tracker会进行URL rewriting
获取当前请求的Session
HttpSession session = request.getSession();
HttpSession Object

Servlet会保留一个关于HttpSession Object的表

  • 这个Object通过session id来被查找

  • 这是从请求对象中提取的:

    cookies或者rewritten URL

    HttpSession session = request.getSession();
    
  • HttpSession object其实就是一个哈希表,用来存储用户的数据

HttpSession的生命周期默认为30min

判断是否存在已有的Session Object
HttpSession session = request.getSession();
if(session.isNew()) { // e.g., add username to it }
else {
// e.g., add new information, extract previous
// stored information from the session object
}
第一次访问Servlet

判断该Session是否已经存在,不存在的将其存为新的Session对象

HttpSession session = request.getSession();
if (session.isNew()) {
	String uName = request.getParameter(“fullName”);
	session.setAttribute(“userName”,uName);
	// [session.setAttribute(String key, Object value)]
}
非第一次访问Servlet

将Session中的信息取出返回

HttpSession session = request.getSession();
if (session.isNew()) { ... }
else {
	int uAge = Integer.parseInt(request.getParameter(“age”));
	session.setAttribute(“userAge”, uAge);
	String name = (String) session.getAttribute(“userName”);
	...
	out.println(“hello ” + name + “ your age is ” + uAge);
}
Session死亡时间

Servlet方法:在超过设置的时间后会丢弃Session

HttpSession session = request.getSession();
session.setMaxInactiveInterval(2*60*60); // two hours

方法invalidate()和logout()显式地删除会话对象。


也可以配置文件来使用


	30

URL Rewriting

将全部要返回浏览器的内容都写入URL,包括session ID

例如:

如果用户点击URL,又会回到Server


在URL重写中,服务器端程序不断添加或更改URL(它们的长度可以不断增加),以记住在页面之间交换的数据。

encodeURL

Servlet方法:

response.encodeURL(“/store/catalog”)

两个作用:

  • 检查URL是否需要被重写
  • 如果URL需要重新,那么session id会被插入URL中并返回重写好的URL
Encoding URL

两种情况需要Encoding URL

  1. 当url嵌入到生成的网页中时

    String originalURL = someRelativeOrAbsoluteURL;
    String encodedURL = res.encodeURL(originalURL);
    out.println(“...”);
    
  2. 使用重定向时 originalURL指的是重定向要去的地址

    String originalURL = someURL;
    String encodedURL = res.encodeRedirectURL(originalURL);
    res.sendRedirect(encodedURL);
    
Rewritten

需要两个不同的方法,因为它们遵循不同的规则来确定是否需要重写URL。

如果不重写URL,在以下情况session会lost:

  • 浏览器不支持cookie
  • 点击了未重写的URL
JavaBean 与 Session的应用

应用JavaBean的好处

  • 可以存储一个范围的属性
  • 很容易定制化

将Session中的Value设成有一个JavaBean

package chain.web; import chain.model.*;
import java.io.*; import javax.servlet.*;
import javax.servlet.http.*; import java.util.*;

public class OperandsServlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
		response.setContentType("text/html");
		DataBean db;
		// Get the current session object, create one if necessary.
		HttpSession session = request.getSession(true);
		if (session.isNew()) { // So first time.
			db = new DataBean();
			int op1 = Integer.parseInt(request.getParameter("op1"));
			int op2 = Integer.parseInt(request.getParameter("op2"));
			db.setOp1(op1);
			db.setOp2(op2);
			session.setAttribute("sum", db);
       
			try {
			PrintWriter out = response.getWriter();
			out.println("Asking for
			Operator");
			out.println("Asking for Operator");
			out.println("");
			out.println("");
			}
			catch (java.io.IOException e) {
				System.err.println(" Print exception" +e);
			}
		} // end if
		else { // There is a session variable for this user.
			db = (DataBean)session.getAttribute("sum");
			String s = request.getParameter("op");
			db.setOperator(s);
            
			try { double x = db.calculate(); db.setAnswer(x); }
			catch(Exception e) { System.out.println(e); }
			session.setAttribute("sum", db);
            
			try {
			request.getRequestDispatcher("Display.jsp").
			forward(request, response);
			}
			catch (javax.servlet.ServletException e) {
			System.err.println(" Servlet exception" + e);
			}
			catch (java.io.IOException e) {
			System.err.println(" Print exception" +e);
			}
			// getServletContext().getRequestDispatcher("/output.jsp").
			forward(request, response);
		}
	}
}                    

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5684124.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存