Serelet/Jsp学习笔记(一)(serlet基础,数据传递)

Servlet开发

Servlet是Sun公司提供的一门用于开发动态WEB资源的技术

一、Servlet执行过程

二、Servlet的使用

首先需要建立WEB项目(J2EE=J2SE+扩展JAR),创建一个动态的WEB资源(动态生成HTML页面)

  • 首先,创建一个普通的Java类,让其去继承HttpServlet
  • 再把开发好的Java类部署到WEB服务器中

当一个类继承了HttpServlet类的普通类,约定俗成有一种称呼这样的普通类为:Servlet

约定的命名方式:XXXXServlet

(1)新建一个Servlet

package com.yu.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 Demo01Servlet extends HttpServlet {//Servlet接口
	/* doGet方法是处理GET的请求方式 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println(req);
		System.out.println(resp);
		System.out.println("获取的请求方式:"+req.getMethod());
	}
	/* doPost方法是处理Post的请求方式:表单设置method="post" */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println(req);
		System.out.println(resp);
		System.out.println("获取的请求方式:"+req.getMethod());
	}
}

备注:因为我们这个Java文件,不能被浏览器直接访问,我们需要通过映射方式完成

(2)Servlet访问URL映射配置

映射建立方式有两种:
一. web.xml中手动配置方案;

<?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>
            <!--web.xml中是唯一的标识-->
            <servlet-name>Demo01Servlet</servlet-name>
            <!--访问servlet全路径-->
            <servlet-class>com.yu.Servlet.Demo01Servlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>Demo01Servlet</servlet-name>
            <!--一般都是从"/"开始写-->
            <url-pattern>/yue.com</url-pattern>
        </servlet-mapping>
</web-app>

二.通过注解进行Servlet映射。

(3)测试Servlet访问

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>测试</title>
    </head>
    <body>
        <a href="yue.com">YUE</a>
        <form action="yue.com" method="get">
            <button>GET请求方式</button>
        </form>
        <form action="yue.com" method="post">
            <button>POST请求方式</button>
        </form>
    </body>
</html>

在这里插入图片描述

(4)生成动态WEB资源

HttpServletRequest : 处理Http请求信息
HttpServletResponse : 处理Http响应信息

二者都是Tomcat容器自动创建(实例化)

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("获取的请求方式:"+req.getMethod());
		//动态生成一个HTML页面,当我访问test01.php请求的时候,响应回去一个HTML页面
		//1.告知响应的头信息是一个HTML数据格式
		resp.setContentType("text/html;charset=UTF-8");
		//2.生成HTML页面
		PrintWriter out = resp.getWriter();
		//3.需要我们手动拼写HTML页面
		String titleName = "动态生HTML页面";
		out.write(" <html> ");
		out.write(" <head> ");
		out.write("  <meta charset='UTF-8'> ");
		out.write("  <title>"+titleName+"</title>");
		out.write(" </head> ");
		out.write("<body>");
		out.write("<h3>");
		out.write(String.valueOf(Math.random()));
		out.write("</h3>");
		out.write("</body>");
		out.write(" </html> ");

	}

三、HttpServletResponse对象

WEB服务器收到客户端Http请求,会针对每一次请求,分别创建一个用于代表的Request请求对象和Response响应对象,如果向获取客户端提交的数据请求对象,向客户端输出数据使用响应对象。

HttpServletResponse对象代表服务器的响应,这个对象中封装了向客户端发送数据、发送响应头、发送响应的状态码等方法

package com.yu.Servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 鱼
 * @Date: 2021/06/14/10:12
 * @Description:
 */
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //响应回去数据类型图片
        //resp.setHeader("refresh","5");//设置refresh响应的头控制浏览器每隔五秒刷新

        //1.内存中创建一张图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //2.得到图片
        Graphics2D g  = (Graphics2D)image.getGraphics();
        g.setColor(Color.WHITE);//设置图片的背景颜色
        g.fillRect(0,0,80,20);//充填背景颜色
        //3.向图片上写入数据
        g.setColor(Color.BLUE);//数据颜色
        g.setFont(new Font(null,Font.BOLD,20));//设置字体
        String str = String.valueOf(new Random().nextInt(10000) +10000);
        g.drawString(str,0,20);//从坐标(0,20)开始写入数据
        //4.响应图片
        resp.setContentType("image/jpeg");//响应一张图片
        resp.setDateHeader("expires",-1);//清除缓存
        resp.setHeader("Cache-Control","no-cache");//不要缓存
        resp.setHeader("Pragma","no-cache");
        //5.将图片写入浏览器
        ImageIO.write(image,"jpg",resp.getOutputStream());

    }
}

服务端响应回去的常用的数据类型:text/html、图片、application/json、下载(流的操作)

重定向与请求转发

在这里插入图片描述

请求重定向:一个WEB资源收到客户端请求后,通知客户端去访问另外一个WEB资源,我们称为重定向

(地址栏的路径发送了改变)

package com.os.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 Demo02Servlet extends HttpServlet {//Servlet
	/* doGet方法是处理GET的请求方式 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("Demo02Servlet");
		//resp.sendRedirect("test01.php");//重定向
		//请求转发
		req.getRequestDispatcher("/test01.php").forward(req,resp);
	}

}

四、Servlet访问URL映射配置

客户端是通过URL地址访问WEB服务器中资源(Servlet),所以Servlet想被外界访问,必须将Servlet映射到一个URL地址上,这个工作由部署描述符web.xml中<servlet><sevlet-mapping>元素完成(或者简化注解方式)

  • <servlet>元素用于注册servlet,他主要包含两个子元素<servlet-name><servlet-class>

  • <sevlet-mapping>元素用于映射一个已经注册对外访问URL映射 , 他主要包含两个子元素<servlet-name><url-pattern>

  1. 一个Servlet可以映射多个路径
public class Demo04Servlet extends HttpServlet {//Servlet
	/* doGet方法是处理GET的请求方式 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("多个映射路径Demo04Servlet");
		//响应的是一个空白页面
	}
}
<servlet>
    <servlet-name>Demo04Servlet</servlet-name>
    <servlet-class>com.os.servlet.Demo04Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo04Servlet</servlet-name>
    <url-pattern>/test04.php</url-pattern>
    <url-pattern>/test04.asp</url-pattern>
    <url-pattern>/test04.html</url-pattern>
    <url-pattern>/test04</url-pattern>
</servlet-mapping>
  1. servlet的映射路径可以使用通配符*
<servlet>
    <servlet-name>Demo06Servlet</servlet-name>
    <servlet-class>com.os.servlet.Demo06Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo06Servlet</servlet-name>
    <!-- 如果有后缀名,不能设置斜线开头 -->
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>Demo07Servlet</servlet-name>
    <servlet-class>com.os.servlet.Demo07Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo07Servlet</servlet-name>
    <!-- 所有sys开头的路径 -->
    <url-pattern>/sys/*</url-pattern>
</servlet-mapping>

<servlet>
    <servlet-name>Demo05Servlet</servlet-name>
    <servlet-class>com.os.servlet.Demo05Servlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Demo05Servlet</servlet-name>
    <!-- *任何的,谁描述的更加准确就使用谁 -->
    <url-pattern>/*</url-pattern>
</servlet-mapping>

在这里插入图片描述

五、HttpServletRequest对象

现在开始,使用注解方式的形式创建Servlet,在传统方式需要我们手动进行配置,这个过程非常的繁琐。

HttpServletRequest 对象代表客户端的请求,当客户端通过HTTP协议访问服务器的时候
Http请求头中的所有信息都封装在这个对象中
通过该对象提供了响应的获取方法,可以获取请求中所有的信息

使用@WebServlet替换传统方式

package com.os.servlet; /**
 * Created with IntelliJ IDEA.
 *
 * @Author: 鱼
 * @Date: 2021/06/19/10:53
 * @Description:
 */

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

/**
 *@WebServlet(name = "Test01Servlet")注解等价于
 * <servlet>
 *     <servlet-class>Test01Servlet</servlet-class>
 *     <servlet-class>com/os/servlet/Test01Servlet</servlet-class>
 * </servlet>
 * 需要建立URL映射:urlPatterns = "/test01.php",是一个数组,只有一个映射如下写法,多个映射数组表示
 * <servlet-mapping>
 *     <servlet-name>Test01Servlet</servlet-name>
 *     <url-parrten> /test01.php</url-parrten>
 * </servlet-mapping>
 *
 *
 * value与urlPatterns等价,两者不能共存
 * */

@WebServlet(name = "Test01Servlet", urlPatterns = "/test01.php")
public class Test01Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

5.1 获取客户端信息

  • getRequestURL() :返回客户端请求时候的完整URL
  • getRequestURI() :返回请求行中的资源名称部分
  • getQueryString() :返回请求行中的参数部分
  • getRemoteAddr() :返回客户端请求的IP地址
out.write("<h4>获取的请求路径:"+request.getServletPath()+"</h4>");
out.write("<h4>获取的发布路径:"+request.getContextPath()+"</h4>");
package com.os.servlet; /**
 * Created with IntelliJ IDEA.
 *
 * @Author: 鱼
 * @Date: 2021/06/19/10:53
 * @Description:
 */

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 *@WebServlet(name = "Test01Servlet")注解等价于
 * <servlet>
 *     <servlet-class>Test01Servlet</servlet-class>
 *     <servlet-class>com/os/servlet/Test01Servlet</servlet-class>
 * </servlet>
 * 需要建立URL映射:urlPatterns = "/test01.php",是一个数组,只有一个映射如下写法,多个映射数组表示
 * <servlet-mapping>
 *     <servlet-name>Test01Servlet</servlet-name>
 *     <url-parrten> /test01.php</url-parrten>
 * </servlet-mapping>
 *
 *
 * value与urlPatterns等价,两者不能共存
 * */

@WebServlet(name = "Test01Servlet", value = "/test01.php")
public class Test01Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        /*1.获取客户端的信息*/
//    + **getRequestURL()** :返回客户端请求时候的完整URL
        String requestURL = request.getRequestURL().toString();
//    + getRequestURI() :返回请求行中的资源名称部分
        String requestURI = request.getRequestURI();
//    + **getQueryString()** :返回请求行中的参数部分
        String queryString = request.getQueryString();
//    + **getRemoteAddr()** :返回客户端请求的IP地址
        String remoteAddr = request.getRemoteAddr();

        String remoteHost = request.getRemoteHost();//客户端传递过来的HOST
        int remotePort = request.getRemotePort();//获取端口号
        String remoteUser = request.getRemoteUser();//获取用户
        String method = request.getMethod();//请求方式

        String pathInfo = request.getPathInfo();//路径信息

        String localAddr = request.getLocalAddr();//获取服务器的IP地址

        String localName = request.getLocalName();//获取服务钱的主机名


        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write("<h3>获取客户端的信息如下:</h3>");

        out.write("<h4>请求完整URL地址:"+requestURL+"</h4>");

        out.write("<h4>获取的请求路径:"+request.getServletPath()+"</h4>");
        out.write("<h4>获取的发布路径:"+request.getContextPath()+"</h4>");

        out.write("<h4>请求的资源:"+requestURI+"</h4>");
        out.write("<h4>获取传递参数:"+queryString+"</h4>");
        out.write("<h4>来访者(客户端)IP地址:"+remoteAddr+"</h4>");
        out.write("<h4>来访者(客户端)主机名:"+remoteHost+"</h4>");
        out.write("<h4>使用的端口号:"+remotePort+"</h4>");
        out.write("<h4>remoteUser:"+remoteUser+"</h4>");
        out.write("<h4>请求的方式:"+method+"</h4>");
        out.write("<h4>pathInfo:"+pathInfo+"</h4>");
        out.write("<h4>localAddr:"+localAddr+"</h4>");
        out.write("<h4>localName:"+localName+"</h4>");

        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}


5.2 获取客户端的请求头

  • getHeader(String name):String
  • getHeaders(String name): 返回 Enumeration
  • getHeaderNames()
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();

		Enumeration<String> requestHeaderInfos = request.getHeaderNames();
		out.write("<h3>获取所有的客户端头信息如下:</h3>");
		while(requestHeaderInfos.hasMoreElements()){
			String headerName = requestHeaderInfos.nextElement();
			String headerValue = request.getHeader(headerName);
			out.write("<h4>"+headerName+":"+headerValue+"</h4>");
		}

		out.close();
	}

5.3 数据传递

  • 一.服务端(Servlet)获取客户端(Html)数据

常用方法:

  1. request.getParameter(“对应传递name属性对应的值”):单个数据,没有返回null

  2. request.getParameterValues(对应传递name属性对应的值)

  3. request.getParameterMap():将传递过来的数据全部获取到,常用于框架封装

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>客户端传递数据</title>
    </head>
    <body>
        <h3>客户端传递的数据:单个值、数组、文件</h3>
        <h3 style="color:red;">表单传递数据必须设置name属性</h3>
        <form action="test02.php" method="get">
            用户名:<input type="text" name="user_name"><br/><!-- 单个值 -->
            <!-- 只要传递的name名字有重复,就代表是数组,有经典控件 -->
            爱好:<!-- 数组 -->
            <input type="checkbox" name="hobby" value="basketall">篮球
            <input type="checkbox" name="hobby" value="football">足球
            <input type="checkbox" name="hobby" value="pingpang">乒乓
            <hr/>
            <button>提交GET请求方式</button>
        </form>
    </body>
</html>
package com.os.servlet;

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

@WebServlet(name = "Test02Servlet",urlPatterns = "/test02.php")
public class Test02Servlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*1.request.getParameter("对应传递name属性对应的值"):单个数据,没有返回null*/
		String userName = request.getParameter("user_name");
		System.out.println("userName = " + userName);
		/*
		* 2.request.getParameterValues(对应传递name属性对应的值):
		* String[] 数组:如果没有返回null
		* */
		String[] hobbyArray = request.getParameterValues("hobby");
		if(hobbyArray!=null){
			for (String s : hobbyArray) {
				System.out.println(s);
			}
		}
        /*
		3.request.getParameterMap():将传递过来的数据全部获取到,常用于框架封装
		*/
		Map<String,String[]>  parameterMap =  request.getParameterMap();
		for(Map.Entry<String,String[]> entry : parameterMap.entrySet()){
			String key = entry.getKey();
			String[] parameterValueArr = entry.getValue();
			String pameterValue = "";
			for (int i = 0; i < parameterValueArr.length; i++) {
				if(i==parameterValueArr.length-1){//单个值
					pameterValue += parameterValueArr[i];
				}else{
					pameterValue+=parameterValueArr[i]+",";
				}
			}
			System.out.println(key+":"+pameterValue);
		}

	}
}

注意:POST请求的中文乱码问题:request.setCharacterEncoding(“UTF-8”);

@WebServlet(urlPatterns = "/test03.php")
public class Test03Servlet extends HttpServlet {
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*解决POST请求的中文乱码问题或者自己使用编码和解码字符串相关方法*/
		request.setCharacterEncoding("UTF-8");
		String userName = request.getParameter("user_name");
		System.out.println(userName);
	}
}
  • 二.服务端(Servlet)传递数据给服务端(Servlet)数据(响应的页面:传递给了客户端)
    在这里插入图片描述
  1. setAttribute:存储数据
  2. getAttribute : 获取数据,返回的类型Object或者NULL
  3. removeAttribute:移除响应数据

请求转发时,必须先存储数据,后读取.若直接读取没有存储,返回null

setAttribute存储数据一致存在,请求转发只要路径不断,数据都可以访问

六、HttpSession(当前会话范围有效)

当我们访问网站的时候,需要进行登录,我们不可能在整个访问完整的过程中,一直传递我们用户名和密码,也不可能一直使用请求转发访问网页。使用Session范围存储的数据是在当前会话范围有效

只要存储过一次,我们就可以在会话范围内访问到

HttpSession session = request.getSession();//我们常用于保存登录用户的信息
//session.setAttribute()//存储数据
//session.getAttribute()

数据什么时候消失:

  • 关闭浏览器或者关闭服务器
  • 超时,当你浏览器不做任何操作的时候,默认30分注销Session
  • 手动注销方式
//1.移除特定存储的数据
HttpSession session = request.getSession();
session.removeAttribute("author");
//2.注销所有session范围数据
session.invalidate();

七、ServletContext(当前应用服务器范围有效)

存储的数据,在当前应用的服务器范围有效

package com.os.servlet;

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;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Random;

@WebServlet(urlPatterns = "/test06.php")
public class Test06Servlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("bookName","西游记");//请求范围有效
		HttpSession session = request.getSession();
		session.setAttribute("author","吴承恩");//在当前会话访问(浏览器范围)
		//ServletContext application = session.getServletContext();
		ServletContext application = request.getServletContext();
		System.out.println("服务器的绝对路径:"+application.getRealPath(""));
		application.setAttribute("price",new Random().nextInt(1000));
	}
}

当服务器关闭时候,数据会消失

八、数据传递总结

  • 重定向传递数据:需要我们拼接数据,不能传递复杂的数据,重定向传递数据中含有中文需要经过特殊处理
  • 请求转发传递数据:HttpServletRequest对象存储和获取数据
  • 会话范围存储数据:HttpSession对象存储和获取数据
    • session的注销方式
  • 应用范围存储数据:ServletContext对象存储和获取数据

注意:

  • 能用request解决,就不要用session处理
  • 能用session解决,就不要用application处理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月色夜雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值