Javaweb----servlet入门

javaweb----servlet

在正式看servlet前先补充一些小知识


web应用目录
下图为web应用目录,为了保证程序开发的正确性和规范性,大家的项目应当按照这样的结构去展开。

在这里插入图片描述

web.xml文件

web.xml文件就是web项目的设置中心,你可以在这里实现你想对项目的设置。
如配制web应用默认页面:

<welcom-file-list>
	<welcom-file>index.html</welcom-file>
	<welcom-file>index.htm</welcom-file>
	<welcom-file>index.jsp</welcom-file>
</welcom-file-list>

当用户访问web应用时,如果没有具体要访问的页面资源,tomcat会按照元素指定默认页面的顺序,一次查找这些默认页面。

Servlet开发入门

Servlet接口及其实现类

Servlet接口位于javax.servlet.Servlet
在Setvlet接口中定义了5个抽象方法
在这里插入图片描述
图源于API
在这里插入图片描述
图源于百度

针对Servlet接口,SUN公司提供了两个默认的接口实现类:GenericServlet和HttpServlet。其中GenericServlet是抽象类并没有实现Http请求处理;HttpServlet继承了GeneriServlet的所有方法。并且为HTTP请求的POST、GET等类型提供了具体的操作方法。
在这里插入图片描述
在这里插入图片描述

使用eclipse工具开发Servlet

创建servlet
在这里插入图片描述
()在这里插入图片描述

在项目正式开始前,简单说明一下servlet引入项目的两种方式:
1、注解(Servlet3.0及其以后版本支持)【推荐使用】
在Servlet文件中形成引入
@WebServlet("/HelloWorld")【包servlet.annotation.WebServlet】
推荐理由:

  • 简洁、便于修改
  • 不容易形成覆盖
    2、web.xml(Servlet3.0及其以后版本需要手动设置否则默认注解方式)
    通过四个子元素来引入
 <servlet>
  	<servlet-name>HelloWorld</servlet-name>
  	<servlet-class>servlet.HelloWorld</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>HelloWorld</servlet-name>
  	<url-pattern>/HelloWorld</url-pattern>
  </servlet-mapping>

需要注意的是,这两种方法不能同时使用。

一个简单的小例子:此处使用的为注解方式

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class servletDemo
 */
@WebServlet("/servletDemo")
public class servletDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		out.println("This Sevlet has been created by eclipse");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在这里插入图片描述

使用配制web.xml方法

  <servlet>
  	<servlet-name>servletDemo</servlet-name>
  	<servlet-class>servlet.servletDemo</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>servletDemo</servlet-name>
  	<url-pattern>/servlet/*</url-pattern>
  </servlet-mapping>

可以注意到url-pattern那有一些特殊,这里用到了Servlet映射路径通配符。
servlet映射路径通配符“ * ”,使用的格式有两种:具体如下。

  • 格式为“ *.扩展名 ”,例如“ *.do ”匹配以“ .do ”结尾的所有URL地址;
  • 格式为“ /* ”例如“ /abc/* ”匹配以“ /abc ”开始的所有URL的地址;

所有当我将URL输入为下面的形式也能显示出正常的页面,不会报错
http://localhost:8080/FirstWebProject/servlet/servlet.servlet123

设置缺省Servlet:当找不到匹配servlet-mapping时交给缺省servlet

 <servlet>
  	<servlet-name>servletDemo</servlet-name>
  	<servlet-class>servlet.servletDemo</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>servletDemo</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>

ServletConfig和ServletContext接口

ServletConfig和ServletContext分别相当于设置局部变量和设置全局变量。

ServletConfig接口比较简单,其作用为获取 Web应用程序的初始化参数,所以献上一个例子就不做过多阐述;

	<servlet>
		<servlet-name>TestServlet02</servlet-name>
		<servlet-class>cn.itcast.servlet.TestServlet02</servlet-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</servlet>

传递数据的方法:
web.xml >> ServletConfig >> Init >> Servlet

	ServletConfig config = this.getServletConfig();
	// 获得参数名为encoding对应的参数值
	String param = config.getInitParameter("encoding");
	out.println("encoding=" + param);

ServletConfig的常用方法
在这里插入图片描述

ServletContext接口
作用:

  • 获取 Web应用程序的初始化参数
  • 实现多个Servlet对象共享数据
  • 读取Web应用下的资源文件
	<context-param>
		<param-name>address</param-name>
		<param-value>beijing</param-value>
	</context-param>

传递数据的方法:
web.xml >> ServletContext >> Init >> Servlet

	ServletContext context = this.getServletContext();
	 // 得到包含所有初始化参数名的Enumeration对象
	Enumeration<String> paramNames = context.getInitParameterNames();
	  // 遍历所有的初始化参数名,得到相应的参数值,打印到控制台
	out.println("all the paramName and paramValue are following:");
	 // 遍历所有的初始化参数名,得到相应的参数值并打印
	 while (paramNames.hasMoreElements()) {
		String name = paramNames.nextElement();
		String value = context.getInitParameter(name);
		out.println(name + ": " + value);
             out.println("<br>");

多个servlet共享数据

<Demo01.java>

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class firstservlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {		
//		response.setCharacterEncoding("utf-8");
//		PrintWriter out = response.getWriter();
//		out.println("Hello World哈哈哈哈");
//		System.out.println("运行");
		ServletContext context = this.getServletContext();
		context.setAttribute("coding", "UTF-8");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
	
	
}

<Demo02.java>

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class servletDemo
 */
//@WebServlet("/servlet")
public class servletDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext context = this.getServletContext();
		String str = (String)context.getAttribute("coding");
		PrintWriter out = response.getWriter();
		out.println(str);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

在浏览器输入http://localhost:8080/FirstWebProject/servlet

读取Web应用下的资源文件
常用方法说明:

  • Set getResourcePaths(String path):返回一个set集合,为相对路径
  • String getRealPath(String path):返回资源文件在服务器文件系统上的真实路径(绝对路径);

<itcast.propties>

name = kim
password = kim123

<servletDemo.java>

package servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class servletDemo
 */
//@WebServlet("/servlet")
public class servletDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		ServletContext context = this.getServletContext();
		/*Java Resources下的src目录其实就是Web-INF下的classes目录*/
		InputStream in = context.getResourceAsStream("/WEB-INF/classes/itcast.propties");
		Properties pros = new Properties();
		pros.load(in);
		out.println("name:"+pros.getProperty("name")+"<br />");
		out.println("password:"+pros.getProperty("password")+"<br />");
//		String str = (String)context.getAttribute("coding");
//		out.println(str);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

接口常用方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

servlet的请求和响应


HttpServletRespons接口对象,继承自ServletResponse,专门用来封装HTTP响应消息。在该接口中定义了向客户端发送响应状态码、响应消息头、响应消息体。
HttpServletResponse : 戳它
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

发送响应消息头相关的三个重点方法:

void setContentType(Stirng type):

  • 用于设置Servlet输出内容的MIME类型
  • 设置字符编码集
    一个栗子:

response.setContentType(“text/html;charset=utf-8”);

void setCharacterEncoding(String ):

  • 设置输出内容使用的字符编码

void addIntHeader(java.lang.String名称,整数值)
添加具有给定名称和整数值的响应标头。此方法允许响应标头具有多个值。
参数:
name -标头名称
value -分配的整数值
功能:实现页面定时刷新

发送响应消息头相关的方法:IO流理念

ServletResponse中定义了两个与输出流相关的方法:
getWriter();
getOutputStream();

区别:
1、getWriter()用于向客户机回送字符数据
2、getOutputStream()返回的对象,可以回送字符数据,也可以回送字节数据(二进制数据)
如何选择:
若果我们回送字符数据,则使用PrintWriter对象,效率高
如果我们回送字节数据,只能用OutputStream
注意:
PrintWriter和OutputStream不能同时使用

		PrintWriter out=response.getWriter();
		out.println("abc");
		OutputStream os=response.getOutputStream();
		os.write("hello,world".getBytes());
解决中文输出乱码问题

计算机的数据都是以二进制的形式存储的,当传输文本时会发生字符和字节之间的转换。字符和字节之间的转换实通过查码表完成的,将字符转换成为字节的过程称为编码,反之为解码;乱码则意味着编码和解码用的码表不一致。故,解决的此问题的方案为:调整response编码码表、浏览器解码码表,使其一致。

方式一:
response设置编码:

response.setCharacterEncoding(“UTF-8”);

通知浏览器使用特定的码表解码

response.setHeader(“Content-type”,“text/html;charset=utf-8”);

方式二:

response.setContentType(“text/html;charset=utf-8”);

实现页面跳转

response.setHeader(“Refresh”,“3;URL=https://www.baidu.com”);

实现请求重定向

利用sendRedirect实现

sendRedirect工作原理

在这里插入图片描述

ewsponse.sendRedirect(“http://www.baidu.com”);

HttpServletRequest对象

包括了获取请求行、请求头和请求消息体

获取请求行信息

在这里插入图片描述

获取消息头

在这里插入图片描述

实现利用Referer请求头请求防止盗链

Referer的的作用是指示一个请求是从哪里链接过来,那么当一个请求并不是由链接触发产生的,那么自然也就不需要指定这个请求的链接来源,如:直接在浏览器的地址栏中输入一个资源的URL地址,那么这种请求是不会包含 Referer 字段的,因为这是一个“凭空产生”的 HTTP 请求,并不是从一个地方链接过去的。服务器允许 Referer 为空,意味着服务器允许浏览器直接访问。

利用Referer防盗链
一些站点为了吸引人气提高访问量,提供了各种软件的下载页面,倒是本身却没有资源,而只是提供超链接指向其他站点上的资源。为防止分流,我们需要进行防盗链。
【referrer中文解释:推荐人、引路人】,根据这个意思,我们便能快速理解防盗链的原理了,通过referer检查是否在自己的网站上发起的请求,而不是别人的网页
一个栗子

package cn.itcast.chapter04.request;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DownManagerServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, 
        HttpServletResponse response)throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
	         // 获取referer头的值
			String referer = request.getHeader("referer"); 
	         // 获取访问地址
			String sitePart = "http://" + request.getServerName();
			// 判断referer头是否为空,这个头的首地址是否以sitePart开始的
			if (referer != null && referer.startsWith(sitePart)) {
				// 处理正在下载的请求
				out.println("dealing download ...");
			} else {
				// 非法下载请求跳转到download.html页面
				RequestDispatcher rd = request
						.getRequestDispatcher("/download.html");
				rd.forward(request, response);
			}
		}
		public void doPost(HttpServletRequest request,
	        HttpServletResponse response)throws ServletException, IOException {
			doGet(request, response);
		}
	}

获取请求参数

在这里插入图片描述

解决请求参数的中文乱码问题

在填写表单时,难免会输入中文,如姓名、公司名等。由于HTML设置了默认编码为ISO-8859-1,因此会导致乱码出现。
解决方法:将浏览器编码和服务器解码设为一致。
对于request中的乱码的解决方法和在response中有所不同,POST方式和GET方式的解决方式不一致。
POST解决方式 :

request.setCharacherEncoding(“utf-8”);

GET解决方式: 解决GET方式提交表单时乱码,可以先对得到的字符串name使用错误码表ISO-8859-1将其重新编码,然后使用码表UTF-8进行解码。

name = new String(name.getBytes(“iso8859-1”,“utf-8”));

通过Request对象传递数据

Request对象不仅可以获取一系列数据,还可以通过属性传递数据。
ServletRequest接口中的一系列操作属性的方法:

setAttribute()方法

public void setAttribute(变量名,值对象);

getAttribute()方法

Object getAtrribute(变量名);

removeAttribute()方法

public void removeAttribute(变量名);

getAttributeNames()方法:该方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。

public Enumeration getAtrributeNames();

RequestDispatcher接口对象

可以用该接口的forword方法实现:让服务器通知另外一个资源去处理请求。注意:此接口与sendRedirect作用上有类似,但其有本质区别。

forword原理图

在这里插入图片描述

一个栗子:

RequestForwardServlet.java

package com.demo;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class RequestForwardServlet
 */
public class RequestForwardServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		//将数据存储在request对象中
		request.setAttribute("company", "Kim集团");
		//访问另一个servlet
		RequestDispatcher dispatcher = request.getRequestDispatcher("/ResultServlet");
		dispatcher.forward(request, response);
	}

}

ResultServlet.java

package com.demo;

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;

/**
 * Servlet implementation class ResultServlet
 */
public class ResultServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("公司名称: "+request.getAttribute("company"));
	}

}

效果图:

在这里插入图片描述

再来一个栗子

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="FirstServlet" method="post">
		<table width="298" border="0" align="center" cellpading="2" callspacing="1">
			<tr>
				<td align="right">学号: </td>
				<td align="left"><input type="text" name="snumber" size="15"></td>
			</tr>
			<tr>
				<td align="right">姓名: </td>
				<td align="left"><input type="text" name="sname" size="15"></td>
			</tr>
			<tr>
				<td colspan="2" align="center"><input type="submit" value="登录"><input type="reset" value="取消"></td>
			</tr>
		</table>
	</form>
</body>
</html>

在这里插入图片描述
Student.java

package com.demo;


public class Student {
	private String snoString="123";
	private String  snameString="123";
	
	public Student(String snoString,String snamString) {
		this.snoString = snoString;
		this.snameString = snamString;
	}
	
	public void setsno(String snoString) {
		this.snoString = snoString;
	}
	
	public String  getsno() {
		return snoString;
	}
	
	public void setsname(String snaString) {
		this.snameString = snameString;
	}
	
	public String  getsname() {
		return snameString;
	}
}

FirstServlet.java

package com.demo;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class FirstServlet
 */
public class FirstServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String snumber = request.getParameter("snumber");
		String sname = request.getParameter("sname");
		Student student = new Student(snumber, sname);
		request.setAttribute("student", student);
//		response.sendRedirect("/Demo05/SecondServlet");
		RequestDispatcher view = request.getRequestDispatcher("SecondServlet");
		view.forward(request, response);
		
	}

}

SecondServlet.java

package com.demo;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Servlet implementation class SecondServlet
 */
public class SecondServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//设置发送到客户端的响应类型
		response.setContentType("text/html;charset=utf-8");
		Student student = (Student)request.getAttribute("student");
		PrintWriter out = response.getWriter();
		out.println("<html><body>");
		out.println("<center>");
		out.println("学号:"+student.getsno()+"<br />");
		out.println("姓名:"+student.getsname()+"<br />");
		out.println(" <a href=\"/Demo05/input.html\">返回输入界面</a> ");
		out.println("</center>");
		out.print("</html></body>");
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值