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是源码文件夹,此文件夹需要创建的是classinterfaceenum,但是倘若在没有标记的情况下,编辑器并不会知道这是什么用途的文件夹。就可能会发生无法进行新建java类的问题。按照下图标记

src标记为sourcesout标记为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方法,作为登录表单请求的方法。当用户在网页上尝试登录时,请求的表单就会发送至后端,后端就收请求的类是LoginLoginHttpServlet的子类,通过改写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实现前后端交互相关推荐

  1. html 和jsp 引入jquery_不用jsp怎么实现前后端交互?给萌新后端的ajax教程(1)

    众所周知jsp是已经入土的技术,虽然仍有不少老项目在用,但已经不值得花时间学习了,当然了解一下也是可以的.如果你是一位萌新后端,不想了解jsp,或者想做一个前后端分离的项目,想在纯html网页上实现前 ...

  2. java web前后台交互_前后端交互(javaweb)

    前段后台交互的学习(Java web) 标签 : 前后端交互 Javaweb 下面介绍了一些关于交互的细节: 请求数据 前端提供请求数据. 在开发中,后台在查询数据库时,需要借助查询条件才能查询到前端 ...

  3. Spring+SpringMVC+MyBatis明日方舟版人员信息管理系统前端页面代码前后端交互+SSM框架 管理员登录 游客登录 普通用户登录 人员的增删改查 信息更新 图片上传 分页查询)

    Spring+SpringMVC+MyBatis明日方舟版人员信息管理系统前端页面代码(前后端交互+SSM框架 管理员登录 游客登录 普通用户登录 人员的增删改查 信息更新 图片上传 分页查询 修改密 ...

  4. 使用Ajax进行前后端交互(一)

    实现我们需要做好准备工作 本章涉及到的架包有: jackson-annotations-2.9.8.jar jackson-core-2.9.8.jar jackson-databind-2.9.8. ...

  5. JAVA中的前后端交互

    JDBC 什么是JDBC java数据库连接(Java Database Connectivity) 有什么用 利用 Java 代码, 可以操作数据库. 怎么用 注册驱动 获取数据库连接 创建 Sta ...

  6. java中常用前后端交互框架,整合Spring-SpringMVC-MyBatis实现简单前后端交互

    整合Spring-SpringMVC-MyBatis实现简单前后端交互 (1)环境要求 IDEA MySQL Tomcat Maven (2)数据库环境 id name pwd 1 Hunter 12 ...

  7. java jqgrid_jqgrid 前后端交互实例

    原标题:jqgrid 前后端交互实例 首先,jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信. 一.jqGrid特性 基于j ...

  8. 前后端交互,网络请求

    这边文章主要根据我自己的前端开发工作经验,东拼西凑出来的一点理解,希望能够对大家有点帮助,如果有误导或者错误的地方还请帮助指正,感谢!!! 前后端交互我理解主要分为三个主要的部分: 1.客户端 2.服 ...

  9. echarts前后端交互数据_SpringBoot2.0实战(26)整合SpringSecurity前后端分离JSON交互...

    在前端的文章中,我们实现了使用 SpringSecurity 实现登录鉴权,并使用数据库存储用户信息,实现登录鉴权 SpringBoot2.0实战(24)整合SpringSecurity之最简登录方法 ...

最新文章

  1. Elasticsearch 查询数据的工作原理是什么?
  2. SVM支持向量机(上)
  3. ES6新特性_Promise介绍与基本使用---JavaScript_ECMAScript_ES6-ES11新特性工作笔记024
  4. C#反射取得方法、属性、变量
  5. Beosin成都链安安全舆情系统上线 公众号更新全新体验!
  6. php输出cad文件,AutoCAD 二次开发 输出为WMF 或BMP文件
  7. linux环境搭建redis集群,Linux下搭建Redis分布式集群(详细图解演示)
  8. STM32F4 ETH-Lwip以太网通信
  9. C++飞机票订票系统
  10. Java 基于WEB的农产品销售管理系统源码+数据库+论文文档+项目辅导视频
  11. Robomaster视觉组成长之路
  12. 教你一招轻松压缩MP4视频到最小
  13. Crontab中的除号(slash)到底怎么用?(转载)
  14. 投影仪软件哪个好用?装上一起看TV,解锁追剧新体验
  15. 如何正确使用HTTP代理?
  16. 安装Nvidia驱动run文件
  17. url 转pdf工具
  18. 前端环境安装遇到的问题
  19. 【车】铅酸电池和锂电池、鼓刹和碟刹
  20. 解决安装vmware-tools出现报错unable to copy the source file./installer/service.sh to the destination file

热门文章

  1. 电磁兼容(EMC):关于接地,你了解多少?
  2. sstream头文件
  3. 单例模式——懒汉式和饿汉式详解
  4. 给移动硬盘分区(一个给mac的时间机器使用,一个用于windows和mac系统之间使用)----记录一次mac系统 用磁盘工具抹掉移动硬盘进度条卡死问题
  5. 2008.5.19-5.21全国哀悼日
  6. 【Go】sql拼接库
  7. 怎样在外网登录访问CRM管理系统?
  8. 计算方法 - 二分法求近似根
  9. Java程序员春招三面蚂蚁金服,开源掌机玩java
  10. 解决报错:无法建立到笔记本服务器的连接。我们会继续尝试重连。请检查网络连接还有服务配置