Servlet 开发技术

news2025/2/4 17:44:03

文章目录

  • 前言
  • 创建Servlet项目
  • 处理请求并响应
    • 处理请求
    • text/plain,纯文本
    • text/html,html代码
    • application/json,JSON格式字符串
  • Servlet 生命周期
    • Servlet在整个生命周期中被调用的方法
    • Servlet运行原理
  • CORS跨域设置


前言

提示:这里可以添加本文要记录的大概内容:

在写 javaweb项目之前先下载好Tomcat与JavaWeb工具

下图展示的是某个JavaWeb工具的代码提示,可以看看自己的有没有
在这里插入图片描述


创建Servlet项目

提示:以下是本篇文章正文内容,下面案例可供参考

第一次生成JavaWeb项目:
在这里插入图片描述
往后生成JavaWeb项目:
在这里插入图片描述
第一步: 继承HttpServlet
第二步: 增加@WebServlet注解,配置地址
第三步: 重写doXXX方法(共7种),处理请求并响应

代码具体操作:

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//第二步:增加@WebServlet注解,配置地址
@WebServlet("/hello")   
					 //第一步:继承HttpServlet
public class HelloServlet extends HttpServlet{
//第三步:重写doXXX方法,处理请求并响应
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		
	}
}

处理请求并响应

处理请求

		//处理请求
		//1.获取请求中的数据
		//调用HttpServletRequest中的方法getParameter("数据名")
		String name = req.getParameter("name");
		//2.具体处理
		System.out.println("前端发送的数据是"+name);

以下是三种相应类型

text/plain,纯文本

//生成纯文本格式的响应
//1.调用HttpServletResponse中的setContentType方法设置内容类型
resp.setContentType("text/plain;charset=utf-8");
//2.调用HttpServletResponse中的getWriter方法输出响应内容
PrintWriter writer = resp.getWriter();
writer.print("Hello, world!");
writer.flush();

上面的代码设置了响应的内容类型为 text/plain,然后输出了一个字符串“Hello, world!”。注意,要在输出内容后调用 flush() 方法,将内容刷入输出流中。

输出效果:
在这里插入图片描述

text/html,html代码

//生成 HTML 代码格式的响应
//1.调用HttpServletResponse中的setContentType方法设置内容类型
resp.setContentType("text/html;charset=utf-8");
//2.调用HttpServletResponse中的getWriter方法输出响应内容
PrintWriter writer = resp.getWriter();
writer.print("<html><head><title>Hello, world!</title></head><body><h1>Hello, world!</h1></body></html>");
writer.flush();

输出效果:
在这里插入图片描述

application/json,JSON格式字符串

Student 类:

public class Student {
	private String name;
	private String sex;
	public Student() {
		super();
		// TODO 自动生成的构造函数存根
	}
	public Student(String name, String sex) {
		super();
		this.name = name;
		this.sex = sex;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	
}

servlet 类:

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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 com.google.gson.Gson;
import po.Student;
@WebServlet("/hello")   
public class HelloServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		//处理请求
		//1.获取请求中的数据
		//调用HttpServletRequest中的方法getParameter("数据名")
		String name = req.getParameter("name");
		//2.具体处理
		System.out.println("前端发送的数据是"+name);
		
		//生成响应
		//1.调用HttpServletResponse中的setContentType 设置内容类型
		resp.setContentType("application/json;charset=utf-8");
		//2.调用HttpServletResponse中的getWriter 输出流
		PrintWriter writer = resp.getWriter();
		Student s1 = new Student("张三","男");
		Student s2 = new Student("李四","女");
		ArrayList<Student> list = new ArrayList<>();
		list.add(s1);
		list.add(s2);
		Gson gson = new Gson();
		
		writer.print( gson.toJson(list));
	}
}

输出效果:
在这里插入图片描述

Servlet 生命周期

  1. 加载阶段:调用构造方法
  2. 初始化阶段:调用 init 方法
    当支持Servlet运行的Web容器接收到客户端的请求时,会先判断用户所请求的Servlet对象是否存在;如果不存在,则需要加载Servlet类,创建 Servlet的对象,然后调用Servlet的init() 方法进行初始化。
  3. 服务阶段:调用 service方法处理发送回来的请求
    容器针对本次客户端请求创建 ServletRequestServletResponse 对象,并且创建一个线程,调用Servlet对象的service( )方法,service()方法再根据客户端的请求方式间接调用 doGet() 方法或者 doPost() 方法。
    service()方法运行结束后产生响应,容器将响应发回客户端。
  4. 销毁阶段:调用 destroy方法销毁
    当Web应用被卸载或者服务器被关闭的时候,容器会销毁为本次客户端请求创建的 ServletRequestServletResponse 对象以及相应的线程。此时会调用 destroy() 方法释放资源。

需要注意的是,加载 Servlet 类,创建 Servlet 对象、调用初始化方法 init() 和销毁方法 destroy() 在Servlet的整个生命周期中都只有一次。

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/life",loadOnStartup = 5)
public class LifeCycleServlet extends HttpServlet{

	public LifeCycleServlet() {
		System.out.println("构造方法调用了");
	}
	@Override
	public void init() throws ServletException {
		// TODO init自动生成的
		System.out.println("init方法调用了");
	}
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("service方法调用了");
	}
	@Override
	public void destroy() {
		// TODO 自动生成的方法存根
		System.out.println("destroy方法调用了");
	}
}

运行项目后控制台输出:
在这里插入图片描述
那第四阶段的:销毁阶段,调用 destroy方法销毁

在Servers内,选择Tomcat右键停止
在这里插入图片描述
回到控制台:
在这里插入图片描述

Servlet在整个生命周期中被调用的方法

Servlet在整个生命周期中会有一些方法被服务器自动调用,其中的主要方法有:
init( )方法:用于初始化
Destro( )方法:用于释放资源
service( )方法:服务类方法,对用户的请求进行处理,并对用户进行响应,几乎所有处理功能都在这里完成。service( )方法通常会激活doGet( )或 doPost( ) 方法。
doGet( )方法可以响应get方式的请求,doPost( ) 方法可以响应 post方式的请求。

一般不推荐直接重写 service( )方法,而是应该重写doGet( )或者 doPost( )方法。通常,表单提交常使用post方式,超链接使用 get 方式。

Servlet运行原理

在这里插入图片描述

CORS跨域设置

CORS是一种机制,允许Web应用程序从不同的域名或端口请求资源,解除了同源策略的限制。通过添加自定义的请求头和响应头来实现,在Web服务器提供的访问策略中,允许或拒绝来自不同域的请求访问资源。CORS促进了Web应用程序的开发,并使得跨域请求更加方便。

先做一个JavaWeb中的Servlet,实现了一个简单的用户登录功能。
登录时需要传入用户名和密码,当用户名为admin,密码为111时,登录成功,返回结果为“成功”;否则返回结果为“失败”。
同时在响应中添加了允许跨域异步请求的请求头。最后将结果通过PrintWriter写回响应中,供前端页面使用。

后端代码:

// 前后端分离项目
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;

@WebServlet("/login")
public class LoginServlet extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String name = req.getParameter("name");
		String pwd = req.getParameter("pwd");
		
		String result = null;
		// ==判断的是内容
		if (name.equals("user") && pwd.equals("123456")) {
			result = "成功";
		} else {
			result = "失败";
		}  
		
		//允许跨域 异步请求                                                        * 代表所有
		resp.setHeader("Access-Control-Allow-Origin", "*");
		//我的响应类型  纯文本
		resp.setContentType("text/plain;charset=utf8");
		//得到字符输出流
		PrintWriter writer = resp.getWriter();
		//将变量result的值输出到控制台或文件中
		writer.print(result);
	}
}

启动Tomcat运行,在原本链接后用问号加上名字和密码的值:?name=user&pwd=123456

在这里插入图片描述

接下来写前端代码:

在选择功能的时候要把Router加上,因为有跳转
在这里插入图片描述
在项目成功后安装axios框架:npm i axios
在这里插入图片描述
进到项目后打开router文件夹下的 index.js 文件
在这里插入图片描述
另外除根组件外其他子组件全部删掉
在根组件中删掉 Home 和 About 以及所有样式,只留一个路由出口

删完后的显示:
在这里插入图片描述
然后新建两个子视图LoginView和IndexView

首页视图内加个h1标签,只需要表明这个视图是干嘛的就行

    <h1>欢迎访问首页视图</h1>

也在登录视图内加个h1标签,只需要表明这个视图是干嘛的就行

    <h1>登录视图</h1>

视图写完后配置路由:index.js

  1. 导入视图
import LoginView from '@/views/LoginView'
  1. 配置视图的路由,三个配置项
  {
    path: '/',
    name: 'login',
    component: LoginView
  },
  {
    path: '/index',
    name: 'index',
    component: () => import('@/views/IndexView')
  }
]

回到终端启动:

在这里插入图片描述
接下来到login视图内加一些内容(两个输入框、一个按钮、一个错误提示)

<template>
  <div>
    <h1>登录视图</h1>
    名: <input type="text" v-model="name"><br>
    密: <input type="text" v-model="pwd">
    <p v-show="isError">用户名或密码输入错误</p><br>
    <button @click="login">登录</button>
  </div>
</template>

接下来在data中配置 name、pwd、isError 的数据

  data () {
    return {
        name: '',
        pwd: '',
        isError: false
    }
  },

然后在 methods 中加一个 login定义

  methods: {
    login(){

    }
  },

在这里面完成axios请求发送,处理回来的相应数据

首先先导入:

import axios from 'axios'

其次写请求:

  methods: {
    login(){
                                                        // 模板字符串拼接动态数据
        axios.get(`http://localhost:8888/CORS/login?name=${this.name}&pwd=${this.pwd}`)
        .then((resp) =>{
          // 处理服务器后端发回的响应,使用箭头函数
          // 判断相应的数据成功还是失败
          if ( resp.data =='成功' ) {
            this.$router.push('/index')
          } else {
            // 失败显示错误提示
            this.isError = true
          }
        })
    }
  },

最后login视图完整代码:(加了样式代码,使其内容丰富)

<template>
  <div class="login-container">
    <h1>用户登录</h1>
    <form>
      <div class="form-field">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username" v-model="name">
      </div>
      <div class="form-field">
        <label for="password">&nbsp;&nbsp;&nbsp;:</label>
        <input type="password" id="password" name="password" v-model="pwd">
      </div>
      <p v-show="isError" class="error-text">用户名或密码输入错误,请重新输入</p>
      <button @click="login" class="login-btn">登录</button>
    </form>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  data () {
    return {
        name: '',
        pwd: '',
        isError: false
    }
  },
  methods: {
    login(){
                                                // 使用模板字符串拼接动态数据
      axios.get(`http://localhost:8888/CORS/login?name=${this.name}&pwd=${this.pwd}`)
        .then((resp) =>{
          // 处理服务器后端发回的响应,使用箭头函数
          // 判断相应的数据成功还是失败
          if (resp.data == '成功') {
            this.$router.push('/index')
          } else {
            // 失败显示错误提示
            this.isError = true
          }
        })
    }
  },
  components: {},
  computed: {},
  watch: {},
  mounted () {}
}
</script>

<style scoped>
.login-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 50px;
}

form {
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: #f6f6f6;
  padding: 20px;
  border-radius: 5px;
  box-shadow: 0px 1px 5px #ccc;
}

.form-field {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-bottom: 20px;
}

.form-field label {
  font-size: 18px;
  margin-right: 10px;
}

.form-field input {
  font-size: 18px;
  padding: 5px;
  border-radius: 3px;
  border: 1px solid #ccc;
  flex: 1;
}

.error-text {
  color: red;
  font-size: 18px;
  margin-top: 10px;
}

.login-btn {
  font-size: 18px;
  font-weight: bold;
  color: white;
  background-color: #4CAF50;
  border: none;
  border-radius: 5px;
  padding: 10px 20px;
  margin-top: 20px;
  cursor: pointer;
}

.login-btn:hover {
  background-color: #3E8E41;
}
</style>

输出效果:
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rust的cargo和基本数据类型

一、cargo 1、cargo 比较大的项目就不适合用rustc进行编译了&#xff0c;此时就需要使用cargo 在安装包的时候&#xff0c;会遇到网速慢卡住的问题&#xff0c;这时候就要更换国内源或者设置代理 方法一&#xff1a;设置命令行代理 方法二&#xff1a;换源 进入用户目录下的…

linux 安装redis、配置密码及简单使用

1&#xff1a;官网下载压缩包 这里我下载的是6.2.13版本。 2&#xff1a;上传到linux服务器 a:创建redis文件夹 b:进入当前redis文件夹 c:解压缩文件 d:进入 redis-6.2.713 e:使用make 命令进行编译将.c文件编译成.o文件 编译成功之后会出现“Its a good idea to run make test…

微信原生实现一个简易的图片上传功能

一、实现原理 wx.showActionSheet()&#xff1a;显示操作菜单&#xff0c;选择是从相册选择还是相机拍摄照片wx.chooseImage()&#xff1a;从本地相册选择图片或使用相机拍照。wx.uploadFile()&#xff1a;将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求&#xff0c…

在自定义数据集上微调Alpaca和LLaMA

本文将介绍使用LoRa在本地机器上微调Alpaca和LLaMA&#xff0c;我们将介绍在特定数据集上对Alpaca LoRa进行微调的整个过程&#xff0c;本文将涵盖数据处理、模型训练和使用流行的自然语言处理库(如Transformers和hugs Face)进行评估。此外还将介绍如何使用grado应用程序部署和…

分型(一)

一点想法&#xff1a; 坐标系本来就是人头脑当中的东西&#xff0c;可以根据需要动态调整&#xff0c;图像处理中&#xff0c;用动态的波看静态的图像&#xff0c;进而找出图像的特征&#xff0c;分型是不是把动态的过程呈现出静态的特征呢&#xff1f; 芒德布罗集&#xff1…

Python(十五)数据类型——bool型

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【动手学深度学习】--08.实战:Kaggle房价预测

文章目录 实战&#xff1a;Kaggle房价预测1.访问和读取数据集2.数据预处理2.1标准化数据2.2离散数据处理 3.训练4.K折交叉验证5.模型选择 实战&#xff1a;Kaggle房价预测 1.访问和读取数据集 # 如果没有安装pandas&#xff0c;请取消下一行的注释 # !pip install pandas%matp…

华为云CodeArts产品体验的心得体会及想法

文章目录 前言CodeArts 的产品优势一站式软件开发生产线研发安全Built-In华为多年研发实践能力及规范外溢高质高效敏捷交付 功能特性说明体验感受问题描述完结 前言 华为云作为一家全球领先的云计算服务提供商&#xff0c;致力于为企业和个人用户提供高效、安全、可靠的云服务。…

基于SpringBoot+vue的在线答疑系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

《实战AI低代码》:普元智能化低代码开发平台发布,结合专有模型大幅提升软件生产力

在7月6日举办的“低代码+AI”产品战略发布会上,普元智能化低代码开发平台正式发布。该平台融合了普元自主研发的专有模型,同时也接入了多款AI大模型的功能。它提供了一系列低代码产品,包括中间件、业务分析、应用开发、数据中台和业务流程自动化等,旨在简化企业的复杂软件生…

Linux网络基础 — 传输层

目录 再谈端口号 端口号范围划分 认识知名端口号 netstat pidof UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 几个问题&#xff1a; 确认应答(ACK)机制 6个标记位 超时重传机制 连接…

rust 引用怎么用

本来好好的引用&#xff0c;被 rust 玩坏了&#xff0c;搞得自己都不会使用引用了&#xff0c;我们还是从简单的例子入手&#xff0c;来探索使用引用可能遇到额问题。 下面的示例代码编译不通过&#xff0c;在 s1 赋值给变量 s2 的过程中&#xff0c;字符串 neojos 值的所有权…

webGPT浏览器安装

edge点击“获取” https://microsoftedge.microsoft.com/addons/detail/wetab%E5%85%8D%E8%B4%B9chatgpt%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5/bpelnogcookhocnaokfpoeinibimbeff?utm_sourceSteamDB # 其他浏览器安装教程如下&#xff1a; https://www.wetab.link/

springcloud gateway 介绍与使用

定义 该项目提供了一个用于在 Spring WebFlux 之上构建 API 网关的库。Spring Cloud Gateway 旨在提供一种简单而有效的方法来路由到 API&#xff0c;并为它们提供横切关注点&#xff0c;例如&#xff1a;安全性、监控/指标和弹性 特征 Spring Cloud Gateway 特性&#xff1a;…

Smartbi 身份认证绕过漏洞

0x00 简介 Smartbi是广州思迈特软件有限公司旗下的商业智能BI和数据分析产品&#xff0c;致力于为企业客户提供一站式商业智能解决方案。 0x01 漏洞概述 Smartbi在安装时会内置三个用户&#xff08;public、service、system&#xff09;&#xff0c;在使用特定接口时&#x…

只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(上)

目录 前言 settimeout/setinterval requestAnimationFrame 基本用法 时间戳参数 帧数与时间戳计算 自动暂停 JS中的贝塞尔曲线 概念 公式 二次贝塞尔 三次贝塞尔 N次贝塞尔 贝塞尔曲线动画 动画类 在动画中使用贝塞尔 总结 相关代码&#xff1a; 贝塞尔曲线相…

【深度学习】:《PyTorch入门到项目实战》(十五):三大经典卷积神经网络架构:LeNet、AlexNet、VGG

【深度学习】&#xff1a;《PyTorch入门到项目实战》(十五)&#xff1a;三大经典卷积神经网络架构&#xff1a;LeNet、AlexNet、VGG&#xff08;代码实现及实际案例比较&#xff09; ✨本文收录于【深度学习】&#xff1a;《PyTorch入门到项目实战》专栏&#xff0c;此专栏主要…

数据结构与算法——顺序表的基本操作(C语言详解版)

顺序表插入元素 向已有顺序表中插入数据元素&#xff0c;根据插入位置的不同&#xff0c;可分为以下 3 种情况&#xff1a; 插入到顺序表的表头&#xff1b;在表的中间位置插入元素&#xff1b;尾随顺序表中已有元素&#xff0c;作为顺序表中的最后一个元素&#xff1b; 虽然…

GaussDB OLTP 云数据库配套工具DAS

目录 一 、前言 二、DAS的定义 1、DAS的定义 2、DAS功能特点 三、DAS应用场景 1、标准版 2、企业版 四、操作示例&#xff08;标准版&#xff09; 1、登录华为控制台登录&#xff0c;输入账号密码 2、新增数据库实例链接 3、新建对象 4、SQL操作 5、导入导出 五、…

OC多态性浅析

OC多态性浅析 小实验 假设有以下两个类classA与class B的声明与实现&#xff1a; /// classA.h#ifndef classA_h #define classA_h#import <Foundation/Foundation.h>interface classA : NSObject-(void) printVar;end#endif /* classA_h *//// classB.h#ifndef class…