当前位置: 首页 > news >正文

Javaweb基础学习(3)

Javaweb基础学习

  • web核心介绍
  • 一、HTTP
    • 1.1 HTTP介绍
    • 1.2、HTTP请求数据格式
    • 1.3、HTTP响应数据格式
  • 二、Tomcat
    • 2.1 简介
    • 2.2 基本使用
    • 2.3 Tomcat配置
    • 2.4 Tomcat部署项目
    • 2.5 Web项目结构
    • 2.6 创建Maven Web项目
  • 三、Servlet
    • 3.1、Servlet简介&快速入门
    • 3.2 创建Servlet步骤
    • 3.3 Servlet执行流程和生命周期
    • 3.4 Servlet方法介绍&体系结构
    • 3.5 urlPattern配置
    • 3.6 XML配置Servlet
  • 四、Request(请求)
    • 4.1 Request简介
    • 4.2 Request继承体系
    • 4.3 Request 获取请求数据
    • 4.4、Request通用方式获取请求参数
    • 4.5、请求参数中文乱码处理
    • 4.6 Request请求转发
  • 五、Response(响应)
    • 5.1 设置响应数据功能介绍
    • 5.2 Response的重定向
    • 5.3 资源路径问题
    • 5.4 Response响应字符数据
    • 5.5 Response响应字节数据
  • 六、小练习
    • 6.1 登录页面
    • 6.2 注册页面

web核心介绍

  • B/S架构: Browser/Server,浏览器/服务器架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可
    好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本

在这里插入图片描述

  • 静态资源: HTML、CSS、JavaScript、图片等。负责页面展现
  • 动态资源: Servlet、JSP等。负责逻辑处理
  • 数据库: 负责存储数据
  • Web服务器: 负责解析HTTP协议,解析请求数据,并发送响应数据

一、HTTP

1.1 HTTP介绍

  • 概念: HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则

HTTP协议特点:

  • 基于TCP协议:面向连接,安全
  • 基于请求-响应模型的:一次请求对应一次响应
  • HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
    缺点多次请求间不能共享数据。-----> Java中使用会话技术(Cookie、Session)来解决这个问题
    优点:速度快

1.2、HTTP请求数据格式

请求数据分为3部分:

  • 请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本
  • 请求头:第二行开始,格式为key: value形式。
  • 请求体: POST请求的最后一部分,存放请求参数

常见的HTTP请求头:

  1. Host:表示请求的主机名

  2. User-Agent:浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 …Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko;

  3. Accept:表示浏览器能接收的资源类型,如text/,image或者*/*表示所有;

  4. Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;

  5. Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。

GET请求和POST请求的区别

  • GET请求请求参数再请求行中,没有请求体。
  • POST请求请求参数在请求体中 GET请求请求参数大小有限制
  • POST没有

1.3、HTTP响应数据格式

响应数据分为3部分:

  1. 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本,200表示响应状态码,OK表示状态码描述
  2. 响应头:第二行开始,格式为key: value形式
  3. 响应体:最后一部分。存放响应数据

常见的HTTP响应头:

  • Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
  • Content-Length:表示该响应内容的长度(字节数);
  • Content-Encoding:表示该响应压缩算法,例如gzip;
  • Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
状态码分类说明
1xx响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx成功―—表示请求已经被成功接收,处理已完成
3xx重定向——重定向到其它地方:它让客户端再发起一个请求以完成整个处理。
4xx客户端错误—―处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx服务器端错误—―处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

在这里插入图片描述

二、Tomcat

2.1 简介

  • Web服务器是一个应该程序(软件),对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷。主要功能是“提供网上信息浏览眠务”

  • 概念: Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。

  • JavaEE: Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF

  • Tomcat也被称为Web容器Servlet容器。Servlet 需要依赖于Tomcat才能运行

2.2 基本使用

  • 下载: 官网下载

  • 安装:绿色版,直接解压即可

  • 卸载:直接删除目录即可

  • 启动:双击: bin\startup.bat

在这里插入图片描述

  • 关闭:
  1. 直接×掉运行窗口:强制关闭
  2. 双击bin\shutdown.bat:正常关闭
  3. Ctrl+C:正常关闭 (建议使用)

2.3 Tomcat配置

  • 配置:

修改启动端口号:conf/server.xml
在这里插入图片描述

注意:HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号

  • 启动时可能出现的问题
    1.端口号冲突:找到对应程序,将其关闭掉
    在这里插入图片描述
    2.启动窗口一闪而过:检查JAVA HOME环境变量是否正确配置

2.4 Tomcat部署项目

  • Tomcat部署项目:
    将项目放置到webapps目录下,即部署完成
  • 一般JavaWeb项目会被打成war包,然后将war包放到webapps目录下,Tomcat会自动解压缩war文件

2.5 Web项目结构

  • Maven Web项目结构:开发中的项目
    在这里插入图片描述
  • 部署的JavaWeb项目结构:开发完成,可以部署的项目
    在这里插入图片描述
  • 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
  • pom.xml中依赖坐标对应的iar包,放入WEB-INF下的lib目
    录下

2.6 创建Maven Web项目

  • 使用骨架
    1.选择Web项目骨架,创建项目
    2.删除pom.xml中多余的坐标
    3.补齐缺失的目录结构
    在这里插入图片描述
  • 不适用骨架
    1.选择web项目骨架,创建项目
    2.pom.xml中添加打包方式为war
    3.补齐缺失的目录结构: webapp
    在这里插入图片描述

== 通过插件进行创建web项目==

  1. 讲下面代码放置于pom.xml 添加Tomcat插件
<build><plugins><!-- Tomcat 插件--><plugin><groupld>org.apache.tomcat.maven</groupld><artifactld>tomcat7-maven-plugin</artifactld><version>2.2</version></plugin></plugins>
</build>
  1. 使用Maven Helper插件快速启动项目,选中项目,右键–> Run Maven --> tomcat7:run

在这里插入图片描述

三、Servlet

3.1、Servlet简介&快速入门

  • Servlet是Java提供的一门 动态 web资源开发技术
  • Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet

3.2 创建Servlet步骤

1. 首先导入Servlet依赖包

    <dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies>

注意:在导包的时候要 记到导入 <scope>provided</scope> 要不然在运行的时候会报错

  1. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话
public class ServletDemo1 implements Servlet {public void service()
}
  1. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {}
  1. 访问:启动Tomcat,浏览器输入URL 访问该Servlet
    http://localhost:8080/tomcat1_war/login

3.3 Servlet执行流程和生命周期

  1. Servlet由谁创建? Servlet方法由谁调用?

Servlet由web服务器创建,Servlet方法由web服务器调用。

  1. 服务器怎么知道servlet中一定有service方法?

因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,而Servlet接口中有service方法

生命周期:

解释:

对象的生命周期指一个对象从被创建到被销毁的整个过程

  • Servlet运行在servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
  1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建servlet对象

非默认情况下可以该改变创建时机

@WebServlet (urlPatterns = "/demo",loadOnStartup =1)

负整数:第一次被访问时创建Servlet对象
0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高

  1. 初始化:在Servlet实例化之后,容器将调用servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

  2. 请求处理:每次请求Servlet时,Servlet容器都会调用servlet的service()方法对请求进行处理。

  3. 服务终止:当需要释放内存或者容器关闭时,容器就会调用servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

3.4 Servlet方法介绍&体系结构

  • 初识化方法,在Servlet被创建的时候执行,就只执行一次
 @Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("在初始创建的时候就执行该方法,就执行一次,init…………");}
  • 提供服务的方法,每次调用Servlet的时候都会调用该方法
@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("当每次访问Servlet的时候就会执行一次,service…………");}
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁Servlet
@Overridepublic void destroy() {System.out.println("当该Servlet销毁的时候就执行一次,一共执行一次,destory…………");}

获取ServletConfig对象

ServletConfig getServletConfig()

获取Servlet信息

String getServletInfo()

体系结构:
在这里插入图片描述

我们将来开发B/S架构的web项目,都是针对HTTP协议所以我们自定义Servlet,会继承HttpServlet

继承的HttpServlet就是人家封装好的Servlet对象,便于我们web开发

HttpServlet使用方法:

  1. 继承HttpServlet
  2. 重写doGet()–> 请求方式:get 和 doPost()方法–>请求方式:post
  3. 通过重写的方法来进行不同请求方式的获取数据方式

HttpServlet原理:

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.interfaces.RSAKey;public class ServletDom2 implements Servlet {@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("创建时调用,只调用一次");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {//将其进行强制转换HttpServletRequest req = (HttpServletRequest) servletRequest;HttpServletResponse res =(HttpServletResponse) servletResponse ;//获取到请求的方式String method = req.getMethod();//通过不同请求方式来进行判断if ("GET".equals(method)){System.out.println("get………………");doGet(req,res);}else if ("POST".equals(method)){System.out.println("post…………");doPost(req, res);}}protected void doPost(HttpServletRequest req, HttpServletResponse res) {}protected void doGet(HttpServletRequest req, HttpServletResponse res) {}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {}
}

3.5 urlPattern配置

Servlet要想被访问,必须配置其访问路径(urlPattern)

  1. 一个Servlet,,可以配置多个urlPattern
@WebServlet(urlPatterns = {"/demo1", "/demo2"}) //这两个路径都可以访问到这个页面
  1. urlPattern配置规则
  • 精确匹配
    配置路径:@WebServlet(urlPatterns = “/user/select”)
    访问路径:localhost:8080/web-demo/user/select
  • 目录匹配
    配置路径:@WebServlet(urlPatterns = "/user/")
    访问路径:localhost:8080/web-demo/user/
  • 扩展名匹配
    配置路径:@WebServlet(urlPatterns = “*.do”)
    访问路径:localhost:8080/web-demo/aaa.do
    localhost:8080/web-demd/bbb.do
  • 任意匹配 -->尽量不要使用这个配置,因为主要是因为会替换源文件的默认访问,会导致静态资源等无法访问到
    配置路径:@WebServlet(urlPatterns = “/”)
    @WebServlet(urlPatterns = “/*”)
    访问路径:localhost:8080/web-demo/hehe
    localhost:8080/web-demo/hehe

和/*区别:

当我们的项目中的Servlet配置了“/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet
当我们的项目中配置了“/*”,意味着匹配任意访问路径
注:不要使用这两个路径,会覆盖掉DefaultServlet,导致无法加载出静态资源

优先级:
精确路径>目录路径>扩展名路径>/* >/

3.6 XML配置Servlet

  • Servlet 从3.0版本后开始支持使用注解配置,3.0版本前只支持XML配置文件的配置方式
    步骤
    1.编写Servlet类
    2.在web.xml中配置该Servlet
<servlet><servlet-name>demo5</servlet-name><servlet-class>com.Smulll.web.servlet.servletDemo5</servlet-class>
</servlet>
<servlet-mapping><servlet-name>demo5</servlet-name><url-pattern>/demo5</url-pattern>
</servlet-mapping>

四、Request(请求)

4.1 Request简介

  • Request:获取请求数据

在这里插入图片描述

4.2 Request继承体系

在这里插入图片描述

  • Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
  • 使用request对象,查阅JavaEE API文档的 HttpServletRequest 接口

4.3 Request 获取请求数据

一般分为三个部分:

  1. 请求行
    在这里插入图片描述
  • String getMethod()获取请求方式:GET
  • String getContextPath()获取虚拟目录(项目访问路径):/request-demo
  • StringBuffer getRequestURL()获取URL(统一资源定位符): http://localhost:8080/request-demo/req1
  • String getRequestURI()获取URI(统一资源标识符): /request-demo/req1
  • String getQueryString()获取请求参数(GET方式) :username=zhangsan&password=123
//1. 获取到请求数据的方法String method = req.getMethod();System.out.println(method);//2. 获取到虚拟地址String contextPath = req.getContextPath();System.out.println(contextPath);//3.获取到访问地址String uri = req.getRequestURI();System.out.println(uri);//4.完整地址StringBuffer url = req.getRequestURL();System.out.println(url);//5. 获取到后面用户后面的值String queryString = req.getQueryString();System.out.println(queryString);
  1. 请求头:
    在这里插入图片描述

String getHeader(String name):根据请求头名称,获取值

  1. 请求体:username=superbaby&password=123
  • ServletlnputStream getInputStream():获取字节输入流
  • BufferedReader getReader():获取字符输入流

4.4、Request通用方式获取请求参数

请求参数获取方式:

  • GET方式:
String getQueryString()
  • POST方式
BufferedReader getReader()

由于不同的请求方式,出现不同的获取方式过于复杂,所以就创建了统一的获取数据方法

  • Map<String, String[ ]> getParameterMap():获取所有参数Map集合
  • String[ ] getParameterValues(String name)︰根据名称获取参数值(数组)
  • String getParameter(String name):根据名称获取参数值(单个值)
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;
import java.io.Reader;
import java.util.Map;@WebServlet("/req1")
public class RequestDom1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. 通过获取到所有的key值Map<String, String[]> map = req.getParameterMap();for (String key : map.keySet()) {System.out.print(key +": ");//2. 通过key值来获取到参数值String[] strings = map.get(key);for (String value : strings) {System.out.println(value + " ");}System.out.println();}//2. 通过名称来获取到当前的数据String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);// 3. 通过获取到数组组合String[] values = req.getParameterValues("hobby");for (String value : values) {System.out.println(value);}}
}

4.5、请求参数中文乱码处理

请求参数如果存在中文数据,则会乱码

解决方案:

  • POST:设置输入流的编码
    req.setCharacterEncoding(“UTF-8”);

  • 通用方式(GET/POST):先编码,再解码
    new String(username.getBytes(“ISO-8859-1”),“UTF-8”);

  • URL编码
    1.将字符串按照编码方式转为二进制
    2.每个字节转为2个16进制数并在前边加上%

 @Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String s = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);System.out.println(s);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");String username = req.getParameter("username");System.out.println(username);}

4.6 Request请求转发

请求转发: 在服务器内部的一种资源跳转方式

简单理解为:
在这里插入图片描述

实现方式:

req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据: 使用Request对象
    1.void setAttribute(String name, Object o):存储数据到request域中
    2.Object getAttribute(String name):根据key,获取值
    3.void removeAttribute(String name):根据key,删除该键值对

请求转发特点

  1. 浏览器地址栏路径不发生变化
  2. 只能转发到当前服务器的内部资源
  3. 一次请求,可以在转发的资源间使用request共享数据

req3

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("/req3")
public class RequestDom3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置键值对和值req.setAttribute("msg","hello Request!!");System.out.println("req3");//跳转req4进行解析数据req.getRequestDispatcher("/req4").forward(req,resp);}
}

req4

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("/req4")
public class RequestDom4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取到键值对的值Object msg = req.getAttribute("msg");System.out.println(msg);System.out.println("req4");}
}

五、Response(响应)

5.1 设置响应数据功能介绍

响应数据被分为三部分:

  1. 响应行 : HTTP/1.1 200 oK

void setStatus(int sc)∶设置响应状态码

  1. 响应头 : Content-Type: text/html

void setHeader(String name,String value)∶设置响应头键值对

  1. 响应体 : <html><head>head><body></body></html>
  • PrintWriter getWriter():获取字符输出流
  • ServletOutputStream getOutputStream():获取字节输出流

5.2 Response的重定向

概念: 重定向就是一种资源跳转方式
在这里插入图片描述
实现方法:

  1. 原始方法:
        //1. 定义响应的状态码resp.setStatus(302);//2. 设置状态头resp.setHeader("location","/tomcat1/resp2");
  1. 简洁方法:
String contextPath = req.getContextPath();//获取到虚拟路径resp.sendRedirect(contextPath+"/resp2");
  • 重定向特点:
  1. 浏览器地址栏路径发生变化
  2. 可以重定向到任意位置的资源(服务器内部、外部均可)
  3. 两次请求,不能在多个资源使用request共享数据

5.3 资源路径问题

通过使用的对象进行判断:

  • 浏览器使用资源路径需要添加虚拟路径
  • 服务端使用资源路径不需要虚拟路径

在这里插入图片描述

5.4 Response响应字符数据

使用:

  • 通过Response对象获取字符输出流
PrintWriter writer = resp.getWriter();
  • 写数据
writer.write("aaa");

注意:

  1. 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
  2. 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
package Response;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;
import java.io.PrintWriter;@WebServlet("/resp3")
public class ResponseDom3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1. 设置其的编码方式于读写内容的方式resp.setContentType("text/html;charset=UTF-8");//2. 获取输出流PrintWriter writer = resp.getWriter();writer.write("<h1>你好!!!!! response</h1>");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}

5.5 Response响应字节数据

使用:

  • 通过Response对象获取字符输出流
ServletOutputStream outputStream = resp.getOutputStream();
  • 写数据
outputStream.write(字节数据);
package Response;import org.apache.commons.io.IOUtils;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;@WebServlet("/resp4")
public class ResponseDom4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 创建一个字节输出流FileInputStream fis = new FileInputStream("E://a.png");// 2. 创建一共字节输出流ServletOutputStream os = resp.getOutputStream();/*byte[] bytes = new byte[1024];int len;// 3. 写入数据while ((len = fis.read())!= -1){os.write(bytes,0,len);}*/IOUtils.copy(fis,os);fis.close();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}
  • IOUtils工具类使用
  1. 导入坐标
<dependency><groupld>commons-io</groupld><artifactld>commons-io</artifactld><versign>2.6</version>
</dependency>
  1. 使用
IOUtils.copy(输入流,输出流);

六、小练习

6.1 登录页面

html页面:

<%--Created by IntelliJ IDEA.User: LENOVODate: 2023/8/17Time: 10:47To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<div style="text-align: center"><form action="login" method="get" id="loginForm">姓名:<input type="text" name="uname" id="uname"> <br>密码:<input type="password" name="upassword" id="upassword" > <br>验证码: <input type="text" name="verify" id="verify"><br><img src="https://ts4.cn.mm.bing.net/th?id=OIP-C.rHuc8SKa0wLVwCqqA27uIwHaEt&w=313&h=199&c=8&rs=1&qlt=90&o=6&dpr=1.6&pid=3.1&rm=2" height="30px;" width="45px"><span id="msg" style="color: red ; font-size:12px;" ></span><br><button type="button" id="loginBtn">登录</button><button type="button" id="registerBtn">注册</button></form>
</div>
</body>
<script type="text/javascript" src="./js/jquery-3.4.1.js"></script>
<script type="text/javascript">$("#loginBtn").click(function(){//获取到用户名和密码和邮箱var uname = $("#uname").val();var upassword =$("#upassword").val();var verify =$("#verify").val();//判断他们是否为空if(isNull(uname)){$("#msg").html("当前用户名不能为空");return;}if(isNull(upassword)){$("#msg").html("当前密码不能为空");return;}if(isNull(verify)){$("#msg").html("当前邮箱不能为空");return;}//如果都不为空就提交数据$("#loginForm").submit();});//创建一个方法来验证所获取到的物质是否为空function isNull(str){if(str = null || str.trim() == ""){return true;}return false;}</script></html>

servletLogin页面:

package com.huanglei.Serverlets;import com.huanglei.mapper.UserMapper;
import com.huanglei.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;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;
import java.io.InputStream;
import java.io.PrintWriter;@WebServlet("/login")
public class ServerletLogin extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.首先获取到传过来的数据String userName = req.getParameter("uname");String userPassword = req.getParameter("upassword");String  verify= req.getParameter("verify");//2.常规获取sqlsessionString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);//通过查询来找到是否包含这个用户名User user = mapper.selectAll(userName);//添加数据响应//首先设置其编/解码规范resp.setContentType("text/html;charset=utf-8");//获取writer对象PrintWriter writer = resp.getWriter();//判断if (user == null){//响应数据writer.write("<h1>不存在该用户请重新输入</h1>");System.out.println("不存在该用户请重新输入");return;}//若存在该用户,通过查询找到该密码是否正确String userPassword1 = user.getUserPassword();//判断该用户密码是否正确if (!userPassword1.equals(userPassword)){writer.write("<h1>密码不正确,请重新输入</h1>");System.out.println("密码不正确,请重新输入");return;}writer.write("登陆成功!!!");System.out.println("登陆成功!!!");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);}
}

6.2 注册页面

html:

<%--Created by IntelliJ IDEA.User: LENOVODate: 2023/8/9Time: 9:05To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>注册界面展示</title>
</head>
<body>
<div style="text-align: center"><form action="register" method="post" id="FormRegister">用户名:<input type="text" name="rname" id="rname"> <br>密码:<input type="password" name="rpassword" id="r_password"> <br>确认密码: <input type="password" name="Rpassword" id="Rpassword"><br>邮箱: <input type="text" name="email" id="email"><br><span id="msg" style="color: red ; font-size:12px;" ></span><br><button type="button" id="registerBtn">注册</button></form>
</div>
</body>
<script type="text/javascript" src="./js/jquery-3.4.1.js"></script>
<script type="text/javascript" >function check() {//判断用户名长度是否超过8var name = $("#rname").val(); // trim去除空格if (name.length > 8  ) {$("#msg").html("用户名长度不能超过8");return false;}//用户名不能有数字for (var i = 0; i < name.length; i++) {var str = name.substring(i, i + 1);if (isNaN(str) === false) {$("#msg").html("用户名只能为字母或中文字符");return false;}}//判断密码是否大于6~12var password = $("#r_password").val();if (password.length < 6 || password.length > 12 ) {$("#msg").html("密码长度必须在6~12之间");return false;}//判断密码为数字+英文//邮箱中必须包含@ 和 .var email=$("#email").val();if(email.indexOf("@")===-1){$("#msg").html('邮箱中必须包含@');return false;}if(email.indexOf(".")===-1){$("#msg").html('邮箱中必须包含.');return false;}return true;}$("#registerBtn").click(function(){//获取到用户名和密码和邮箱var rname = $("#rname").val();var r_password =$("#r_password").val();var Rpassword =$("#Rpassword").val();var email =  $("#email").val();//判断他们是否为空if(isNull(rname)){$("#msg").html("当前用户名不能为空");return;}if(isNull(r_password)){$("#msg").html("当前密码不能为空");return;}if(isNull(Rpassword)){$("#msg").html("当前确认密码不能为空");return;}if(isNull(email)){$("#msg").html("当前邮箱不能为空");return;}if (r_password !== (Rpassword)){$("#msg").html("密码与确认密码不相符合!");return;}if (check()){alert("注册成功!!!")//若都不为空就提交$("#FormRegister").submit();}});//创建一个方法来验证所获取到的物质是否为空function isNull(str){if(str == null || str.trim() === ""){return true;}return false;}</script>
</html>

serverletRegister:

package com.huanglei.Serverlets;import com.huanglei.mapper.UserMapper;
import com.huanglei.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;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;
import java.io.InputStream;
import java.io.PrintWriter;@WebServlet("/register")
public class ServletRegister extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.首先获取到其输入的数据信息String userName = req.getParameter("rname");String userPassword = req.getParameter("rpassword");String email = req.getParameter("email");//2. 首先判断其当中是否含有该用户// 常规获取sqlsessionString resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper mapper = sqlSession.getMapper(UserMapper.class);//通过查询来找到是否包含这个用户名User user = mapper.selectAll(userName);//返回数据,设置解码规则resp.setContentType("text/html;charset=utf-8");PrintWriter writer = resp.getWriter();//判断是否包含该用户if(user != null){writer.write("已经存在该用户");return;}//不存在该用户,创建User类存储数据,将数据加入到数据库User user1 = new User();user1.setUserEmail(email);user1.setUserName(userName);user1.setUserPassword(userPassword);user1.setUserId(null);mapper.addTables(user1);sqlSession.commit();sqlSession.close();}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req,resp);}
}

相关文章:

Javaweb基础学习(3)

Javaweb基础学习 web核心介绍一、HTTP1.1 HTTP介绍1.2、HTTP请求数据格式1.3、HTTP响应数据格式 二、Tomcat2.1 简介2.2 基本使用2.3 Tomcat配置2.4 Tomcat部署项目2.5 Web项目结构2.6 创建Maven Web项目 三、Servlet3.1、Servlet简介&快速入门3.2 创建Servlet步骤3.3 Serv…...

使用在 Web 浏览器中运行的 VSCode 实现 ROS2 测程法

一、说明 Hadabot是软件工程师学习ROS2和机器人技术的机器人套件。我们距离Hadabot套件的测试版还有一周左右的时间。我们将在本文末尾披露有关如何注册的更多信息。 新的Hadabot套件完全支持ROS2。除了硬件套件外&#xff0c;Hadabot软件环境将主要基于Web浏览器&#xff0c;以…...

快速学习GO语言总结

备注&#xff1a;本博客将自己初步学习GO的总结进行分享&#xff0c;希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力&#xff0c;如有错误请留言指正&#xff0c;谢谢&#xff01; 一、初步了解Go语言 &#xff08;一&#xff09;Go语言诞生的主要问题和目标…...

尚硅谷宋红康MySQL笔记 10-18

是记录&#xff0c;我不会记录的特别详细 第10章 创建和管理表 标识符命名规则 数据库名、表名不得超过30个字符&#xff0c;变量名限制为29个只能包含 A–Z, a–z, 0–9, _共63个字符数据库名、表名、字段名等对象名中间不要包含空格同一个MySQL软件中&#xff0c;数据库不能…...

Java 面试题--SpringBoot篇

一、什么是 SpringBoot&#xff1f; Spring Boot 是 Spring 开源组织下的子项目&#xff0c; 是 Spring 组件一站式解决方案&#xff0c;主要是简化 了使用 Spring 的难度&#xff0c;简省了繁重 xml 的配 置&#xff0c;提供了各种启动器&#xff0c;在运行过程中自定 配置,&a…...

GitKraken 详细图文教程

前言 写这篇文章的原因是组内的产品和美术同学&#xff0c;开始参与到git工作流中&#xff0c;但是网上又没有找到一个比较详细的使用教程&#xff0c;所以干脆就自己写了一个[doge]。文章的内容比较基础&#xff0c;介绍了Git内的一些基础概念和基本操作&#xff0c;适合零基…...

ubuntu20.04 root用户下使用中文输入法——root用户pycharm无法用中文输入法问题

因为一些众所不周知的bug&#xff0c;我的pycharm使用apt或者snap安装都不行了&#xff0c;官网下了“绿色版”&#xff0c;运行pycharm.sh也运行不起来&#xff0c;有个java相关环境报错&#xff0c;jre和jdk都装了&#xff0c;还是有点问题&#xff0c;最后尝试发现可以用roo…...

FastDFS与Nginx结合搭建文件服务器,并实现公网访问【内网穿透】

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…...

嵌入式蓝海变红海?其实是大浪淘沙!

嵌入式是当下热门的职业方向之一&#xff0c;吸引了众多求职者的目光。然而&#xff0c;有人担心大家一拥而上&#xff0c;导致嵌入式就业竞争激烈&#xff0c;找工作难度大。其实&#xff0c;嵌入式行业的竞争并非无法逾越的天堑&#xff0c;也远远没有从蓝海变成红海&#xf…...

【附安装包】Solid Edge2023安装教程最强CAD选择

软件下载 软件&#xff1a;Solid Edge版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;3.85G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a;https://pan.bai…...

494. 目标和

494. 目标和 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;数组回溯法动态规划 参考代码&#xff1a;数组回溯法__494目标和__动态规划 经验吸取 原题链接&#xff1a; 494. 目标和 https://leetcode.cn/problems/target-sum/description/ 完成情况&#…...

C++学习笔记总结练习:C++编译过程详解

编译和链接的过程 0 概述 程序要运行起来&#xff0c;必须要经过四个步骤&#xff1a;预处理、编译、汇编和链接。接下来通过几个简单的例子来详细讲解一下这些过程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFwSfKYp-1692237034055)(imag…...

嵌入式设备应用开发(qt界面开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 linux界面开发有很多的方案可以选。比如说lvgl、minigui、ftk之类的。但是,这么多年来,一直屹立不倒的还是qt。相比较其他几种方案,qt支持多个平台,这里面就包括了linux平台。此…...

pytest结合Excel实现接口自动化

前言 我们先来回顾下之前篇章“pytest通过parametrize方法实现数据驱动实战”&#xff0c;主要是通过yaml文件来读取测试用例。而我们用Excel文件存放测试用例又有什么区别呢&#xff1f; 毫无疑问&#xff0c;Pytest自动化测试框架也能读取Excel文件实现数据驱动。 还记得之…...

【LLM数据篇】预训练数据集+指令生成sft数据集

note 在《Aligning Large Language Models with Human: A Survey》综述中对LLM数据分类为典型的人工标注数据、self-instruct数据集等优秀的开源sft数据集&#xff1a;alpaca_data、belle、千言数据集、firefly、moss-003-sft-data多轮对话数据集等 文章目录 note构造指令实例…...

WebDAV之π-Disk派盘 + 一羽记帐

一羽记帐是一款真正让你体验3S极速记账的轻量级APP。针对个人记账,没有花哨冗余的功能。界面美丽、无广告、极速启动、功能全面。一羽记帐功能涵括广,基本可以满足90%人的记账需求。完全无侵入、百分百无广告,无需担心数据安全,所有的操作都不经过任何第三方。 π-Disk派盘…...

ChatGPT:记一次超复杂的KVM桌面系统连接问答记录

​ KVM切换器可以使多台电脑共用键盘&#xff0c;显示器&#xff0c;鼠标&#xff0c;当电脑很多&#xff0c;显示器也是分为主从&#xff0c;需要共用键盘鼠标和音响设备&#xff0c;而买KVM切换器只有2个通道4进2出不满足需求时&#xff0c;就要组合多个KVM使用&#xff0c;大…...

python-docx把dataframe表格添加到word文件中

python-docx把dataframe表格添加到word文件中思路较为简单&#xff1a; 先把dataframe格式转变为table新建一个段落&#xff1a;document.add_paragraph()把table添加到这个段落下方 效果图 示例代码 from docx import Document, oxml import pandas as pd import numpy as …...

Web AP—BOM 浏览器对象模型

代码下载 BOM BOM&#xff08;Browser Object Model&#xff09;即浏览器对象模型&#xff0c;它提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是 window。 BOM 由一系列相关的对象构成&#xff0c;并且每个对象都提供了很多方法与属性。 BOM 缺乏标…...

Flink分流,合流,状态,checkpoint和精准一次笔记

第8章 分流 1.使用侧输出流 2.合流 2.1 union &#xff1a;使用 ProcessFunction 处理合流后的数据 2.2 Connect &#xff1a; 两条流的格式可以不一样&#xff0c; map操作使用CoMapFunction&#xff0c;process 传入&#xff1a;CoProcessFunction 2.2 BroadcastConnectedSt…...

c# 实现sql查询DataTable数据集 对接SqlSugar ORM

有时候对于已经查询到的数据集&#xff0c;想要进行二次筛选或者查询&#xff0c;还得再查一遍数据库 或者其他的一些逻辑处理不太方便&#xff0c;就想着为什么不能直接使用sql来查询DataTable呢&#xff1f; 搜索全网没找到可用方案&#xff0c;所以自己实现了一个。 主要…...

记一次布尔盲注漏洞的挖掘与分析

在上篇文章记一次由于整型参数错误导致的任意文件上传的漏洞成因的分析过程中&#xff0c;发现menu_id貌似是存在注入的。 public function upload() {$menu_id $this->post(menu_id);if ($id) {$where "id {$id}";if ($menu_id) {$where . " and menu_id…...

C++11 新特性 ---- noexcept

1. 异常 异常通常用于处理逻辑上可能发生的错误 在C98中&#xff0c;提供了一套完善的异常处理机制&#xff0c;直接在程序中将各种类型的异常抛出&#xff0c;从而强制终止程序的运行。 1.1 基本语法 当函数抛出异常时&#xff0c;程序会停止执行&#xff0c;并显示异常信息…...

《Linux运维总结:Centos7.6之OpenSSH7.4p1升级版本至9.4p1》

Centos通过yum升级OpenSSH 在官方支持更新的CentOS版本&#xff0c;如果出现漏洞&#xff0c;都会通过更新版本来修复漏洞。这时候直接使用yum update就可以升级版本。 yum -y update openssh 但是&#xff0c;CentOS更新需要有一段时间&#xff0c;不能在漏洞刚出来的时候就有…...

七夕节日表白:七大网页风格与其适用人群

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

通达信指标公式16:使用BARSLAST函数写一个指标回测的思路

★★★★★博文原创不易&#xff0c;我的博文不需要打赏&#xff0c;也不需要知识付费&#xff0c;可以白嫖学习小技巧&#xff0c;喜欢的老铁可以多多帮忙点赞&#xff0c;小红牛在此表示感谢&#xff0c;就是对作者的最大支持。愿与诸君共勉&#xff0c;悟道于股市★★★★★…...

Jenkins自动化部署Vue项目

1、新建item&#xff0c;选择 Freestyle project 2、源码管理选择git&#xff0c;输入git仓库地址和授权账号&#xff0c;并指明要部署的分支 3、构建选择 Execute shell&#xff0c;输入vue项目打包命令 命令示例&#xff1a; source /etc/profile node -v npm config set re…...

Android JNI打印logcat日志

在 JNI 中打印日志可以使用 __android_log_print 函数来实现。该函数是 Android NDK 提供的一个用于在本地代码中输出日志消息到 logcat 的方法。 要在 JNI 中打印日志&#xff0c;请按照以下步骤进行操作&#xff1a; 在你的 JNI C/C 代码中包含 <android/log.h> 头文件…...

第28次CCF计算机软件能力认证(测试)

测试300分要是考试的时候也能这么发挥就好 第一题&#xff1a;现值计算 解题思路&#xff1a;直接模拟 n , m input().split() n int(n);m float(m) l list(map(int , input().split())) res 0 for i in range(0 , n 1):res pow(1 m , -i) * l[i] print(res) 第二题…...

九耶丨阁瑞钛伦特-Java高频面试题-请谈谈 ReadWriteLock 和 StampedLock

ReadWriteLock包括两种子锁 &#xff08;1&#xff09;ReadWriteLock ReadWriteLock 可以实现多个读锁同时进行&#xff0c;但是读与写和写于写互斥&#xff0c;只能有一个写锁线程在进行。 &#xff08;2&#xff09;StampedLock StampedLock是Jdk在1.8提供的一种读写锁&a…...

做网站需要哪些技术/自助建站系统软件

量化投资是指使用数理分析、编程、建模等方式&#xff0c;通过对样本数据进行集中比对处理&#xff0c;找到数据之间的关系&#xff0c;制定量化策略&#xff0c;并使用编写的软件程序来执行交易&#xff0c;从而获得投资回报的方式。在如今的量化投资领域&#xff0c;已经有了…...

wordpress mysql 数据库/促销方案

SessionⅠ 关于SessionⅡ Seesion的用法A. 向Session存入数据B. 获取Session的值C. Session的删除与注销Ⅲ Session和Cookie的异同总结Ⅰ 关于Session 在前面一篇讲Cookie的文章中我提到了会话的概念&#xff0c;->Cookie&#xff0c;这个Seesion就是一个会话。关于seesion…...

十大高端网站建设/比较靠谱的电商培训机构

一次WIFI渗透小米4A千兆路由器提权开telnet 到朋友家里&#xff0c;手机信号太差了&#xff0c;于是想连个wifi网络。苦于没有Wi-Fi密码&#xff0c;于是这篇文章便有了着落。 1. 网络嗅探 打开手机 WIFI 发现周围的 WIFI 热点挺多的&#xff0c;用模拟器下载WIFI万能钥匙开始…...

网站建设开发感悟/百度广告费用

JS版本  整体思路就是&#xff1a;不管多少层级&#xff0c;每层都需要添加子类进去&#xff0c;写个递归函数寻找子类即可var data [{"txt":"成都","key":"成都","val":"","parentKey":"四川&…...

可以做司法考试题的网站/软文营销的宗旨是什么

昨天师哥师姐參加了北京一家IT公司的面试&#xff0c;说心里话自己很想去&#xff0c;很想提前了解下公司的面试。无奈自己水平有限&#xff0c;没有资格參加面试&#xff0c;无限羡慕中…… 大神们一归来&#xff0c;我就開始询问他们的面试过程&#xff0c;正所谓总结前人的经…...

模板网站官网/会计培训班一般收费多少

相关题目与解析2017年6月1日&#xff0c;()开始施行。A.中华人民共和国计算机信息系统安全保护条例B.计算机信息系统国际物理安全是计算机信息系统安全的保障&#xff0c;保证计算机信息系统各种设备的物理安全是保障整个网络系统安全的前提。()计算机信息系统的安全保护&#…...