Java EE 开发技术与案例教程——第三章:Servlet

目录

 

环境

了解什么是servlet

创建servlet

那么xml里面怎么配置呢

如果配置好xml和servlet的java类,就可以访问了,那么具体我们是怎么访问并且执行servlet的呢?

干点大的:用户登录的身份验证


环境

到了这一步不需要任何的环境了

了解什么是servlet

我们来说说这个servlet是啥,和jsp有啥差别:知乎:servlet和jsp介绍以及区别区别与联系

【前一个连接特别好,里面还包含了其他关于servlet的东西】

servlet是位于web服务器内部,运行在服务器的java程序,可以生成动态的web,传统java应用是从命令行启动,但是servlet是由web服务器进行加载的,而且servlet运行需要在web.xml中进行描述和注册,比如映射servlet的名字啊,配置servlet类啊,初始化servlet的参数之类的,这个我们会在下面详细说明。

jsp和servlet都可以做页面,但是jsp更接近表示层,servlet更多处理比较复杂,jsp难以写出的逻辑层的东西

我们访问tomcat任何一个资源其实都是在访问servlet,也就是说其实jsp也是被编译成了一个Servlet,然后进行访问的。

创建servlet

关于如何在web工程中创建一个servlet,有两种方法,推荐适用前一种

Servlet架构由javax.servlet和javax.servlet.http两个Java包组成。前面定义了所有的servlet类,后面定义了最常见的采用http通信的httpservlet的类。照理来说所有用户编写的类都需要实现javax.servlet.Servlet这个接口的五个方法

  • init()方法 :初始化一个Servlet类实例,并将其加载到内存中。只能用一次(开始的时候
  • service()方法 :Servlet成功初始化后该方法会被调用,用于处理用户请求
  • destroy()方法 :终止Servlet服务,销毁一个Servlet实例。 用一次
  • getServletConfig()方法 :获得ServletConfig对象,里面包含该Servlet的初始化信息,如初始化参数和ServletContext对象。
  • getServletInfo()方法:返回一个String对象,该对象包含Servlet的信息,例如开发者、创建日期、描述信息等

但是我们一般继承httpservlet(其他的比如genericservlet也有类似特性),这个类帮我其他都实现了,我们只需要实现service方法!cool

我们来看看第一节课的helloworld用servlet咋写:

  import javax.servlet.*;
  import javax.servlet.http.*;
  import java.io.*;
  public class Helloworld extends HttpServlet
  {
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException
     {
      res.setContentType("text/html;charset=GBK");
      PrintWriter out=res.getWriter();
      out.println("<html>");
      out.println("<head><title>HelloWorld!</title></head>");
      out.println("<body>");
      out.println("<p>欢迎学习java Servlet</p>");
      out.println("</body></html>");
      }
    public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException,IOException
     { doGet(req,res);}
  }

来看看我们是怎么从index.jsp变到helloworld.java的


<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    This is my JSP page. <br>
  </body>
</html>

这个是index.jsp的代码 我们发现,其实helloworld就是把要显示的,前后输出<html> </html>还有中间的body部分,虽然说一个是html里面嵌套java一个是java里面嵌套html语法,这就好像纸包鸡和鸡包纸(什么鬼?)

而我们转眼看看helloworld.java 这里的dopost直接交给doget处理,就是说不论发来的html是get还是post方法,我们都是用同一个函数处理。

并且如果你实际操作看看,就会发现这个.java文件被编译成了一个helloworld.class字节文件

那么xml里面怎么配置呢

我们编译完需要放在指定位置并且在web.xml中进行配置

指定位置)

在web.xml中配置文件中,<servlet>和<servlet-mapping>标识用于对Servlet进行配置,这个配置信息可以分为两个部分

  • 第一部分是配置Servlet的名称和对应的类
  • 第二部分是配置Servlet的访问路径

<servlet>:对每个Servlet进行说明和定义。     

<description>是对Servlet的描述信息,<display-name>是发布时Servlet的名称,这两项在配置是可省略。           

 <servlet-name>是这个Servlet的名称,这个名字可以任意命名但是要和<servlet-mapping>节点中的<servlet-name>保持一致。     

<servlet-class>是Servlet对应类的路径,在这里要注意,如果有Servlet带有包名,一定要把包路径写完整,否则Servlet容器就无法找到对应的Servlet类。

<init-param>用于对Servlet初始化参数进行设置(没有可省略,但是想下面那个工程就需要用到name和password)

(对这些初始化参数的访问可以在init()方法体中通过getInitParameter()方法进行获取)

<load-on-startup>用于指定容器载入Servlet时的优先顺序。如果Servlet没有设定<load-on-startup>载入优先级,则Servlet容器会在这个Servlet被访问时再进行初始化。

<servlet-mapping>:是对Servlet的访问路径进行映射。     

<servlet-name>是这个Servlet的名称,要和<servlet >节点中的<servlet-name>保持一致。     

<url-pattern>定义了Servlet的访问映射路径这个路径就是在地址栏中输入的路径。     

注意: <servlet>和<servlet-mapping>是成对出现,而且Servlet容器中有多少个servlet类就需要配置多少次。

如果配置好xml和servlet的java类,就可以访问了,那么具体我们是怎么访问并且执行servlet的呢?

Servlet的执行过程:     

首先根据在地址栏输入的路径信息找到<servlet-mapping>中<url-pattern>对应的<servlet-name>,再对应找到<servlet>中该<servlet-name>对应的<servlet-class>类,从而实例化该servlet并执行。

比如:

在上面我们的helloworld.java的<url-pattern>为/servlet/HelloWorld(此路径为虚拟路径,通常的写法为/servlet/类名)所以在地址栏中输入http://127.0.0.1:8080/servlet/HelloWorld

 <servlet>
  <description> Servlet Example</description>
  <display-name>Servlet</ </display-name>        
  <servlet-name>HelloWorld</servlet-name>
          <servlet-class>HelloWorld</servlet-class>
  		 <init-param>
            		<param-name>user</param-name>
           		<param-value>alex</param-value>
      		     </init-param>
      		     <init-param>
           		<param-name>address</param-name>
           		<param-value>http://www.hrbust.edu.cn</param-value>
      			</init-param>
  		<load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
          <servlet-name>HelloWorld </servlet-name>
          <url-pattern>/servlet/HelloWorld</url-pattern>
  </servlet-mapping>

此图是servlet的生命周期

干点大的:用户登录的身份验证

程序模块:程序共分3个部分         

  • 用户登录页面login.html         
  • 登录页面验证码生成类CheckCodeServlet.class         
  • 用户身份验证类LoginServlet.class。

工程目录:

界面十分简单,可以看到唯一可以讲的就是这个from action在点击之后会发生两种动作,这里是html的知识点,总之会发生不同的动作点击之后,下面这个程序中from action是提示我们等等提交submit之后跳转的页面,和我们数据库中add是一样的写法,而且图片那调用了checkcodeservlet生成一个图片,如果点击图片,会在这个servlet(我们说了这个文件最后会变成一个servlet)的对象调用reload。我们接下来会讲到checkcodeservlet中我们是生成图片的同时往session中保存了验证码是什么,好在loginservlet中判断是否正确。

<!DOCTYPE html>
 	<HTML>
  <HEAD>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <TITLE>用户登录</TITLE>
  </HEAD>
  <BODY bgColor=#ffffff leftMargin=0 text=#000000  topMargin=30>
  <form action="servlet/LoginServlet" method="get">
  姓名<input maxlength=10 name=name size=8><br>
  密码<input  type=password name=password size=8><br>
  验证码<input  name=code size=8><br>
  <img src="servlet/CheckCodeServlet" onclick="self.location.reload();"/><br>
  <input name=Submit type=submit value=提交>
  <input name=Submit2 type=reset value=重置>
  </form>
  </BODY>
  </HTML>

数据库中操作(部分)

<form action="addAction.jsp" method="Post">
	    添加:
    <br />
		电影名称: <input type="text" name="MovieName" />
		<br />
		电影类型: <input type="text" name="MovieType" />
    <br />
         电影描述: <input type="text" name="MovieDes" />
    <br />
		<input type="submit" value="提交" />
	</form>
————————————————
版权声明:本文为CSDN博主「专业渡劫修仙」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kuizhao8951/article/details/100896498

checkcodeservlet.java部分,如果不懂下面java servlet request和respone部分,可以看看这里

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 java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;

public class CheckCodeServlet extends HttpServlet{
	  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
	  	resp.setContentType("image/jpeg");//使客户端浏览器区分不同种类的数据,告诉客户端这是图片//设置显示内容类型
	  	OutputStream out=resp.getOutputStream();//取得输出流
	  try{
	  		resp.setHeader("programa","no-cache");//HTTP消息头
	      resp.setHeader("Cache-Control","no-cache");//Cache-Control指定请求和响应遵循的缓存机制
	  resp.setDateHeader("Expires",0);
//开始制作code
	  BufferedImage image=new BufferedImage(50,18,BufferedImage.TYPE_INT_RGB);
	  Graphics g=image.getGraphics();
	  g.setColor(Color.LIGHT_GRAY);
	  g.fillRect(0,0,50,18);
	  g.setColor(Color.LIGHT_GRAY);
	  g.drawRect(0,0,50,18);
	  String str="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	  String code="";
	  for(int i=0;i<4;i++)
	  {
	  int k=(int)(Math.random()*36);
	  char c=str.charAt(k);
	  code+=c;
	  }
//将code放入session:session机制采用的是在服务器端保持 HTTP 状态信息的方案
	  HttpSession session=req.getSession();
	  session.setAttribute("code",code);
	  g.setColor(Color.BLACK);
	  Font font=new Font("DIALOG",Font.ITALIC,15);
	  g.setFont(font);
	  g.drawString(code,3,15);
	  ImageIO.write(image,"JPEG",out);
	  out.flush();
	  out.close();
	  }finally{out.close();}
	  	}
	  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException
	  {doGet(req,resp);}
	  }
 
 import java.io.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 public class LoginServlet extends HttpServlet
 {protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException
 {	resp.setContentType("text/html;charset=gbk");
 	PrintWriter out=resp.getWriter();
 try{
	//req.setCharacterEncoding("utf-8");
 	String myUserName=this.getInitParameter("name");
  	String myPassWord=this.getInitParameter("password");
  	HttpSession session=req.getSession();
  	String scode=(String)session.getAttribute("code");
  	String userName=req.getParameter("name");
  	String passWord=req.getParameter("password");
  	String code=req.getParameter("code");
  	out.println("<html><body>");
  	out.println("<br/>");
  	if(!code.toUpperCase().equals(scode)){out.println("验证码错误!");}
  	else if(userName.equals(myUserName)&&passWord.equals(myPassWord))
  		{out.println("登录成功!");}
  			else{ 
  				out.println(myUserName+" "+myPassWord+" "+userName+" "+passWord);
  				out.println("登录失,败!");}
  }
  	finally{out.close();}
  }
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
  doGet(req,resp);}
  }

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>CheckCodeServlet</servlet-name>
    <servlet-class>CheckCodeServlet</servlet-class>
  </servlet>
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>LoginServlet</servlet-class>
    <init-param>
    	<param-name>name</param-name>
    	<param-value>cxq</param-value>
    </init-param>
    <init-param>
    	<param-name>password</param-name>
    	<param-value>1234</param-value>
    </init-param>
  </servlet>


  <servlet-mapping>
    <servlet-name>CheckCodeServlet</servlet-name>
    <url-pattern>/servlet/CheckCodeServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/servlet/LoginServlet</url-pattern>
  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

其实这里有一个问题,就是客户端get请求的时候,我这边用户名req收到的是iso编码的,需要在html里面设置编码转换,但是我还不会。并且//req.setCharacterEncoding("utf-8");是不能改变编码的,接受的时候已经默认是iso进行解码之后了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值