jsp实现前后端交互
jsp实现前后端交互
编辑器:Idea 2020.2.3 notepad++
图形编辑器:mspaint
1 JSP技术概述
JSP全名为Java Server Pages
,中文名叫java服务器页面,其根本是一个简化的Servlet
设计,它是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML(标准通用标记语言的子集)文件(*.htm
,*.html
)中插入Java程序段(Scriptlet
)和JSP标记(tag
),从而形成JSP文件,后缀名为(*.jsp
)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。
它实现了Html语法中的java扩张(以 <%, %>形式)。JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。
为了能够使用java作为后端并通过servlet实现前后端通信,不妨将所有html改成jsp,jsp中实现表单创建,并上传至后端指定类,后端对数据库进行某些操作是的最终实现前端和数据库的交互。
2 servlet方面
2.1 整体功能
在前端实现表单创建和发送请求,tomcat服务器接收到请求后,使用重写后的doGet(request,response)
方法对发送过来的请求进行处理,由于实现的是登录功能,故而在处理前端请求时需要访问数据库。
在serlet重写过程中需要重写doGet()
方法,故而新建Login
类继承HttpServlet
类,进而改写所需方法。
2.2 tomcat配置
如果想要使用前后端交互功能,那么需要使用服务器,这里选用的是tomcat
服务器。将前端请求发送至tomcat
服务器后,根据设定将请求转至相应的后端程序。
2.2.1 下载与安装
关于tomcat
配置,首先就是需要下载tomcat
服务器。这个很简单,直接去官网,速度还行。
tomcat
官方网址:https://tomcat.apache.org/download-90.cgi
如果下载的是zip
,就是免安装版的,直接解压到喜欢的路径即可。我的路径是D:\jarfile\
2.2.2 项目结构配置
安装完成后就是相应的项目配置了。首先需要做的就是将项目转为web
项目。点击F4
,进入项目结构界面。
点击加号后在下拉箭头选择web
。这样会在原来的项目根目录下生成一个web
目录,可以在这个目录下书写相关的jsp
文件。
ps:其实,除了本身功能,jsp
文件的书写和html文件的书写没有什么本质区别,只是jsp
文件可以用java语言书写部分代码实现更多功能。故而可以把web
作为html
的根目录,在里面进行网页编写,但是网页后缀需要改成jsp
。上图中也有我的项目结构,仅做参考。
其次就是对项目文件标记的说明。如果想要将某些文件夹作为某些用途,需要对此文件夹进行标记。例如,src
是源码文件夹,此文件夹需要创建的是class
、interface
、enum
,但是倘若在没有标记的情况下,编辑器并不会知道这是什么用途的文件夹。就可能会发生无法进行新建java
类的问题。按照下图标记
将src
标记为sources
,out
标记为Excluded
(out是输出文件夹,相当于代码回收场,是一次编译后的结果,再次编译项目是创建的索引不会包含out的),其余的标记可以自行百度,这里不做额外补充
点击Dependencies
再点击加号建立相关的jar
包依赖。点击加号之后会弹出一个下拉菜单,选择里面的library
,光标置于library
上时就会有另一个下拉菜单,选择里面的java
,进而去选择路径,此时的路径就是2.2.1步骤你解压的tomcat
路径,这样就把tomcat
的依赖添加进来啦。至于mysql
jar
包的导入,就按照咱们最原始的jar
包导入就好啦。我存放项目jar包的路径是项目路径下的lib
,然后再“add as library
"就可以啦。
ps:add as library,文件夹右键,里面就有,慢慢找不要慌。
2.2.3 Debug配置
这个时候基本配置就已经完成了,但是还是不能运行的。因为还没有对Debug
就行配置
选择tomcat server
的时候其实选择一个就够了,我选择的是local
,之后就是弹出来一个命名,根据自己口味酌情命名。
点击F4
,进入project structure
,选择artifacts
,然后如图选择就行,顺序是+
->web application
->from module
,再点击以此确定就好了。
截至目前为止,整个项目的配置就完成啦!
2.2.4 web文件夹配置
废话不多说,在解释之前,先贴上源码(解释在源码中了/呲牙/呲牙/呲牙)
<?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"><!-- 欢迎文件,在项目运行时弹出的第一个界面 --><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 在服务器上运行的小程序设定 --><!-- 一个servlet对应一个servlet-mapping --><servlet><servlet-name>Login</servlet-name><!-- 小程序对应后端路径 --><!-- 这里指的是相对路径,src下的com.servlet.login.Login --><!-- Login即为我的实现登录的后端类 --><servlet-class>com.servlet.login.Login</servlet-class></servlet><!-- 小程序映射路径 --><servlet-mapping><servlet-name>Login</servlet-name><!-- 这个是编译运行时小程序对应的输出路径,位于out中 --><url-pattern>/servlet/login</url-pattern></servlet-mapping><!-- 与上同 --><servlet><servlet-name>Register</servlet-name><servlet-class>com.servlet.register.Register</servlet-class></servlet><servlet-mapping><servlet-name>Register</servlet-name><url-pattern>/servlet/register</url-pattern></servlet-mapping>
</web-app>
如果没有解释清楚的话,可以对照我的项目树状图理解这一部分。
2.3 Login
在Account.jsp
文件中调用了Login
方法,作为登录表单请求的方法。当用户在网页上尝试登录时,请求的表单就会发送至后端,后端就收请求的类是Login
,Login
是HttpServlet
的子类,通过改写HttpServlet
中的doGet
方法,相应前端请求,根据不同的响应结果实现不同的页面跳转。
package com.servlet.login;import java.io.*;import javax.servlet.http.HttpServlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.mysql.sqlExecute;//需要说明网络服务器名称
//Account.jsp发送请求到名为Login的网络服务器
@WebServlet("/Login")
public class Login extends HttpServlet {public Login(){super();}@Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response){try{response.getWriter().append("Served at: ").append(request.getContextPath());PrintWriter pw = response.getWriter();pw.append("sss");String username = request.getParameter("username");String password = request.getParameter("password");System.out.println("账号是:" + username);System.out.println("密码是:" + password);sqlExecute se = new sqlExecute();if(password.equals(se.queryPassword(username))){System.out.println("登陆成功");//成功后跳转response.sendRedirect("index.jsp");}else{System.out.println("登陆失败");//失败后跳转response.sendRedirect("views/Account.jsp");}}catch(IOException e){e.printStackTrace();}}
}
2.4 Register
在Register.jsp
中调用了Register
方法,具体步骤基本和Login
一致,但是执行的数据库操作不同
Login
执行的是查询操作;Register
执行的是插入操作
package com.servlet.register;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;import com.mysql.sqlExecute;//指定网络服务器名称
//Register.jsp中的请求发送到的是名为Register的服务器
@WebServlet("/Register")
public class Register extends HttpServlet {public Register(){super();}@Overridepublic void doGet(HttpServletRequest request,HttpServletResponse response){try{response.getWriter().append("Served at: ").append(request.getContextPath());PrintWriter pw = response.getWriter();pw.append("sss");String nation = request.getParameter("region");String telephone = request.getParameter("phone");System.out.println("国家为:"+nation);System.out.println("电话为:"+telephone);sqlExecute se = new sqlExecute();se.insert(nation,telephone);response.sendRedirect("index.jsp");}catch(IOException e){e.printStackTrace();}}
}
3 数据库方面
3.1 整体功能
在servlet配置完成后,前端就可以发送数据请求了,其后就是后端接受同时响应请求。在接受请求时,根据不同的操作对数据库进行不同的操作,例如登录就是查询数据库相关表单,注册就是在数据库相应表单中插入某些数据。在之后的代码优化中,用户修改个人信息即为数据库的update功能。
3.2 sqlDao
这一层是在数据库上的操作,通过sqlExecute
类的获取的Connection
对象conn
连接数据库,并在数据库上进行一系列操作。在这一层,包括查询和更新两个主函数,另外就是查询列名辅助函数,辅助sqlExecute
类中查询指定密码的方法实现。
package com.mysql;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import java.sql.ResultSetMetaData;public class sqlDao {private Connection conn;/*** 构造函数* */public sqlDao(Connection n){this.conn = n;}/*** 更新操作* */public void update(String sql){System.out.println(sql+"已执行");try{Statement stmt = conn.createStatement();stmt.executeUpdate(sql);stmt.close();}catch(SQLException e){e.printStackTrace();}catch(NullPointerException e){System.out.println("请连接数据库");}}/*** 获取列名* */public Vector<String> selectTitle(String sql){Vector<String> temp = new Vector<>();try{Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql);//获取列数ResultSetMetaData rsMd = rs.getMetaData();int columnCount = rsMd.getColumnCount();System.out.println(rs.next());//获取列名for(int i = 0; i < columnCount; i++){temp.add(rsMd.getColumnName(i+1));}rs.close();stmt.close();}catch(SQLException e){e.printStackTrace();}catch(NullPointerException e){System.out.println("请连接数据库");}return temp;}/*** 查询操作* */public Vector<Vector<String>> select(String sql){Vector<Vector<String>> r = new Vector<>();System.out.println(sql + "已执行");try{Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql);int columnCount = rs.getMetaData().getColumnCount();while(rs.next()){Vector<String> temp = new Vector<>();r.add(selectTitle(sql));for(int i = 0; i < columnCount; i++){temp.add(rs.getString(i+1));}r.add(temp);}}catch(SQLException e){e.printStackTrace();}catch(NullPointerException e){System.out.println("请连接数据库");}return r;}
}
3.3 sqlExecute
在这一层,根据名字也能判断出来这是一个与sql
语句相关的类,此类用来执行不同的sql
语句,不同的sql
语句对应sqlDao
里面的各种方法,sqlExecute
类中将引用sqlDao
的方法。另外就是,sqlExecute
还控制数据库的连接。
package com.mysql;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
import java.util.Vector;public class sqlExecute {private static String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true";private static String driver = "com.mysql.cj.jdbc.Driver";private static String user;private static String password;private static Connection conn;private int max_id;//构造函数public sqlExecute(){this.user = "root";this.password = "159357";connListener cl = new connListener();//在构造sqlExecute对象时连接数据库cl.connect();}//连接监听private class connListener{public void connect(){try{Class.forName(driver);conn = DriverManager.getConnection(url,user,password);if(null!=conn){System.out.println("成功连接数据库");}}catch(ClassNotFoundException | SQLException e){e.getStackTrace();}}}//查询指定用户的密码public String queryPassword(String username){String sql = "select * from users where username = '" + username +"';";sqlDao sd = new sqlDao(conn);Vector<Vector<String>> temp = sd.select(sql);int i,j,k;//暂时不考虑重名问题if(temp.get(1).contains(username)) {int cow = temp.size();int col = temp.get(0).size();//确定用户名所在列for(k = 0;k < col;k++){if(temp.get(0).get(k).equals("username")){break;}}//确定密码所在列for(j = 0;j < col;j++){if(temp.get(0).get(j).equals("password")){break;}}//确定用户名所在行for(i = 0;i<cow;i++){if(temp.get(i).get(k).equals(username)){break;}}return temp.get(i).get(j);}else{System.out.println("此用户不存在");return null;}}//根据注册页面1进行数据库插入操作public void insert(String nation,String phone){max_id=findMax()+1;String sql = "insert into users values(" + max_id + ",'"+nation+"',null,null,'"+phone+"',null);";sqlDao sd = new sqlDao(conn);sd.update(sql);}//由于userid为主键不可为空,故而插入时需要指定最大idpublic int findMax(){String sql = "select max(userid) as max_id from users;";sqlDao sd = new sqlDao(conn);Vector<Vector<String>> r = sd.select(sql);int mid = Integer.parseInt(r.get(1).get(0));return mid;}
}
4 项目整体结构(树状图)
ps:由于图片比较多,目录会显得比较长,我把相关的图片目录都删除了,只要是
C:\LIXIANLEI\THEFOURTHWEEK\XIAOMI商城
│ Xiaomi商城.iml
│
├─.idea
│ │ .gitignore
│ │ misc.xml
│ │ modules.xml
│ │ uiDesigner.xml
│ │ vcs.xml
│ │ workspace.xml
│ │
│ ├─artifacts
│ │ Xiaomi_war_exploded.xml
│ │
│ └─libraries
│ mysql_connector_java_8_0_21.xml
│
├─doc
│ │ tree.txt
│ │ tree1.txt
│ │ 前后端交互.md
│ │
│ └─img
│ Debug配置-1.png
│ Debug配置-2.png
│ Debug配置-3.png
│ 项目配置-1.png
│ 项目配置-2.png
│ 项目配置-3.png
│
├─lib
│ mysql-connector-java-8.0.21.jar
│
├─out
│ ├─artifacts
│ │ └─Xiaomi_war_exploded
│ │ │ index.jsp
│ │ │
│ │ ├─.idea
│ │ │ ├─artifacts
│ │ │ └─libraries
│ │ ├─css
│ │ │ Account.css
│ │ │ base.css
│ │ │ index.css
│ │ │ load.css
│ │ │ register.css
│ │ │ reset.css
│ │ │ style.css
│ │ │
│ │ ├─img
│ │ │
│ │ ├─js
│ │ ├─lib
│ │ ├─META-INF
│ │ │ context.xml
│ │ │
│ │ ├─src
│ │ │ └─com
│ │ │ └─servlet
│ │ │ └─login
│ │ ├─views
│ │ │ Account.jsp
│ │ │ Register.jsp
│ │ │
│ │ ├─web
│ │ │ ├─css
│ │ │ ├─img
│ │ │ │ └─Router
│ │ │ ├─js
│ │ │ ├─META-INF
│ │ │ ├─views
│ │ │ └─WEB-INF
│ │ └─WEB-INF
│ │ │ web.xml
│ │ │
│ │ ├─classes
│ │ │ │ Account.jsp
│ │ │ │ Register.jsp
│ │ │ │
│ │ │ └─com
│ │ │ ├─mysql
│ │ │ │ sqlDao.class
│ │ │ │ sqlExecute$1.class
│ │ │ │ sqlExecute$connListener.class
│ │ │ │ sqlExecute.class
│ │ │ │
│ │ │ └─servlet
│ │ │ ├─login
│ │ │ │ Login.class
│ │ │ │
│ │ │ └─register
│ │ │ Register.class
│ │ │
│ │ └─lib
│ │ mysql-connector-java-8.0.21.jar
│ │
│ └─production
│ └─Xiaomi商城
│ │ Account.jsp
│ │ Register.jsp
│ │
│ └─com
│ ├─mysql
│ │ sqlDao.class
│ │ sqlExecute$1.class
│ │ sqlExecute$connListener.class
│ │ sqlExecute.class
│ │
│ └─servlet
│ ├─login
│ │ Login.class
│ │
│ └─register
│ Register.class
│
├─src
│ └─com
│ ├─mysql
│ │ sqlDao.java
│ │ sqlExecute.java
│ │
│ └─servlet
│ ├─login
│ │ Login.java
│ │
│ └─register
│ Register.java
│
└─web│ index.jsp│ ├─css│ Account.css│ base.css│ index.css│ load.css│ register.css│ reset.css│ style.css│ ├─img│ ├─js├─META-INF│ context.xml│ ├─views│ Account.jsp│ Register.jsp│ └─WEB-INFweb.xml
5 常见问题汇总
下面的问题会出现是笔者一点点磨出来的,正所谓“久病成医”,但是我也没有生过全部的病,如果下面没有你想要的答案,别怪我哟,可以私信我咱们慢慢讨论(好吧,王婆卖瓜了一次)
5.1 404问题
5.1.1 jsp文件存放位置错误
我也是刚接触前后端交互方面编程,但是404和405我已经遇见无数次了。一般有很多种情况,例如找不到相关的资源。首先就是你要确定你新建的jsp
文件不能存放在WEB-INF
文件夹下,就是不能和web.xml
文件放在同一个文件夹。放在web
根目录下或者新建一个目录都可以。网上有相应的博客,这里就不贴链接了。
5.1.2 修改jsp文件后没有修改路径
另外就是在修改过jsp
文件位置后,并没有在其余与此jap
文件相关或者存在跳转的文件中的地址,例如,我的Account.jsp
文件中有两个跳转,但这时我将index.jsp
文件移动到了views
文件夹中,但是没有修改相应的路径,例如我的web.xml文件中欢迎界面就是index.jsp,但是根目录下的index.jsp
已经被我移走了,这样再就运行就会提示404
错误,找不到index.jsp
资源
5.1.3 相对路径问题
如果这两个地方都没有问题,那就是有一个小细节没有注意到。因为对于我们的项目而言。在运行时,前端的根目录就是web
文件夹,故而在书写相对路径的时候需要多留几个心眼。
5.2 点击登录无反应
5.2.1 jsp文件中问题
首先咱们先理清一下思路,首先我们需要在jsp
文件中创建表单,将此表单通过一定的方法发送到指定的网络服务器上,等待相关的网络服务器响应请求。既然是这样,这里面就有几个容易犯错的点。
- 单词拼写错误(不要笑,不要把form拼写成from,这两个词很像的,我有次因为这个调试了一下午,哭死在学习英语和实现前后端交互的路上)
- 登录按钮那一块类型一定不要写成"button",一定要写成"submit",即
type="submit"
- 然后就是看有没有对应的规则限制你的输入,如果有的话,查看你的输入是否符合规则,不符合规则并且没有任何错误提示在代码中说明的话,点击登录也是没有反应的
- 再一个就是检查from表单对应的服务器是否正确,是action属性,例如实现登录功能时,
action="Login"
(按照我的代码哈) - 最后一个就是选择的方法,如果在你的后端代码改写的是doPost方法,那么
method="post"
;如果改写的是doGet方法,那么method="get"
,这也是form表单的属性之一
5.2.2 后端代码问题
。因为对于我们的项目而言。在运行时,前端的根目录就是web
文件夹,故而在书写相对路径的时候需要多留几个心眼。
jsp实现前后端交互相关推荐
- html 和jsp 引入jquery_不用jsp怎么实现前后端交互?给萌新后端的ajax教程(1)
众所周知jsp是已经入土的技术,虽然仍有不少老项目在用,但已经不值得花时间学习了,当然了解一下也是可以的.如果你是一位萌新后端,不想了解jsp,或者想做一个前后端分离的项目,想在纯html网页上实现前 ...
- java web前后台交互_前后端交互(javaweb)
前段后台交互的学习(Java web) 标签 : 前后端交互 Javaweb 下面介绍了一些关于交互的细节: 请求数据 前端提供请求数据. 在开发中,后台在查询数据库时,需要借助查询条件才能查询到前端 ...
- Spring+SpringMVC+MyBatis明日方舟版人员信息管理系统前端页面代码前后端交互+SSM框架 管理员登录 游客登录 普通用户登录 人员的增删改查 信息更新 图片上传 分页查询)
Spring+SpringMVC+MyBatis明日方舟版人员信息管理系统前端页面代码(前后端交互+SSM框架 管理员登录 游客登录 普通用户登录 人员的增删改查 信息更新 图片上传 分页查询 修改密 ...
- 使用Ajax进行前后端交互(一)
实现我们需要做好准备工作 本章涉及到的架包有: jackson-annotations-2.9.8.jar jackson-core-2.9.8.jar jackson-databind-2.9.8. ...
- JAVA中的前后端交互
JDBC 什么是JDBC java数据库连接(Java Database Connectivity) 有什么用 利用 Java 代码, 可以操作数据库. 怎么用 注册驱动 获取数据库连接 创建 Sta ...
- java中常用前后端交互框架,整合Spring-SpringMVC-MyBatis实现简单前后端交互
整合Spring-SpringMVC-MyBatis实现简单前后端交互 (1)环境要求 IDEA MySQL Tomcat Maven (2)数据库环境 id name pwd 1 Hunter 12 ...
- java jqgrid_jqgrid 前后端交互实例
原标题:jqgrid 前后端交互实例 首先,jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信. 一.jqGrid特性 基于j ...
- 前后端交互,网络请求
这边文章主要根据我自己的前端开发工作经验,东拼西凑出来的一点理解,希望能够对大家有点帮助,如果有误导或者错误的地方还请帮助指正,感谢!!! 前后端交互我理解主要分为三个主要的部分: 1.客户端 2.服 ...
- echarts前后端交互数据_SpringBoot2.0实战(26)整合SpringSecurity前后端分离JSON交互...
在前端的文章中,我们实现了使用 SpringSecurity 实现登录鉴权,并使用数据库存储用户信息,实现登录鉴权 SpringBoot2.0实战(24)整合SpringSecurity之最简登录方法 ...
最新文章
- Elasticsearch 查询数据的工作原理是什么?
- SVM支持向量机(上)
- ES6新特性_Promise介绍与基本使用---JavaScript_ECMAScript_ES6-ES11新特性工作笔记024
- C#反射取得方法、属性、变量
- Beosin成都链安安全舆情系统上线 公众号更新全新体验!
- php输出cad文件,AutoCAD 二次开发 输出为WMF 或BMP文件
- linux环境搭建redis集群,Linux下搭建Redis分布式集群(详细图解演示)
- STM32F4 ETH-Lwip以太网通信
- C++飞机票订票系统
- Java 基于WEB的农产品销售管理系统源码+数据库+论文文档+项目辅导视频
- Robomaster视觉组成长之路
- 教你一招轻松压缩MP4视频到最小
- Crontab中的除号(slash)到底怎么用?(转载)
- 投影仪软件哪个好用?装上一起看TV,解锁追剧新体验
- 如何正确使用HTTP代理?
- 安装Nvidia驱动run文件
- url 转pdf工具
- 前端环境安装遇到的问题
- 【车】铅酸电池和锂电池、鼓刹和碟刹
- 解决安装vmware-tools出现报错unable to copy the source file./installer/service.sh to the destination file