微信小程序 + Java + Mysql(登录 Demo)

目录

一、开发前准备

二、设计登录页面(小程序)

三、创建 Maven 项目

四、创建数据库与数据表

五、后台代码(Java Servlet)

六、运行

七、总结 建议


一、开发前准备

 1、注册一个微信开发者账号:https://open.weixin.qq.com (略)

 2、开发工具:idea、Mysql、微信开发者工具

 3、应用技术:Java(后台)、小程序(前端)、Maven、Mysql、跨域

 4、本次案例以功能为主,页面效果能用就行(不注重页面设计)

注意:创建小程序的项目和Javaweb项目我都略过了详细的创建步骤(可能刚开始的小白会不懂怎么创建,我刚开始接触小程序的时候也是一样,创建项目都弄了好久),如果有需要的话,后面我会做一个 文章详细介绍。

二、设计登录页面(小程序)

1、login.wxml(设计登录页面的文件)



  

  
    
      
        
          
            
              
            
            
              
            
          

          
            
              
            
            
              
            
          
        
      
    

    

  

页面效果: 

微信小程序 + Java + Mysql(登录 Demo)_第1张图片

 2、login.js(完成登录的逻辑代码)

  这里的代码基本上每一行我都注释了,每一行代码的意思都写的很清楚了,方便大家的阅读 

  (在我们开发编程的过程中,一定要养成写注释的习惯,这样会方便我们之后的阅读,出现 BUG了也能更快的找到问题所在)

// pages/login/login.js

Page({

  /**
   * 页面的初始数据
   */

  /**
   * 页面的初始数据
   */
  data: {
    account:null,
    password:null,
    
  },
/**
 * 从文本框中得到输入的值
 * 获取账号的方法
 */
  userAccount:function(event){
    // 获取文本框输出的账号
    var userAccount = event.detail.value;
    this.setData({
      // 把获取到的账号赋值给 account 变量
      account:userAccount,
    })
    console.log(this.data.account)
  },

  // 获取密码的方法
  userPassword:function(event){
    // 获取文本框输出的密码
    var userPassword = event.detail.value;
    this.setData({
      // 把获取的密码赋值给 password 变量
      password:userPassword,
    })
    console.log(this.data.password)
  },
  

  // 点击登录按钮要做的事情
  loginTap:function(){
    wx.request({
      // 接口地址:登录的 servlet 地址
      url: 'http://localhost:8080/项目名/XXX.do', 
      // 向后端传递的数据
      data: {
        // 账号
        x:this.data.account,
        // 密码
        y:this.data.password,
      },
      // 以HTTP协议传HTML资料到浏览器前所送出的字串
      header: {
        //'content-type': 'application/json' //默认值
        'Content-Type': 'application/x-www-form-urlencoded'
      },

      // 以什么方法传递(常用的是:POST、GET)
      method: 'POST',

      // 成功之后要做的操作
      success(res) {
        // 这里输出了登录的用户名
        console.log(res.data.user_name)
        console.log('----successed----')

        // 判断是否存在数据,成功就跳到下一个页面
        if(res){
          /**
           * 1、wx.navigateTo
              保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。
              2、wx.redirectTo
              关闭当前页面,跳转到应用内的某个页面。
              3、wx.switchTab
              跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
              4、wx.navigateBack
              关闭当前页面,返回上一页面或多级页面。可通过 [getCurrentPages()] 获取当前的页面栈,决定需要返回几层。
              5、wx.reLaunch
              关闭所有页面,打开到应用内的某个页面。
           */
          wx.redirectTo({
            // 跳到成功页面
            url: '/pages/HomePage/homePage',
          })
        }
      },
      // 失败
      fail(res){
          // showModal:模态对话框
          wx.showModal({
            title:'提示',
            content:'登录失败,账号或密码错误',
            success(req){
              if(res.confirm){
                console.log("用户点击了确定",res);
              } else if(res.cancel){
                console.log("用户点击了取消");
              }
            }
          })
        console.log('----fail----')
      }
    })

  },

  // 点击了注册按钮
  rigestTap:function(){
    wx.showModal({
      title:'提示',
      content:'这是注册功能',
      success(res){
        if(res.confirm){
          wx.redirectTo({
            // 跳到注册页面
            url: '/pages/register/reg',
          })
        
        } else{
          console.log("点击了取消按钮");
        }
      }
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

三、创建 Maven 项目

  为什么要选择使用 Maven 呢? 因为我们开发需要使用很多的 jar 包,每需要一个就需要去下载一个,还要在项目配置中添加进去,操作非常繁琐,所以我们使用 Maven 来对我们的项目依赖我们需要的 jar 包,只需要到网上复制到 pom.xml 文件中就可以使用该 jar 包的 API 方法。

1、首先我们要创建一个Maven项目,这里我选择的是 Java ,但是我们需要的是web项目,后面我在项目结构中创建 web 项目

微信小程序 + Java + Mysql(登录 Demo)_第2张图片

2、把我们的项目创建为 web 项目 

步骤:点击我们软件的设置按钮  ----- Project Structure

微信小程序 + Java + Mysql(登录 Demo)_第3张图片

 

3、配置pom.xml文件

      下载依赖的网址:Maven Repository: Search/Browse/Explore (mvnrepository.com)

注意:一定要记得把我们的打包方式设置为 war 包,因为我们这次的项目为 web项目

  1、junit依赖:

        用途:

                1、进行单元测试,测试一个方法或者类是否能够正常运行

                       略.......

2、servlet依赖:

        用途:

                1、允许程序员注册一个类,在 Tomcat 收到的某个特定的 HTTP 请求的时候,执行这个类中的一些代码
                2、帮助程序员解析 HTTP 请求,把 HTTP 请求从一个字符串解析成一个 HttpRequest 对象
                3、帮助程序员构造 HTTP 响应,程序员只要给指定的 HttpResponse 对象填写一些属性字段,Servlet 就会自动的按照 HTTP 协议的方式构造出一个 HTTP 响应字符串,并通过 Socket 编写返回给客户端

3、MySQL依赖:

        用途:

                1、MySQL依赖是用于Java程序中连接和操作MySQL数据库的工具包

4、lombok依赖:

        用途:为我们的实体类省去重复的代码

                1、@Data 不需要写getter setter 

                2、@NoArgsConstructor 无参构造方法

            3、@AllArgsConstructor 有参数构造

"1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    
    <groupId>org.examplegroupId>
    <artifactId>untitled1artifactId>
    <version>1.0-SNAPSHOTversion>
    
    <packaging>warpackaging>

    <properties>
        <maven.compiler.source>11maven.compiler.source>
        <maven.compiler.target>11maven.compiler.target>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    properties>

    <dependencies>
        
        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>4.0.1version>
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.13.2version>
            <scope>testscope>
        dependency>

        
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.33version>
        dependency>

     

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.26version>
            <scope>providedscope>
        dependency>




    dependencies>




project>

四、创建数据库与数据表

-- 创建数据库
create database psm;

-- 使用数据库
use pms;


-- 创建数据表:userInfo
-- if not exists userInfo:判断userInfo表是否存在,不存在则创建
create table if not exists userInfo(
UserId int  primary key auto_increment,    -- 用户ID
userName varchar(20) ,                     -- 账号
userPwd varchar(32),                       -- 密码(我们要使用MD5加密,加密后密码长度为32位)
picture varchar(200)                       -- 头像
);

select * from userInfo;

五、后台代码(Java Servlet)

1、创建用户实体类

      是不是觉得我们的实体类少了很多代码,没错,这就是 Lombok 帮我们省去了

package entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Date 2023-04-25
 * @Author qiu
 */
@Data // 生成get\set
@NoArgsConstructor // 无参构造方法
@AllArgsConstructor // 有参构造方法
public class UserInfo {

    /**
     * 账号
     */
    String userName;

    /**
     * 密码
     */
    String userPwd;

    /**
     * 头像
     */
    String picture;


}

 

2、SqlRunner执行器(增、删、改、查操作的封装)

        对JDBC 进行封装,封装后我们就不再需要写那7个恶心的步骤了,省去了大量的重复代码。

package runner;



import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * SqlRunner 执行器 - 执行 增、删、改、查操作
 *  * 

* * 更新操作:insert、update、delete * * 查询操作:select * @Date 2023-04-25 * @Author qiu */ public class SqlRunner { private Connection connection; public SqlRunner(Connection connection) { this.connection = connection; } /** * 通用更新操作:执行 增、删、改的 SQL 语句 *

* insert into staffs(name,age,phone,sta_pos) * values (?,?,?,?) ; * * @param sql * @param params 不定长参数,本质上是一个数组 * @return */ public int executeUpdate(String sql, Object... params) { // 第一:获取连接对象 if (connection == null) { throw new RuntimeException("连接对象为null"); } // 第二:预编译SQL语句 PreparedStatement ps = null; try { ps = connection.prepareStatement(sql); // 第三:填充参数 setParameter(ps, params); // 第四:执行SQL语句 // 第五:返回结果 return ps.executeUpdate(); } catch (SQLException e) { throw new RuntimeException(e); } finally { // 第六:关闭相关的对象 close(ps); close(connection); } } /** * 填充 SQL 语句中的占位符数据 * * @param ps * @param params * @throws SQLException */ private static void setParameter(PreparedStatement ps, Object[] params) throws SQLException { for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } } /** * 返回实体对象的属性名称 * * @param clazz 实体对象的 Class 对象 * @param columnLabel select 后面的名称 * @param * @return */ private String getFieldName(Class clazz, String columnLabel) { // 1.获取实体对象所有的字段对象 Field[] fields = clazz.getDeclaredFields(); // 2.循环遍历字段数组 for (Field field : fields) { // 3.判断字段是否存在 Column 注解 boolean isExist = field.isAnnotationPresent(Column.class); // 4.如果存在,则获取注解的内容 if (isExist) { String columnName = field.getAnnotation(Column.class).value(); // 5.判断注解的内容是否与 select 后面的字段名称一样 if (columnName.equals(columnLabel)) { // 6.如果一样,则返回字段名称 - staPos return field.getName(); } } } // 7.如果不一样,则返回 select 后面的字段名称 return columnLabel; } /** * 通用查询操作 - 返回的List集合 * * @param clazz 实体对象的Class对象 * @param sql 要执行查询语句 * @param params 查询语句点位符数据 * @param T为具体的实体类型对象 * @return 返回的List集合 */ public List executeQuery(Class clazz, String sql, Object... params) { List list = new ArrayList<>(); // 第一:获取连接对象 if (connection == null) { throw new RuntimeException("连接对象为null"); } PreparedStatement ps = null; ResultSet rs = null; try { // 第二:预编译SQL语句 ps = connection.prepareStatement(sql); // 第三:填充参数 setParameter(ps, params); // 第四:执行SQL语句 - ResultSet rs = ps.executeQuery(); // 第五:获取结果集元数据对象 ResultSetMetaData metaData = rs.getMetaData(); // 第六:获取查询字段的数量 int count = metaData.getColumnCount(); // 第七:对结果集进行处理 - 遍历结果集,读取结果集中的数据,封装到List集合 while (rs.next()) { // 1.实例化实体对象 - 思考:实体对象是谁呢? - 在这里,谁都可以,我们要做一个通用的查询 - 通过 clazz 这个参数来确定要操作的具体实体对象的Class对象 T entity = clazz.getConstructor().newInstance(); // 2.读取结果集各列的数据 - 思考:有几列数据?是不确定的 - 解决? - ResultSetMetaData // Object xxx = rs.getObject("yyy") ; for (int i = 1; i <= count; i++) { // 2.1)获取查询字段名称 - 必须和实体对象的属性名称保持一致 - sta_pos、add_time String name = getFieldName(clazz, metaData.getColumnLabel(i)); // 2.2)根据名称获取实体对象的字段对象 Field declaredField = clazz.getDeclaredField(name); // 2.3)设置字段访问权限 declaredField.setAccessible(true); // 2.4)获取结果集中的数据 Object obj = rs.getObject(i); // 2.5)封装数据到实体对象中 - 思考:获取数据后,给对象的哪个属性初始化呢? - 反射 declaredField.set(entity, obj); } // 3.把实体对象添加到 List 集合中 list.add(entity); } } catch (SQLException e) { throw new RuntimeException(e); } catch (Exception e) { throw new RuntimeException(e); } finally { // 第八:关闭对象 close(rs); close(ps); close(connection); } return list; } /** * 查询数据,返回数据表的一行数据 * * @param clazz * @param sql * @param params * @param * @return */ public T query4Entity(Class clazz, String sql, Object... params) { T entity = null; // 第一:获取连接对象 if (connection == null) { throw new RuntimeException("连接对象为null"); } PreparedStatement ps = null; ResultSet rs = null; try { // 第二:预编译SQL语句 ps = connection.prepareStatement(sql); // 第三:填充参数 setParameter(ps, params); // 第四:执行SQL语句 - ResultSet rs = ps.executeQuery(); // 第五:获取结果集元数据对象 ResultSetMetaData metaData = rs.getMetaData(); // 第六:获取查询字段的数量 int count = metaData.getColumnCount(); // 第七:对结果集进行处理 - 遍历结果集,读取结果集中的数据,封装到List集合 if (rs.next()) { // 1.实例化实体对象 - 思考:实体对象是谁呢? - 在这里,谁都可以,我们要做一个通用的查询 - 通过 clazz 这个参数来确定要操作的具体实体对象的Class对象 entity = clazz.getConstructor().newInstance(); // 2.读取结果集各列的数据 - 思考:有几列数据?是不确定的 - 解决? - ResultSetMetaData // Object xxx = rs.getObject("yyy") ; for (int i = 1; i <= count; i++) { // 2.1)获取查询字段名称 - 必须和实体对象的属性名称保持一致 - sta_pos、add_time String name = getFieldName(clazz, metaData.getColumnLabel(i)); // 2.2)根据名称获取实体对象的字段对象 Field declaredField = clazz.getDeclaredField(name); // 2.3)设置字段访问权限 declaredField.setAccessible(true); // 2.4)获取结果集中的数据 Object obj = rs.getObject(i); // 2.5)封装数据到实体对象中 - 思考:获取数据后,给对象的哪个属性初始化呢? - 反射 declaredField.set(entity, obj); } } } catch (SQLException e) { throw new RuntimeException(e); } catch (Exception e) { throw new RuntimeException(e); } finally { // 第八:关闭对象 close(rs); close(ps); close(connection); } return entity; } /** * 关闭结果集对象 * * @param rs */ private void close(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } /** * 关闭语句对象 * * @param stmt */ private void close(Statement stmt) { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } /** * 关闭结果集对象 * * @param conn */ private void close(Connection conn) { if (conn != null) { try { conn.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }

3、接口类(定义登录和注册的方法)

package dao;

import entity.UserInfo;

/**
 * @Date 2023-04-25
 * @Author qiu
 */
public interface UserDao {

    /**
     *  登录的方法
     */
    UserInfo login(String account,String password);

    /**
     * 注册账号的方法
     *
     */
    int insert(String account,String pwd,String prictrue);


}

4、接口实现类(实现接口后,完成接口中的方法的功能)

package dao.daoImpl;

import dao.UserDao;
import entity.UserInfo;
import runner.SqlRunner;
import utils.DbUtil;

/**
 * @Date 2023-04-25
 * @Author qiu
 */
public class UserDaoImpl implements UserDao {

    // 实例化 SQL Runner 对象 - 提供了增、删、改、查
    SqlRunner sqlRunner = new SqlRunner(DbUtil.getConnection());

    /**
     * 实现登录的方法
     * @param account  账号
     * @param password  密码
     * @return
     */
    @Override
    public UserInfo login(String account, String password) {
        String sql = "select userName,userPwd from userInfo where userName = ? and userPwd = ?";
        return sqlRunner.query4Entity(UserInfo.class,sql,account,password);
    }

    /**
     * 用户注册的方法
     * @param account
     * @param pwd
     * @return
     */
    @Override
    public int insert(String account, String pwd,String prictrue) {
        String sql = "insert into userInfo(userName,userPwd,picture) values(?,?,?)";
        return sqlRunner.executeUpdate(sql,account,pwd,prictrue);
    }
}

5、连接数据库的工具类(DbUtil) 

package utils;

import java.sql.*;

/**
 * 连接数据库 & 释放相关对象
 *
 *
 *
 * @Date 2023-03-29
 * @Author qiu
 */
public class DbUtil {
    /**
     * 连接驱动程序
     */
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    /**
     * 连接URL
     */
    private static final String URL = "jdbc:mysql://localhost:3306/pms?useUnicode=true;characterEncoding=utf8;serverTimezone=Asia/Shanghai";
    /**
     * 帐号
     */
    private static final String USER = "账号";
    /**
     * 密码
     */
    private static final String PASS = "密码";


    static {
        /*
         * 加载驱动程序
         */
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            System.out.println("加载驱动程序失败...");
            e.printStackTrace();
        }
    }

    /**
     * 获取连接对象 -- Java程序 与 数据库之间的桥梁
     *
     * @return
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL, USER, PASS);
        } catch (SQLException e) {
            System.out.println("获取连接对象失败...");
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭相关的 JDBC 对象
     *
     * DriverManager:驱动管理对象,获取连接对象
     *
     * DriverManager.getConnection(URL, USER, PASS);
     *
     * ResultSet:结果集对象 用于接收查询数据时,返回的结果
     *
     * Statement:语句对象 用于执行SQL语句(PreparedStatement、CallableStatement)
     * 增、删、改:executeUpdate() 查询:executeQuery()
     *
     *
     * Connection:连接对象 建立JAVA程序与数据库之间的桥梁
     *
     * @param rst
     * @param stmt 父类对象可以接收子类对象 - 多态
     * @param conn
     */
    public static void close(ResultSet rst, Statement stmt, Connection conn) {
        if (rst != null) {
            try {
                rst.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // executeUpdate()、executeQuery() - 略
    public static void main(String[] args) {
        System.out.println(DbUtil.getConnection());
    }

}

6、登录的Servlet

package servlet;

import dao.daoImpl.UserDaoImpl;
import entity.UserInfo;

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;

/**
 *
 * 用户登录的 servlet
 *
 * @Date 2023-04-25
 * @Author qiu
 */
@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {



        // 获取小程序端传递过来的数据并打印输出
        String account = req.getParameter("x");
        String password = req.getParameter("y");

        // 判断 账号和密码不为空
        if (account != null && password != null) {

            // 实例化 UserDaoImp
            UserDaoImpl userDao = new UserDaoImpl();
            // 调用登录的方法进行登录
            UserInfo login = userDao.login(account, password);

            System.out.println("登陆成功");
            PrintWriter writer = resp.getWriter();
            writer.write("你好");
        } else {
            System.out.println("账号密码为空");
        }

    }


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

7、跨域过滤器

package filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Date 2023-04-26
 * @Author qiu
 */
@WebFilter("/servlet/*")
public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("跨域访问--初始化");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 向下转换类型
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        // 解决跨域问题

        // 允许所有的域名
        String origin = req.getHeader("origin");
        resp.setHeader("Access-Control-Allow-Origin", origin);

        // 允许发送cookies
        resp.setHeader("Access-Control-Allow-Credentials", "true");

        // 允许请求所有的方法
        resp.setHeader("Access-Control-Allow-Methods", "*");

        // 预检请求的最大超时(有效)时间为3600秒
        resp.setHeader("Access-Control-Max-Age", "3600");

        // 定义可以返回的头部信息字段
        resp.setHeader("Access-Control-Allow-Headers", "Authorization,Origin,X-Requested-With,Content-Type,Accept,"
                + "content-Type,origin,x-requested-with,content-type,accept,authorization,token,id,X-Custom-Header,X-Cookie,Connection,User-Agent,Cookie,*");

        resp.setHeader("Access-Control-Request-Headers", "Authorization,Origin, X-Requested-With,content-Type,Accept");

        // 可以暴露给外部所有头部信息字段
        resp.setHeader("Access-Control-Expose-Headers", "*");

        // 过滤器放行
        filterChain.doFilter(req, resp);
    }

    @Override
    public void destroy() {
        System.out.println("跨域访问--销毁");
    }
}

8、防止页面乱码的过滤器

package filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharEncodingFilter implements javax.servlet.Filter {

	// 定一个变量存编码
	private String encoding;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// filterConfig:读取过滤器的一些配置信息

		String encoding = filterConfig.getInitParameter("encoding");
		this.encoding = encoding;
		System.out.println("中文处理....初始化" + encoding);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 父接口转为子接口
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;

		// 设置请求
		req.setCharacterEncoding(encoding);

		// 设置响应对象的编码
		resp.setCharacterEncoding(encoding);
		//resp.setContentType("text/html;charset=" + encoding);

		// 放行
		chain.doFilter(req, resp);
	}

	@Override
	public void destroy() {
		System.out.println("中文编码销毁....");
	}

}

        还需要配置xml,星号表示全部servlet都可用

 
        CharEncodingFilter
        filter.CharEncodingFilter
        
            编码设置
            encoding
            UTF-8
        
    
    
        CharEncodingFilter
        /*
    

好啦,到这里我们的登录功能的所有准备和代码都已经完成了,那么怎么执行我们的服务器(TomCat)呢?怎么去登录呢?

其实,和我们之前写 web 项目一样,只不过现在我们是用微信小程序来设计页面,后台代码还是我们熟悉的JavaServlet。我们只需要运行我们的猫就可以了

六、运行

1、直接点击运行,开启服务器

微信小程序 + Java + Mysql(登录 Demo)_第4张图片

 

2、运行页面 404?

 运行之后是不是发现页面报错啦,没关系,这是因为我们没有在web项目中写我们的页面,我们的页面在小程序中设计了,如果不行看到这个错误的话,可以在项目中随便写一个页面就ok啦!

微信小程序 + Java + Mysql(登录 Demo)_第5张图片

 

3、运行小程序的登录页面

1、输入账号密码进行登录

微信小程序 + Java + Mysql(登录 Demo)_第6张图片

 2、登录成功后跳转页面

微信小程序 + Java + Mysql(登录 Demo)_第7张图片

3、后台提示

微信小程序 + Java + Mysql(登录 Demo)_第8张图片

好啦,到这里我们的小程序+ Java 的登录 DEMO已经完成了。

这次没有使用到MD5加密和文件上传的工具类,我打算在下一章的注册功能中再实现代码给到大家。

七、总结 建议

1、我是在学校学习Java后台开发的学生,只是这段时间老师讲的内容不是很多,就自己开始学习一点课外的知识来充实自己的知识库。

2、大家在学习的时候呢,不要盲目的学习,要有目标性去学,才会从中获取到自己想要的。不要学这个学一下,学那个又学一下,这样只会让自己什么都学不到,我就试过这样了,看这个新鲜就学这个,看哪个新鲜又学哪个,到最后什么都没有学会。就会觉得自己什么都学不好,所以大家在学习过程中一定要专注一门课程,等你学会了,再去学别的。

3、本次是自己第一次发布博客,没有经验,全靠自己的感觉去写,如果有写的不好的,请各位大佬指出,我会及时更正!

 

你可能感兴趣的:(小程序,+,Java,开发,maven,servlet,intellij-idea)