哈喽!刚刚开始接触Android, 有很多地方都不同懂,甚至有点想放弃,曾几何时,我会感叹 安卓“从界面到放弃”,但做什么事都要坚持下来,这个登录做了一周了,下面开始进入主题。
这篇博客是写Android 客户端登录,怎样传数据到服务端(用的是SSM框架)。然后又从服务端查询到数据,怎样传到Android端。 看到评论都要后台代码,我放上了Git ,要的自取 服务端下载地址
环境准备: 1 Android端:Android Studio 2.3.3 版本
需要重要jar fastjson 和 gson 包下载地址:点击打开链接
2,服务端:工具: Eclipse
框架:spring+springmvc+mybatis ,不会搭这个框架的私我,后期我会写这个框架怎么搭建的
重要jar包:jackson.jar 下载地址:点击打开链接
- Android 端
- 登录界面的 activity_login.xml文件 ,我只贴了主要的控件的
<LinearLayout
android:id="@+id/email_login_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:id="@+id/userId"
/>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="40dp"
android:hint="账号"
android:inputType="textEmailAddress"
android:maxLines="1"
android:imeOptions="actionDone"
/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:inputType="textPassword"
android:maxLines="1"
android:imeOptions="actionDone"
/>
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/btn_login"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@color/colorloginbtn"
android:text="登 录"
android:textColor="@color/bg_white"
android:textStyle="bold"
android:textSize="20sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<Button
android:id="@+id/btnRegister"
android:layout_width="50dp"
android:layout_height="25dp"
android:text="注册"
android:textSize="18sp"
android:background="@drawable/login_btn_click_bg" />
<Button
android:id="@+id/btnForgotPassword"
android:layout_width="80dp"
android:layout_height="25dp"
android:layout_alignParentRight="true"
android:text="忘记密码"
android:textSize="18sp"
android:background="@drawable/login_btn_click_bg" />
</RelativeLayout>
</LinearLayout>
2. LoginActib
package com.gx.cn.hospitalmanage;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.gx.cn.hospitalmanage.MyFragmentOne.NetUtils;
import com.gx.cn.hospitalmanage.MyFragmentOne.User;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import cz.msebera.android.httpclient.Header;
/**
* A login screen that offers login via email/password.
*/
public class LoginActivity extends AppCompatActivity {
private Button btnRegister,btnForgotPassword,mEmailSignInButton;
private Intent intent;
private TextView userID;
private TextView userName;
private TextView password;
private String result;
String name,pwd; //定义用户名和密码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//隐藏标题
getSupportActionBar().hide();
//进入主界面
mEmailSignInButton = (Button) findViewById(R.id.btn_login);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
EditText tvname=(EditText) findViewById(R.id.username); //获取用户控件
name= tvname.getText().toString(); //获取控件里面的值
EditText tvPsd=(EditText) findViewById(R.id.password);
pwd=tvPsd.getText().toString();
new Thread() {
@Override
public void run() {
int num= init(name,pwd);
if(num>0){ //判断id是否大于1,>1就是查询到有数据 ,可以进入主界面
Intent it=new Intent(LoginActivity.this,MainActivity.class);
it.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(it);
}else {
Toast.makeText (getApplicationContext(),"用户或密码错误", Toast.LENGTH_LONG ).show();
}
}
}.start();
}
});
//注册
btnRegister=(Button)findViewById(R.id.btnRegister);
btnRegister.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent it=new Intent(LoginActivity.this,RegisterActivity.class);
startActivity(it);
}
});
//忘记密码
btnForgotPassword =(Button)findViewById(R.id.btnForgotPassword);
btnForgotPassword.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
//json格式与服务端交互
private int init(String name,String pwd){
// 192.168.3.138 这个ip地址是电脑Ipv4 地址 /20170112 是服务端的项目名称 /login/toJsonMain 是@RequestMapping的地址
String urlPath="http://192.168.3.138:8080/20170112/login/toJsonMain.action";
// String urlPath="http://192.168.42.207:8080/20170112/login/toJsonMain.action"; 这个是实体机(手机)的端口
URL url;
int id=0;
try {
url=new URL(urlPath);
JSONObject jsonObject=new JSONObject();
jsonObject.put("username",name); //参数put到json串里
jsonObject.put("password",pwd);
//JSONObject Authorization =new JSONObject();
// Authorization.put("po类名",jsonObject 即po的字段)
String content=String.valueOf(jsonObject); //json串转string类型
HttpURLConnection conn=(HttpURLConnection) url.openConnection(); //开启连接
conn.setConnectTimeout(5000);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("ser-Agent", "Fiddler");
conn.setRequestProperty("Content-Type","application/json");
//写输出流,将要转的参数写入流里
OutputStream os=conn.getOutputStream();
os.write(content.getBytes()); //字符串写进二进流
os.close();
int code=conn.getResponseCode();
if(code==200){ //与后台交互成功返回 200
//读取返回的json数据
InputStream inputStream=conn.getInputStream();
// 调用自己写的NetUtils() 将流转成string类型
String json= NetUtils.readString(inputStream);
Gson gson=new Gson(); //引用谷歌的json包
User user=gson.fromJson(json,User.class); //谷歌的解析json的方法
id =user.getId(); //然后user.get你想要的值
String username=user.getUsername();
String password=user.getPassword();
}else{
Toast.makeText (getApplicationContext(),"数据提交失败", Toast.LENGTH_LONG ).show();
}
}catch (Exception e){
e.printStackTrace();
}
return id;
}
}
3. NetUtils 这个类是 将流转成string类型,LoginActivity会调用到
public class NetUtils {
public static byte[] readBytes(InputStream is){
try {
byte[] buffer = new byte[1024];
int len = -1 ;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len = is.read(buffer)) != -1){
baos.write(buffer, 0, len);
}
baos.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null ;
}
public static String readString(InputStream is){
return new String(readBytes(is));
}
}
4. 实体类: User
public class User {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
生成get和set() ,快捷键 Alt+Insert
5. 在AndroidManifest.xml 里面加上
<uses-permission android:name="android.permission.INTERNET"/>开启Android连接网络
6. 断点调式:看图
第一次运行要断点测试:主要看content 这个值后面有没有生成数据,或者生成的格式是否和我圈的一致,如果不是这样的json格式,Android 发送的请求可能会失败,或者JAVA服务端接收不到数据。
如果能发送过去,后台根据username和password这两个参数查询,如果查询到数据就返回 json =后面这一串json数据,
如果查询不到,json=“ ”空
服务端:(SSM)
1. Controller层 处理请求
package cn.itcast.ssm.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.itcast.ssm.po.UserCustom;
import cn.itcast.ssm.service.UserService;
@Controller
@RequestMapping("/login")
public class LoginJsonTest {
@Autowired
private UserService userService; //注入UserService
//获取key/value格式 从jsp页面传也可以,从Android传来也可以,只要格式对应这里接收就行了
@RequestMapping("/toMain")
public @ResponseBody UserCustom toMain(UserCustom userCustom ) throws Exception{
UserCustom userList =userService.selectUserIf(userCustom);
return userList;
}
//获取json格式 从Android端传来的json格式,如果不是json格式,这里就接收不到数据
@RequestMapping("/toJsonMain")
public @ResponseBody UserCustom toJsonMain(@RequestBody UserCustom userCustom ) throws Exception{
UserCustom userList =userService.selectUserIf(userCustom); //查询语句
return userList; //返回json格式的数据给Android ,这里为什么这简单,都是Jackson.jar做的工作
}
}
2.如果Android端 哪个边没有问题,请求就能响应 后台 记得断点测试,看图吧
3.查询到数据并成功返回 ,看图吧
jsp 页面传到json数据:
总结一下:
1.首先要做好Java后台的工作,搭建好框架,用jsp页面写一个简单登录界面,然后用将用户名和密码通过ajax() 发送请求,记得ajax方法里面用json格式,传递参数,如果能传到后台,你就成功一半了,然后返回json数据就很简单了,因为jsp页面解析json数据相对比Android简单得多,然后按照这个思路去跟Android端连接,记得把这个连接地址复制到Android端请求的url地址
2.在Android端,我刚开始是不会将参数转json格式,和将json数据转成我们想要的数据类型,都是搞上网查询,看大神们怎样用json的,不懂就要多问,多查询资料。
3.如果上面代码中有什么不对的地方,请各位大神指点一下,或者大家有什么想说都可以,大家共同学习,一起进步。