【移动应用开发技术】android通过web与后台数据库交互_第1页
【移动应用开发技术】android通过web与后台数据库交互_第2页
【移动应用开发技术】android通过web与后台数据库交互_第3页
【移动应用开发技术】android通过web与后台数据库交互_第4页
【移动应用开发技术】android通过web与后台数据库交互_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】android通过web与后台数据库交互

开发一个app与后台数据库交互,基于mysql+jdbc+tomcat,没有使用DBUtils或jdbc框架,纯粹底层jdbc实现.以后逐步改用Spring框架,优化mysql,进一步部署tomcat等等,现在项目刚刚起步,还有很多不懂的东西,得慢慢来这几天踩了很多坑,说得夸张点真是踩到我没有知觉,希望能帮助别人少踩坑...2.github这是源码地址,包括前后端与建表等所有代码.(欢迎star)IDE就不说了,重点说一下mysql与tomcat9的安装一.安装Mysql8.0.17这个是目前比较新的mysql版本.服务器系统是centos其他系统安装看这里centos使用yum命令安装(参考链接)(1)下载mysqlsudoyumlocalinstall//mysql80-community-release-el7-1.noarch.rpm(2)安装mysqlsudoyuminstallmysql-community-server(3)启动服务sudoservicemysqldstart(4)查看初始化密码,用于下一步设置自己的root密码sudogrep'temporarypassword'/var/log/mysqld.log(5)本地使用root登录mysql-uroot-p输入上一步看到的密码(6)更改密码altermysql.user'root'@'localhost'identifiedby'password';注意新版本的mysql不能使用太弱的密码如果出现如下提示则说明密码太弱了,请使用一个更高强度的密码(7)允许外部访问usemysql;

updateusersethost='%'whereuser='root';这个可以根据自己的需要去修改,host='%'表明允许所有的ip登录,也可以设置特定的ip,若使用host='%'的话建议新建一个用户配置相应的权限.(8)配置防火墙(可选)由于作者使用的是阿里云的服务器,没配置防火墙的话远程连接不上,因此需要手动配置,如图其中授权对象可以根据自己的需要更改,/0表示允许所有的ip.<br><br>二.安装tomcat9(1)先去官网下载,下载后上传文件到服务器作者使用的是scp命令,不会的可以看这里scpapache-tomcat-xxxx.tar.gzusername@xx.xx.xx.xx:/改成自己的用户名和ip(2)连接到服务器,解压压缩包mkdir/usr/local/tomcat

mvapache-tomcat-xxxx.tar.gz/usr/local/tomcat

tar-xzvfapache-tomcat-xxx.tar.gz(3)修改tomcat默认端口(可选)修改conf/server.xml文件,一般只需修改<Connectorport="8080"protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"/>中的8080端口,修改这个端口即可这个懒的话(比如作者)可以不改(4)启动tomcat运行bin目录下的startup.shcdbin

./startup.sh(5)测试浏览器输入服务器IP:端口若出现则表示成功.(6)开机启动建议配置开机启动,修改/etc/rc.local文件vim/etc/rc.local

添加

sh/usr/local/tomcat/bin/startup.sh这个根据自己的tomcat安装路径修改,指定bin下的startup.sh即可创建用户表,这里简化操作(好吧我喜欢偷懒)就不创建新用户不授权了这是一个在本地用root登录的示例,请根据实际情况创建并授权用户.(1)创建user.sqlCREATEDATABASEuserinfo;

USEuserinfo;

CREATETABLEuser

(

idINTNOTNULLPRIMARYKEYAUTO_INCREMENT,

nameCHAR(30)NULL,

passwordCHAR(30)NULL

);(2)导入到数据库mysql-uroot-p<user.sql(1)创建项目选择webapplication选好路径,改好名字后finish(2)添加jar包创建一个叫lib的目录添加两个jar包:mysql-connector-java-8.0.17.jarjavax.servlet-api-4.0.1.jar打开ProjectStructureModules-->+-->JARsordirectories选择刚才新建的lib下的两个jar包打勾,apply(3)创建包与类总共4个包(4)先来处理DBUtils类这个是连接数据库的类,纯粹的底层jdbc实现,注意驱动版本.packagecom.util;

importjava.sql.*;

publicclassDBUtils{

privatestaticConnectionconnection=null;

publicstaticConnectiongetConnection()

{

try{

Class.forName("com.mysql.cj.jdbc.Driver");

Stringurl="jdbc:mysql://:3306/数据库名字";

Stringusename="账号";

Stringpassword="密码";

connection=DriverManager.getConnection(url,usename,password);

}

catch(Exceptione)

{

e.printStackTrace();

returnnull;

}

returnconnection;

}

publicstaticvoidcloseConnection()

{

if(connection!=null)

{

try{

connection.close();

}

catch(SQLExceptione)

{

e.printStackTrace();

}

}

}

}主要就是获取连接与关闭连接两个函数.Stringurl="jdbc:mysql://:3306/数据库名字";

Stringusename="账号";

Stringpassword="密码";这几行根据自己的用户名,密码,服务器ip和库名修改注意,mysql8.0以上使用的注册驱动的语句是Class.forName("com.mysql.cj.jdbc.Driver");旧版的是Class.forName("com.mysql.jdbc.Driver");注意对应.(5)接下来处理User类User类比较简单,就是就三个字段与getter,setterpackagecom.entity;

publicclassUser{

privateintid;

privateStringname;

privateStringpassword;

publicintgetId(){

returnid;

}

publicvoidsetId(intid){

this.id=id;

}

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

=name;

}

publicStringgetPassword(){

returnpassword;

}

publicvoidsetPassword(Stringpassword){

this.password=password;

}

}(6)接下来是UserDaopackagecom.dao;

importcom.entity.User;

importcom.util.DBUtils;

importjava.sql.Connection;

importjava.sql.PreparedStatement;

importjava.sql.ResultSet;

importjava.sql.SQLException;

publicclassUserDao{

publicbooleanquery(Useruser)

{

Connectionconnection=DBUtils.getConnection();

Stringsql="select*fromuserwherename=?andpassword=?";

try{

PreparedStatementpreparedStatement=connection.prepareStatement(sql);

preparedStatement.setString(1,user.getName());

preparedStatement.setString(2,user.getPassword());

ResultSetresultSet=preparedStatement.executeQuery();

returnresultSet.next();

}

catch(SQLExceptione)

{

e.printStackTrace();

returnfalse;

}

finally{

DBUtils.closeConnection();

}

}

publicbooleanadd(Useruser)

{

Connectionconnection=DBUtils.getConnection();

Stringsql="insertintouser(name,password)values(?,?)";

try{

PreparedStatementpreparedStatement=connection.prepareStatement(sql);

preparedStatement.setString(1,user.getName());

preparedStatement.setString(2,user.getPassword());

preparedStatement.executeUpdate();

returnpreparedStatement.getUpdateCount()!=0;

}

catch(SQLExceptione)

{

e.printStackTrace();

returnfalse;

}

finally{

DBUtils.closeConnection();

}

}

}主要就是查询与添加操作,查询操作中存在该用户就返回true,否则返回false添加操作中使用executeUpdate()与getUpdateCount()!=0.注意不能直接使用returnpreparedStatement.execute();去代替preparedStatement.executeUpdate();

returnpreparedStatement.getUpdateCount()!=0;咋一看好像没有什么问题,那天晚上我测试的时候问题可大了,android那边显示注册失败,但是数据库这边的却insert进去了我好吧说多了都是泪,还是函数用得不够熟练.<br><br>所以在这个例子中returnpreparedStatement.execute();肯定返回false,所以才会数据库这边insert进去,但前端显示注册失败(这个bug作者找了很久)(7)servlet包的SignIn与SignUp类SingIn类用于处理登录,调用jdbc查看数据库是否有对应的用户SignUp类用于处理注册,把user添加到数据库中这两个使用的是http连接,后期作者会采用https加密连接.SignIn.javapackagecom.servlet;

importcom.dao.UserDao;

importcom.entity.User;

importjavax.servlet.ServletException;

importjavax.servlet.annotation.WebServlet;

importjavax.servlet.http.HttpServlet;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjava.io.IOException;

@WebServlet("/SignIn")

publicclassSingInextendsHttpServlet{

@Override

protectedvoiddoGet(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse)throwsIOException,ServletException

{

this.doPost(httpServletRequest,httpServletResponse);

}

@Override

protectedvoiddoPost(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse)throwsIOException,ServletException

{

httpServletRequest.setCharacterEncoding("utf-8");

httpServletResponse.setCharacterEncoding("utf-8");

httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8

Stringname=httpServletRequest.getParameter("name");

Stringpassword=httpServletRequest.getParameter("password");

UserDaouserDao=newUserDao();

Useruser=newUser();

user.setName(name);

user.setPassword(password);

if(!userDao.query(user))//若查询失败

{

httpServletResponse.sendError(204,"queryfailed.");//设置204错误码与出错信息

}

}

}

@WebServlet("/SignIn")这行代码表示这是一个名字叫SignIn的servlet,可用于实现servlet与url的映射,如果不在这里添加这个注解,则需要在WEB-INF目录下的web.xml添加一个<servlet-mapping>叫servlet的映射httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8这行代码设置响应类型与编码Stringname=httpServletRequest.getParameter("name");

Stringpassword=httpServletRequest.getParameter("password");HttpServletRequest.getParameter(Stringname)方法表示根据name获取相应的参数下面是SignUp.javapackagecom.servlet;

importcom.dao.UserDao;

importcom.entity.User;

importjavax.servlet.annotation.*;

importjavax.servlet.http.*;

importjavax.servlet.*;

importjava.io.IOException;

@WebServlet("/SignUp")

publicclassSignUpextendsHttpServlet{

@Override

protectedvoiddoGet(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse)throwsIOException,ServletException

{

this.doPost(httpServletRequest,httpServletResponse);

}

@Override

protectedvoiddoPost(HttpServletRequesthttpServletRequest,HttpServletResponsehttpServletResponse)throwsIOException,ServletException

{

httpServletRequest.setCharacterEncoding("utf-8");

httpServletResponse.setCharacterEncoding("utf-8");//设定编码防止中文乱码

httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8

Stringname=httpServletRequest.getParameter("name");//根据name获取参数

Stringpassword=httpServletRequest.getParameter("password");//根据password获取参数

UserDaouserDao=newUserDao();

Useruser=newUser();

user.setName(name);

user.setPassword(password);

if(!userDao.add(user))//若添加失败

{

httpServletResponse.sendError(204,"addfailed.");//设置204错误码与出错信息

}

}

}

(8)添加servlet到web.xml<?xmlversion="1.0"encoding="UTF-8"?>

<web-appxmlns="/xml/ns/javaee"

xmlns:xsi="/2001/XMLSchema-instance"

xsi:schemaLocation="/xml/ns/javaee/xml/ns/javaee/web-app_4_0.xsd"

version="4.0">

<servlet>

<servlet-name>SignIn</servlet-name>

<servlet-class>com.servlet.SingIn</servlet-class>

</servlet>

<servlet>

<servlet-name>SignUp</servlet-name>

<servlet-class>com.servlet.SignUp</servlet-class>

</servlet>

</web-app>要把刚才创建的Servlet添加进web.xml,在<servlet>中添加子元素<servlet-name>与<servlet-class><servlet-name>是Servlet的名字,最好与类名一致.<servlet-class>是Servlet类的位置.如果在Servlet类中没有添加@WebServlet("/xxxx")这个注解,则需要在web.xml中添加<servlet-mapping>

<servlet-name>SignIn</servlet-name>

<url-pattern>/SignIn</url-pattern>

</servlet-mapping>其中<servlet-name>与<servlet>中的子元素<servlet-name>中的值一致<url-pattern>是访问的路径(9)最后添加一个叫Hello.html的html文件用于测试.<!DOCTYPEhtml>

<head>

<metacharset="utf-8">

<title>Welcome</title>

</head>

<body>

Helloweb.

</body>

</html><br><br><br>作者用的是IDEA,Eclipse的打包请看这里(1)打开projectstructure(2)选择Artifacts,WebApplication:Archive(3)改名字,创建WEB-INF目录与子目录classes(4)选中classes,添加ModuleOutput,选择自己的web项目(5)添加jar包,选中lib目录后添加jar包文件(那个lib文件夹被挡住了)(6)添加Hello.html与web.xmlweb.xml这个需要在WEB-INF目录里,Hello.html在WEB-INF外面(7)打包,Build->BuildArtifacts(8)上传到服务器把打包好的.war文件上传到服务器的tomcat的/webapps目录下的scp***.warusername@xxx.xxx.xxx.xxx:/usr/local/tomcat/webapps注意改成自己的webapps目录.(9)测试在浏览器输入服务器IP:端口/项目/Hello.html作者是在本地上开了tomcat后测试的(1)新建工程(2)MainActivity.javapackagecom.cx;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.Button;

importandroid.widget.EditText;

importandroid.widget.Toast;

importandroidx.appcompat.app.AppCompatActivity;

publicclassMainActivityextendsAppCompatActivity{

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Buttonsignin=(Button)findViewById(R.id.signin);

signin.setOnClickListener(newView.OnClickListener(){

@Override

publicvoidonClick(Viewview){

Stringname=((EditText)findViewById(R.id.etname)).getText().toString();

Stringpassword=((EditText)findViewById(R.id.etpassword)).getText().toString();

if(UserService.signIn(name,password))

runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_SHORT).show();

}

});

else{

runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_SHORT).show();

}

});

}

}

});

Buttonsignup=(Button)findViewById(R.id.signup);

signup.setOnClickListener(newView.OnClickListener(){

@Override

publicvoidonClick(Viewview){

Stringname=((EditText)findViewById(R.id.etname)).getText().toString();

Stringpassword=((EditText)findViewById(R.id.etpassword)).getText().toString();

if(UserService.signUp(name,password))

runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

Toast.makeText(MainActivity.this,"注册成功",Toast.LENGTH_SHORT).show();

}

});

else{

runOnUiThread(newRunnable(){

@Override

publicvoidrun(){

Toast.makeText(MainActivity.this,"注册失败",Toast.LENGTH_SHORT).show();

}

});

}

}

});

}

}没什么好说的,就为两个Button绑定事件,然后设置两个Toast提示信息.(3)UserService.javapackagecom.cx;

importjava.io.OutputStream;

import.HttpURLConnection;

import.URL;

import.URLEncoder;

publicclassUserService{

publicstaticbooleansignIn(Stringname,Stringpassword){

MyThreadmyThread=newMyThread("http://本机IP:8080/cx/SignIn",name,password);

try

{

myThread.start();

myThread.join();

}

catch(InterruptedExceptione)

{

e.printStackTrace();

}

returnmyThread.getResult();

}

publicstaticbooleansignUp(Stringname,Stringpassword){

MyThreadmyThread=newMyThread("http://本机IP:8080/cx/SignUp",name,password);

try

{

myThread.start();

myThread.join();

}

catch(InterruptedExceptione)

{

e.printStackTrace();

}

returnmyThread.getResult();

}

}

classMyThreadextendsThread

{

privateStringpath;

privateStringname;

privateStringpassword;

privatebooleanresult=false;

publicMyThread(Stringpath,Stringname,Stringpassword)

{

this.path=path;

=name;

this.password=password;

}

@Override

publicvoidrun()

{

try{

URLurl=newURL(path);

HttpURLConnectionhttpURLConnection=(HttpURLConnection)url.openConnection();

httpURLConnection.setConnectTimeout(8000);//设置连接超时时间

httpURLConnection.setReadTimeout(8000);//设置读取超时时间

httpURLConnection.setRequestMethod("POST");//设置请求方法,post

Stringdata="name="+URLEncoder.encode(name,"utf-8")+"&password="+URLEncoder.encode(password,"utf-8");//设置数据

httpURLConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//设置响应类型

httpURLConnection.setRequestProperty("Content-Length",data.length()+"");//设置内容长度

httpURLConnection.setDoOutput(true);//允许输出

OutputStreamoutputStream=httpURLConnection.getOutputStream();

outputStream.write(data.getBytes("utf-8"));//写入数据

result=(httpURLConnection.getResponseCode()==200);

}catch(Exceptione){

e.printStackTrace();

}

}

publicbooleangetResult()

{

returnresult;

}

}MyThreadmyThread=newMyThread("http://本机IP:8080/cx/SignUp",name,password);

MyThreadmyThread=newMyThread("http://本机IP:8080/cx/SignIn",name,password);这两行换成自己的ip,本地ip的话可以用ipconfig或ifconfig查看,修改了默认端口的话也把端口一起改了.路径的话就是端口/web项目名/Servlet名web项目名是再打成war包时设置的,Servlet名在web.xml中的<servlet>的子元素<servlet-name>设置,与java源码中的@WebServlet()注解中的一致另外一个要注意的就是线程问题,需要新开一个线程进行http的连接(4)activity_main.xml前端页面部分很简单,就两个button,用于验证功能.<?xmlversion="1.0"encoding="utf-8"?>

<LinearLayout

xmlns:app="/apk/res-auto"

xmlns:android="/apk/res/android"

android:layout_height="match_parent"

android:layout_width="match_parent"

android:orientation="vertical"

>

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="用户名"

/>

<EditText

android:layout_width="300dp"

android:layout_height="60dp"

android:id="@+id/etname"

/>

</LinearLayout>

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="密码"

/>

<EditText

android:layout_width="300dp"

android:layout_height="60dp"

android:id="@+id/etpassword"

/>

</LinearLayout>

<LinearLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal">

<Button

android:layout_width="120dp"

android:layout_height="60dp"

android:text="注册"

android:id="@+id/signup"

/>

<Button

android:layout_width="120dp"

android:layout

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论