JSP向Servlet传递数据以及与STM32、ESP8266通信过程

系列文章:
Servlet向JSP传递数据以及JSP页面DIV定时局部刷新
STM32 ESP8266和Java服务器透传模式下的双向通信
jsp向servlet传输数据
ESP8266的AP模式与STA模式简单测试

工作流程:
login.jsp->ValidateTest.java->ControlTest.jsp和SocketTest.java->Control.java->8266->STM32

以上文件中后缀名为.jsp的就是JSP文件,Control.javaValidateTest.java就是所谓的Servlet文件,SocketTest.java就是普通的Java Class文件。即只要是和JSP文件有数据传递关系的都得创建Servlet文件,而不是创建Class文件,当然了,你创建Class文件也行,只不过里面还是都得有Servlet文件所必须的doPost之类的方法。
Servlet是用来和JSP进行通信的文件,Servelt与JSP关系
工作流程文字描述:
第一步:进入登录页面login.jsp,输入账号和密码
第二步:进入账号密码验证程序ValidateTest.java,验证成功后进入第三步,验证失败返回第一步
第三步:先进入控制系统页面ControlTest.jsp,然后再进入创建服务器并等待客户端的连接请求SocketTest.java,若有客户端连接成功,则进入第四步,若一直没有客户端连接请求,则一直在这里等待客户端的连接,直至人为终止程序
第四步:点击控制按钮,向客户端发送数据
第五步:客户端即工作在透传模式下的ESP8266把收到的数据传递给STM32
第六步:STM32解析并处理数据
首先运行第一个登录页面:
login.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录</title>
<style>
        	body{margin: 0;
        		 padding: 0;
        		 font-family: sans-serif;
        		 background-image: url(img/login_background.png);
        		 background-size: cover;
        		}
        	.box{
        		position: absolute;
        		top: 50%;
        		left: 50%;
        		transform: translate(-50%,-50%);
        		width: 400px;
        		padding: 40px;
        		background: rgba(0,0,0,.8);
        		box-sizing: border-box;
        		box-shadow: 0 15px 25px rgba(0,0,0,.5);
        		border-radius: 10px;
        	}
        	.box h2{
        		margin: 0 0 30px;
        		padding: 0;
        		color: #fff;
        		text-align: center;
        	}
        	.box .inputBox{
        		position: relative;
        	}
        	.box .inputBox input{
        		width: 100%;
        		padding: 10px,0;
        		font-size: 16px;
        		color: #fff;
        		letter-spacing: 1px;
        		margin-bottom: 30px;
        		border: none;
        		border-bottom: 1px solid #fff;
        		outline: none;
        		background: transparent;
        	}
        	.box .inputBox label{
        		position: absolute;
        		top: 0;
        		left: 0;
        		padding: 10px,0;
        		font-size: 16px;
        		color: #fff;
        		letter-spacing: 1px;
        		pointer-events: none;
        		transition: .5s;
        	}
        	.box .inputBox input:focus ~ label,
        	.box .inputBox input:valid ~ label
        	{
        		top: -18px;
        		left: 0;
        		color: #03a9f4;
        		font-size: 12px;
        		
        	}
        	.box input[type="submit"]{
        		background: transparent;
        		border: none;
        		outline: none;
        		color: #fff;
        		background: #03a9f4;
        		padding: 10px 20px;
        		cursor: pointer;
        		border-radius: 5px;
        		margin-left: 120px;
        	}
        </style>
</head>
<body>
<div class="box">
    		<h2>Login</h2>
    		<!-- 下面这句话很重要,由它决定跳转到哪个文件执行,并且说明了使用post方法,
    		所以不能只用点击事件来触发,点击事件没有说明使用的是post方法 ,
    		另外注意当使用get方法时,账号密码会暴露在地址栏中 -->
    		<form action="ValidateTest" method="post">
    			<div class="inputBox">
    				<input type="text" name="Username" required="" />
    				<label>Username</label>
    			</div>
    			<div class="inputBox">
    				<input type="password" name="password" required="" />
    				<label>password</label>
    			</div>
    			<!-- 注意提交按钮不用设置成点击事件,直接使用form的action属性即可设置跳转到哪个页面 -->
    			<input type="submit" name="" value="submit" />
    		</form>
    	</div>
</body>
<!-- <script>
function login(){
	location.replace("LoginServlet");
}
</script> -->

</html>

运行结果:
在这里插入图片描述
输入账号密码之后,数据会通过<form action="ValidateTest" method="post">这句话来进行相应的跳转,action后面的参数就是指的是要把用户输入的账号和密码传输到哪一个程序中执行,method后面的参数是指采用哪种传输方式,传输方式有post和get。
ValidateTest.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LoginServlet
 */
//@WebServlet是采用注入的方式表示这是一个Servlet类,采用此方法比较方便,因为此方法不用再去配置web.xml文件
@WebServlet("/ValidateTest")
public class ValidateTest extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ValidateTest() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    //doGet响应get请求,doPost响应post请求,为了保证不管在login.jsp中选择post方法还是get方法,在这里都能有所回应,所以
    //这里只在doPost中写相应的代码,而在doGet中直接调用doPost函数即可
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		doPost(request, response);
//		response.getWriter().append(info);	
	}

	private void alert(String string) {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//从login页面中获取用户名和密码
		String name = request.getParameter("Username");
		String password = request.getParameter("password");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		if(name == null || password == null || name.equals("") || password.equals("")) {
			response.getWriter().append("账号/密码不能为空");
			return;
		}else {
			if(name.equals("asddssdf") && password.equals("sdjfhjhffjshbfgk")) {
				RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/ControlTest.jsp");//这句话的意思是当验证账号密码都正确后,要继续跳转到哪一个页面,这里是跳转到ControlTest页面
				dispatcher.forward(request, response);
				SocketTest.getSocket();//这句话是用来创建一个服务器等待客户端(连接在STM32上的8266)的连接,连接成功后生成一个Socket用来双方的通信。注意创建Socket以及等待客户端连接一定要在页面跳转到控制页面之后进行,因为等待客户端连接是一个阻塞函数,程序会一直死在那里等待客户端的连接
			}else {
				//response.sendRedirect("login.jsp");//直接重定向到登录页面,无任何提示信息
				
				//有登录失败的提示信息,但是跳到了一个新页面,点击确定之后重新回到登录页面回到指定页面
				PrintWriter out = response.getWriter();
				out.print("<script>alert('账号/密码错误,请重新登录!');window.location.href='login.jsp'</script>");
			}
		}
	}
}

ControlTest.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>控制系统</title>
</head>
<body>
<h2>这里是控制系统</h2>
<button onclick="power()">控制按钮</button>
</body>
<script src="js/jquery-3.2.1.min.js"></script>
		<script type="application/javascript"></script>
    	
 		<script type="text/javascript">
 		var switch_flag = "0";
 		
 		function power(){
 		 	if(switch_flag == "0"){
 		 		switch_flag = "1";
 		 		//使用ajax向servlet传递数据
 		 		$.ajax({  
						type:"post",  
			            url:"Control",  
			            data:{
			               'switch_flag':"1",
			            },
			       	    dataType:"json"    //数据类型为json格式
			       });
 		 	}
 		 	else if(switch_flag == "1"){
				
 		 		switch_flag = "0";
				$.ajax({  
					type:"post",  
		            url:"Control",  
		            data:{
		               'switch_flag':"0",
		            },
		       	    dataType:"json"    //数据类型为json格式
		       });
 		 	}
 		}
 		</script>
</html>

关于json技术请点击。这个控制按钮的作用就是每次点击,他就会使switch_flag改变一次值,值在0和1之间来回改变,并且通过json技术把switch_flag的值传递给参数url所指定的程序中,即url:"Control",。然后在Control.java文件中再把相应的数据通过Socket发送给客户端8266.
Control.java

package servlet;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

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 servlet.SocketDemo;


/**
 * Servlet implementation class LoginServlet
 */
//@WebServlet是采用注入的方式表示这是一个Servlet类,采用此方法比较方便,因为此方法不用再去配置web.xml文件
@WebServlet("/Control")
public class Control extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Socket socket;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Control() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
    //doGet响应get请求,doPost响应post请求,为了保证不管在login.jsp中选择post方法还是get方法,在这里都能有所回应,所以
    //这里只在doPost中写相应的代码,而在doGet中直接调用doPost函数即可
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {	
		doPost(request, response);
//		response.getWriter().append(info);	
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String switch_flag = request.getParameter("switch_flag");

		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		System.out.println("收到ajax请求");
		System.out.println("总电源:"+switch_flag);

		Socket client = SocketTest.getClient();
//			DataInputStream input = new DataInputStream(socket.getInputStream()); 
		DataOutputStream out = new DataOutputStream(client.getOutputStream());  
			
//		System.out.print("请向客户端发送数据:\n");  
		String s = switch_flag;
//			String s = new BufferedReader(new InputStreamReader(System.in)).readLine();  
        out.writeUTF(s);  //注意必须是UTF格式
        System.out.print("向客户端发送的数据为:"+s+"\n");
	}
}

SocketTest.java

package servlet;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTest {
	private static Socket Client = null;
	private static ServerSocket serverSocket = null;
	private static final int SERVER_PORT = 12444;

	private static String resultFromClient = "";

	//以下是一个静态方法(static 表示这是一个静态方法),静态方法的作用就是可以在不进行创建对象(即不进行实例化)的情况下调用此方法
	//由于本方法需要返回一个值,故不能用void了,由于返回值类型是一个Socket,故应该在static的后面加上返回值的类型(就相当于int cha等等)Socket
	public static  Socket getSocket() throws IOException {
		try {
			serverSocket = new ServerSocket(SERVER_PORT);
			System.out.print("服务器已建立\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.print("等待客户端的连接...\n");
		Client = serverSocket.accept();
		System.out.println("Socket client" + Client.getRemoteSocketAddress() + "成功连接");
		return Client;
	}
	public static Socket getClient() {
		return Client;
	}
}

运行结果:
在这里插入图片描述
每点击一次控制按钮,就会向客户端发送一次数据
在这里插入图片描述
以上实验有一个问题,就是在输入完正确的账号密码并且点击提交之后,按逻辑来说应该是先显示控制系统的页面即ControlTest.jsp,然后再调用SocketTest函数去创建ServerSocket并且一直等待客户端的连接请求,也就是说我们看到的应该是在控制系统的页面去等待客户端的连接,我之前写好的程序也是这样的,但是我又写了这个博客实验的时候,它总是停留在登录页面一直等待客户端的连接,我也不知道咋回事。

下载客户端(STM32端)代码(不完整,完整的请下载后面的)
至此就完成了服务器向客户端发送数据
客户端向服务器发送数据并局部实时刷新到JSP页面进行显示请点击
STM32端较完整代码下载:

链接:https://pan.baidu.com/s/1reuUT-HItQsyJ7YcqcBdfQ 
提取码:4r5b
发布了103 篇原创文章 · 获赞 319 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/qq_36554582/article/details/103904560