我正在编写一个使用java Servlet管理登录的Android应用程序。 登录数据在MySQL数据库中检查。 这个servlet应该返回一个json对象。 在某些代码下面:
的Servlet
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package AndroidControllers;
import Database.Authentication;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONObject;
/**
*
* @author serge
*/
public class Android extends HttpServlet {
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
/* TODO output your page here. You may use following sample code. */
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet Android</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet Android at " + request.getContextPath() + "</h1>");
out.println("</body>");
out.println("</html>");
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
String user = request.getParameter("username");
String pass = request.getParameter("password");
PrintWriter out = response.getWriter();
JSONObject logged = Authentication.login_json(user, pass);
if(logged != null)
writer.print(logged);
else{
logged.put("type", "ERROR");
logged.put("username", "ERROR");
writer.print(logged);
}
//processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Authentication.login_json方法:
public static JSONObject login_json(String user, String pass){
JSONObject json = new JSONObject();
Connection conn = null;
String sql = "select username, user_type from users where username = '" + user +
"' and password = '" + pass + "';";
try{
Class.forName("com.mysql.jdbc.Driver");
conn = Utilities.connect();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
if(rs.next()){
json.put("username", user);
json.put("type", rs.getString("user_type"));
}
else{
json.put("username", "FAIL");
json.put("type", "FAIL");
}
}
catch(SQLException | ClassNotFoundException ecc){
System.out.println("ERROR: " + ecc.getMessage());
}
finally{
Utilities.disconnect(conn);
}
return json;
}
Android中使用的身份验证方法:
package com.example.serge.biblioteca;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class http_authentication{
public static JSONObject login_json(String user, String pass) {
String json_string = "";
JSONObject stream = new JSONObject();
JSONParser parser = new JSONParser();
String url = "http://localhost:43746/Progetto_TWEB/Android?username=" + user
+ "&password=" + pass;
try {
URL link = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) link.openConnection();
// Check the connection status
if (urlConnection.getResponseCode() == 200) {
// if response code = 200 ok
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
// Read the BufferedInputStream
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
sb.append(line);
}
json_string = sb.toString();
stream = (JSONObject) parser.parse(json_string);
// End reading...............
// Disconnect the HttpURLConnection
urlConnection.disconnect();
} else {
// Do something
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} finally {
}
// Return the data from specified url
return stream;
}
}
这些方法在普通的Java类中使用效果很好,它们总是返回预期的json对象。在Andoid应用程序中,我总是得到一个空的json对象,我不知道为什么。
这里是活动代码:
package com.example.serge.biblioteca;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.json.simple.parser.JSONParser;
import org.json.simple.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by serge on 28/12/2017.
*/
public class login extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
final Button login = (Button) findViewById(R.id.login_login);
final EditText username = (EditText) findViewById(R.id.txtUser);
final EditText password = (EditText) findViewById(R.id.txtPass);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
JSONObject logged = new JSONObject();
boolean vuoto = false;
String logged_type = "";
String logged_user = "", user_type = "";
TextView welcome = (TextView)findViewById(R.id.normal_intro);
String user = username.getText().toString();
String pass = password.getText().toString();
try {
logged = http_authentication.login_json(user, pass);
vuoto = logged.isEmpty();
//The following setText always returns an empty String so I think the object is null
username.setText(logged.toString());
}
catch(Exception ecc){
username.setText(ecc.getMessage());
}
}
});
}
}
你能帮助我理解为什么Android Activity总是得到一个null对象,但普通的java类运行良好吗? 谢谢
答案 0 :(得分:0)
我设法解决了这个问题。 如果有人想知道我将如何解释如下:
首先,我创建了一个新的Servlet,它执行相同的操作但代码少得多:
package AndroidControllers;
import Database.Authentication;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONObject;
import org.json.simple.parser.*;
public class Login extends HttpServlet {
private static final long serialVersionUID = 1L;
public Login() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
JSONObject logged = Authentication.login_json(username, password);
if(!logged.isEmpty()){
out.println(logged);
}
else{
logged.put("username", "NULL");
logged.put("type", "NULL");
out.println(logged);
}
}
}
此servlet获取两个参数(用户名和密码)并检查它们是否存在MySQL数据库。如果它们存在,则返回类型为:{“username”:“username”,“type”:“admin”或“type”:“normal”}的JSONObject。 Authentication.login_json(用户名,密码)方法是相同的......
我还开发了Android Activity:
package com.example.serge.biblioteca;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class login_page extends AppCompatActivity implements View.OnClickListener{
Button login;
EditText user, pass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_page);
findViewsByID();
login.setOnClickListener(this);
}
private void findViewsByID(){
login = (Button) findViewById(R.id.login_login);
user = (EditText) findViewById(R.id.txtUser);
pass = (EditText) findViewById(R.id.txtPass);
}
@Override
public void onClick(View view) {
String username = user.getText().toString();
String password = pass.getText().toString();
String URL = "http://192.168.1.4:43746/Progetto_TWEB/Login?username=" + username
+ "&password=" + password;
GetXMLTask task = new GetXMLTask();
task.execute(new String[] { URL });
}
private class GetXMLTask extends AsyncTask<String, Void, JSONObject> {
@Override
protected JSONObject doInBackground(String... urls) {
JSONObject output = null;
for (String url : urls) {
String json_string = getOutputFromUrl(url);
JSONParser parser = new JSONParser();
try {
output = (JSONObject) parser.parse(json_string);
}
catch(ParseException ecc){
}
}
return output;
}
private String getOutputFromUrl(String url) {
StringBuffer output = new StringBuffer("");
try {
InputStream stream = getHttpConnection(url);
BufferedReader buffer = new BufferedReader(
new InputStreamReader(stream));
String s = "";
while ((s = buffer.readLine()) != null)
output.append(s);
} catch (IOException e1) {
e1.printStackTrace();
}
return output.toString();
}
// Makes HttpURLConnection and returns InputStream
private InputStream getHttpConnection(String urlString)
throws IOException {
InputStream stream = null;
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
try {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("GET");
httpConnection.connect();
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
stream = httpConnection.getInputStream();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return stream;
}
@Override
protected void onPostExecute(JSONObject output) {
Intent redirect_normal = new Intent(login_page.this, normal_user.class);
String type = output.get("type").toString();
if(type.equals("normal"))
startActivity(redirect_normal);
else if(type.equals("NULL"))
user.setText("LOGIN FAILED");
else if(type.equals("admin"))
user.setText("NOT NORMAL");
}
}
}
如您所见,Activity可以使用AsyncTask,HTTPURLConnection和InputStream与Servlet通信。 这一切一切正常,因为Android Activity得到了预期的JSONObject。 我想对在这里帮助过我的所有人说谢谢。 希望这对某人有用,对不起我的英语。