简单的微信小程序 从入门到入土

前言

前阵子接了个小项目,要做个微信小程序。逻辑方面十分简单,教科书般的工单系统。不过由于我对于后端前端完全没有学习基础,语言至今只学过C/C++的基础,终究还是花了一个多星期才做出beta版。虽然本地的确能跑了,但是估计还是有不少问题。在此记录下流程,以便后期修改时能立刻想起来。同时分享出来作为一个“起码跑的起来”的例子,以供大家参考指正。
本人能力有限,如有错误或不规范之处,感谢指出

思路

一个简单的 C/S 结构就可以解决这个问题:
客户端发送信息给服务器,服务器进行处理,返回客户端需求的数据,之后由小程序显示出来
所以我们需要一个服务器来接受请求,一个数据库用来存放数据,一组代码来操作数据库和接受到的请求。

开发工具

服务器使用Tomcat 8.0.44 , 后端开发使用Eclipse Oxygen Release (4.7.0) , 小程序开发使用微信web开发者工具1.02 , 数据库使用MySQL 5.6.44

基本流程

提交请求
响应请求
查询数据
返回数据
小程序
服务器
数据库

Q:小程序如何提交请求呢?
A:利用wx.request和wx.uploadFile API提交给服务器。

Q:服务器如何才能获取小程序提交的请求?
A: 使用servlet获取小程序提交的请求。

Q: 我现在成功获取到了小程序发送来的数据,可是想保存在数据库里,该怎么办呢?
A: 使用JDBC连接数据库从而在服务器代码中将获取的数据存入数据库中。

数据库

首先在MySQL 中创建出相应数据库和表。
如:

CREATE TABLE USER
  (
	
    username varchar(16) primary key ,
	password varchar(24) ,
	name varchar(16), 
	permission tinyint(1) ,
	phone char(11),
	accept BOOL

  );

服务端

选择了Servlet 用作服务器接收小程序请求。配置了web.xml后则可在 创建出的Servlet文件中的doGetdoPost 函数中对接收到的数据进行处理了。
示例代码(查询数据库中内容):

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    // 修改编码为utf-8 用于显示中文
    //        response.setContentType("text/html;charset=utf-8"); 
    response.setContentType("application/json; charset=utf-8");
    // 设置响应头允许ajax跨域访问  
    response.setHeader("Access-Control-Allow-Origin", "*");
    // 星号表示所有的异域请求都可以接受  
    response.setHeader("Access-Control-Allow-Methods", "GET,POST");

    // ——————————————————————————
    // 连接和注册数据库
    // JDBC 驱动名及数据库 URL
    String DB_URL = "jdbc:mysql://localhost:3306/working?characterEncoding=utf8";
    // 数据库的用户名与密码
    String USER = "root";
    String PASS = "password";
    Connection conn = null;
    Statement stmt = null;
    try {
        // 注册 JDBC 驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 打开链接
        conn = DriverManager.getConnection(DB_URL, USER, PASS);
        // 实例化Statement对象
        stmt = conn.createStatement();
        //
	// ————————————————————————————

        // 用于接受客户端传递的数据
        String cData = request.getParameter("data");
        // 如果是获取数据的指令
        if (cData.equals("G")) {
			// 执行查询
			String sql;
			sql = "select * from worklist";
			ResultSet rs = stmt.executeQuery(sql);

			List < String > Wno = new ArrayList < String > ();
			List < String > Wstate = new ArrayList < String > ();
			List < String > Wtitle = new ArrayList < String > ();
			List < String > Wcreater = new ArrayList < String > ();
			List < String > Wworker = new ArrayList < String > ();
			// 回送数据 格式为json
			int i = 0;
			while (rs.next()) {
				i++;
				Wcreater.add("\"" + rs.getString("creater") + "\"");
				Wworker.add("\"" + rs.getString("worker") + "\"");
				Wno.add("\"" + rs.getString("no") + "\"");
				Wstate.add("\"" + rs.getString("state") + "\"");
				Wtitle.add("\"" + rs.getString("title") + "\"");
			}
			// 返回json格式数据
			response.getWriter().write("{\"no\": " + Wno + " ,");
			response.getWriter().write("\"state\": " + Wstate + " ,");
			response.getWriter().write("\"creater\": " + Wcreater + " ,");
			response.getWriter().write("\"worker\": " + Wworker + " ,");
			response.getWriter().write("\"title\": " + Wtitle + "}");

			System.out.print("返回" + i + "份工单数据成功\n");
			// 完成后关闭结果集
			rs.close();
		}
		// 完成后关闭实例,释放连接
		stmt.close();
		conn.close();
	}catch (SQLException se) {
		// 处理 JDBC 错误
		se.printStackTrace();
	} catch (Exception e) {
		// 处理 Class.forName 错误
		e.printStackTrace();
	} finally {
		// 关闭资源
		try {
			if (stmt != null) stmt.close();
		} catch (SQLException se2) {} // 关闭连接
		try {
			if (conn != null) conn.close();
		} catch (SQLException se) {
			se.printStackTrace();
		}
	}
}

这里需要注意的是三方(数据库,后端,前端)的编码一定要统一,不然一定会有乱码;
同时,回传的数据最好使用json格式,否则小程序读取数据会十分麻烦。

客户端

小程序方面则可以调用微信封装的API wx.request对服务器进行请求数据.
js代码如下:

 var temp_this = this;
 wx.request({
     url: 'http://localhost/working/QuestionList',
     data: {
         data: 'G',
     },
     header: {
         'content-type': 'application/json'
     },
     method: 'get',
     dataType: 'json',
     responseType: 'text',
     success: function(res) {
         console.log(res.data)

         console.log("向服务器请求成功")
         // 将服务端数据存储在本地
         temp_this.setData({
             no: res.data.Wno,
             state: res.data.Wstate,
             creater: res.data.Wcreater,
             worker: res.data.Wworker,
             title: res.data.Wtitle
         });

     },
 })

小程序中要注意的则是: 定义一个临时指针指向this,否则在wx.request函数里无法直接调用this

到了这时候,已经实现了客户端和服务器的通信,小程序具备了雏形。

上传图片

之后甲方需求上传相应图片,这部分和之前的内容就不太一样了——不能通过数据库直接实现(硬要说利用数据库实现也可以,利用数据库存储二进制文件,但是效率极差,故考虑直接存储在服务器上利用URL直接访问)。
在数据库中添加了图片数量字段,由于本程序不考虑安全性问题,故使用了有规律的目录进行存储图片,节省数据库存储目录的字段,直接利用工单号进行构建。
用到了fileupload这个包
fileupload下载
代码如下:

package com.temp.temp.temp;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

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 org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import java.util.*; 

/**
 * Servlet implementation class getImage
 */
@WebServlet("/getImage")
public class getImage extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public getImage() {
        super();
        // TODO Auto-generated constructor stub
    }
    // 全局的 no 用于确定当前工单
    private String no = "";
    
    // 更新照片数量函数
    private void sqlUpdate(int flag) {
        // ——————————————————————————
        // 连接和注册数据库
        // JDBC 驱动名及数据库 URL
           String DB_URL = "jdbc:mysql://localhost:3306/working?useUnicode=true&characterEncoding=utf-8";
           // 数据库的用户名与密码
           String USER = "root";
           String PASS = "young1225";
           Connection conn = null;
           Statement stmt = null;
           try{
               // 注册 JDBC 驱动
               Class.forName("com.mysql.jdbc.Driver");
               // 打开链接
               conn = DriverManager.getConnection(DB_URL,USER,PASS);
               // 执行查询
              // 实例化Statement对象
               stmt = conn.createStatement();
             //
             // ————————————————————————————
               
               // 更新语句——————————
               String update;
               // 每次对于不同的插入,在数据库中对于计数器自增1
               if(flag == 1)
            	   update = "update working set WdevPhotocount = WdevPhotocount + 1 where no = " + no;
               else 
            	   update = "update working set WwrkPhotocount = WwrkPhotocount+ 1 where no = " + no;
               
				System.out.println(update);
				stmt.executeUpdate(update);
               
               // 完成后关闭
               stmt.close();
               conn.close();
           }catch(SQLException se){
               // 处理 JDBC 错误
               se.printStackTrace();
           }catch(Exception e){
               // 处理 Class.forName 错误
               e.printStackTrace();
           }finally{
               // 关闭资源
               try{
                   if(stmt!=null) stmt.close();
               }catch(SQLException se2){
               }// 关闭连接
               try{
                   if(conn!=null) conn.close();
               }catch(SQLException se){
                   se.printStackTrace();
               }
           }
    }
    
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// doPost
		System.out.print("成功进入GetImage\n");
	
	    // 存取form中其他数据
	    String ino = "";
	    String permission ="";
        //获得磁盘文件条目工厂  
        DiskFileItemFactory factory = new DiskFileItemFactory(); 
        //文件上传处理  
        ServletFileUpload upload = new ServletFileUpload(factory);  
        try {  
            //可以上传多个文件  
            List<FileItem> list = (List<FileItem>)upload.parseRequest(request);  
            for(FileItem item : list){  
                //如果获取的 表单信息是普通的 文本 信息  
                if(item.isFormField()){                     
                    //获取用户具体输入的字符串,因为表单提交过来的是 字符串类型的  
                    String value = item.getFieldName() ;
//                    System.out.print("value:" + value+item.getString("UTF-8")+"\n");
                    // 进行判断,为每一个键值存储属性
                    if(value.equals("no"))
                    {
                    	no = new String(item.getString("UTF-8"));
                    }
                    else if(value.equals("permission"))
                    { 
                    	permission = new String(item.getString("UTF-8"));
                    }
                    else if(value.equals("ino"))
                    {
                    	ino = new String(item.getString("UTF-8"));
                    }
                }
                else{  
 
                    //获取文件需要上传到的路径 
                    @SuppressWarnings("deprecation")
            		String path = request.getRealPath("/temp/0" + no);  
                    // 新建目录
                    File file=new File(path);
                    if(!file.exists()){
                    	file.mkdirs();
                    }
                    factory.setRepository(new File(path));  
                    //设置 缓存的大小
                    factory.setSizeThreshold(4096*1024*1024) ;  
                    // 构造文件名
                	String filename = permission+"_0"+ino+".jpg";
                    //写到磁盘上  
                    item.write( new File(path,filename) );// 写入文件至服务器
                    System.out.println("上传成功:"+filename);
                    response.getWriter().print(path+"\\"+filename);//将路径返回给客户端
                    // 统计照片数量
                    if(permission.equals("dev"))
                    	sqlUpdate(1);
                    else
                    	sqlUpdate(0);
                }
            }
        } catch (Exception e) {  
        	System.out.println("上传失败");
        	response.getWriter().print("上传失败:"+e.getMessage());
        }	
   }
}


而在微信小程序这边,只需要调用wx.uploadFile 把相应数据丢给服务器的上述代码进行处理即可。
代码:

// 遍历图片数组,并上传
for(var i = 0 ; i < this.data.images.length ; i++)
{
	// 上传图片
	wx.uploadFile({
		url: 'http://localhost/working/imageOpt',
		filePath: temp_this.data.images[i],
		name: 'file',
		header: {},
		formData: {
			'permission': ((wx.getStorageSync("userPermission")) == 1 ? '开发者' : '施工者'),
			'wno': temp_this.data.no,
			'ino': ''+i,
		},
		success: function (res) {
			console.log(res.data);
		},
	})
}

尾声

综上,构建一个跑的起来的微信小程序的流程就完成了,关于小程序正式上线的部分在网上则是一搜一大把,在此不再赘述。
以及关于微信小程序的详情可以参考 微信小程序开放文档

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值