從零開發一款APP 二、Java Web後端註冊介面的實現__Java

來源:互聯網
上載者:User

今天我們要完成上一篇部落格中介面的設計,連結為  從零開發一款APP 一、Java Web後端註冊介面的設計  。上一篇的大致設計為,用戶端傳入使用者名稱、密碼、暱稱,然後服務端進行驗證,根據不同的情況返回不同的結果。

首先,根據上一節寫的請求介面的請求樣本,我們伺服器端需要從請求中讀取到請求的結果,請求的樣本為 {s:{"uname"=xxx,"upwd"=xxx,"nkname"=xxx}} ,但是如果我們每次接受到請求時,都需要先得到s對應的JsonObject,然後在去一個一個的解析,這樣實在是太痛苦了,而且這樣做重複代碼太多。所以,我們可以把json解析放到父類中。

我們知道,java web中每次請求都會映射到對應的HttpServlet 類對象中的service()方法中,在HttpServlet 的service()方法源碼中,會根據請求的類型,調用自身不同的方法來處理,比如如果得到請求類型為get,則調用自己的doGet()方法,如果請求類型為post,則調用自己的doPost()方法。所以,我們可以覆蓋HttpServlet 的service()方法,在裡面做出json解析。我們json解析使用的是阿里巴巴開源的fastjson。

下面為BaseServlet的源碼:

/** * 所有HttpServlet的基類,會把請求中的加密字串取出來並進行解密 (當前還尚未解密) * @author liuheng * */public class BaseServlet extends HttpServlet {//請求的Jsonprotected JSONObject requestJson;@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String securityString = req.getParameter("s");System.out.println("擷取的加密String為" + securityString);requestJson = JSON.parseObject(URLDecoder.decode(securityString, "UTF8"));super.service(req, resp);}}
可以看出,我們直接將s對應的字串解析成JSONObject,這樣子類就可以使用了。需要注意的是,我們所有的請求都使用post方式,所以,子類只需要複寫doPost()方法即可。

擷取到請求參數後,就應該去做相應的邏輯處理,比如判斷是否有重複使用者名稱,是否有重複暱稱,當判斷都沒有時,進行寫入,這時候如果寫入失敗,還需要返回失敗的標誌位。我們統稱這種邏輯處理類為Service類。

僅僅一個Service類是不夠的,我們還需要進行資料庫訪問的DAO類,DAO模式是標準的J2EE設計模式之一.開發人員使用這個模式把底層的資料訪問操作和上層的商務邏輯分開,即,我們使用DAO類來將訪問資料庫的代碼進行封裝,可以直接調用DAO類來擷取到我們需要的對象,而無需考慮資料庫內部的實現。

實體類為:

public class User extends IdEntity {private String name;private String password;private String nickname;private String token;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}public String getToken() {return token;}public void setToken(String token) {this.token = token;}}
UserDAO介面為:

public interface UserDao {/** * 將User儲存至資料庫中 *  * @param connection * @param user */public void save(Connection connection, User user) throws SQLException;/** * 查詢資料庫中是否有對應的UserName,如果有,返回對應id,沒有,返回0 *  * @param connection * @param userName * @return */public int queryUserName(Connection connection, String userName) throws SQLException;/** * 根據User查詢資料庫中相應的id的password是否正確。如果正確,返回對應的id,否則返回0 *  * @param connection * @param user * @return * @throws SQLException */public int queryPassWord(Connection connection, int id, String password) throws SQLException;/** * 向指定Id的User中更新token *  * @param connection * @param userId * @param token * @throws SQLException */public void updateToken(Connection connection, int userId, String token) throws SQLException;/** * 根據token擷取到使用者的id,如果沒有,返回0 * @param connection * @param token * @throws SQLException */public int getUserId(Connection connection,  String token) throws SQLException;}
其相應的實作類別為:

public class UserDaoImplement extends BaseDaoImplement implements UserDao {@Overridepublic void save(Connection connection, User user) throws SQLException {PreparedStatement statement = connection.prepareCall("insert into tal_user (name,password,nickname) values(?,?,?)");statement.setString(1, user.getName());statement.setString(2, user.getPassword());statement.setString(3, user.getNickname());statement.execute();}public int queryUserName(Connection connection, String userName) throws SQLException {PreparedStatement statement = connection.prepareCall("Select * from tal_user where name = ?");statement.setString(1, userName);ResultSet set = statement.executeQuery();// 下一個不為空白,說明資料庫中包含有此欄位,則返回此條資料的idif (set.next()) {return set.getInt("id");} else {return 0;}}@Overridepublic int queryPassWord(Connection connection, int id, String password) throws SQLException {PreparedStatement statement = connection.prepareCall("Select * from tal_user where id = ? and password = ?");statement.setInt(1, id);statement.setString(2, password);ResultSet set = statement.executeQuery();// 下一個不為空白,說明資料庫中包含有此欄位,則返回此條資料的idif (set.next()) {return set.getInt("id");} else {return 0;}}@Overridepublic void updateToken(Connection connection, int userId, String token) throws SQLException {PreparedStatement statement = connection.prepareCall("update tal_user set token =  ? where id = ?");statement.setString(1, token);statement.setInt(2, userId);statement.execute();}@Overridepublic int getUserId(Connection connection, String token) throws SQLException {PreparedStatement statement = connection.prepareCall("select * from tal_user where token = ?");statement.setString(1, token);statement.executeQuery();ResultSet set = statement.executeQuery();if (set.next()) {return set.getInt("id");} else {return 0;}}}
DAO類寫好後,我們就可以書寫邏輯Service類,比如如果我們需要判斷是否有相應的使用者名稱,那麼就應該調用DAO類的queryUserName()方法,如果返回為0,則有相同使用者名稱。

下面為LoginService類源碼:

public class LoginService {private UserDao mUserDao = new UserDaoImplement();private static final int RESULT_NULL_USERNAME = 1,RESULT_WRONG_PASSWORD = 2;public LoginResult login(String userName, String passWord) {Connection connection = null;LoginResult result = new LoginResult();connection = ConnectionFactory.getInstance().makeConnection();try {//1、先判斷是否有相應的使用者名稱int id = mUserDao.queryUserName(connection, userName);if (id == 0) {result.setCode(RESULT_NULL_USERNAME);return result;}//2、在判斷密碼是否正確int userId = mUserDao.queryPassWord(connection, id, passWord);if (userId == 0) {result.setCode(RESULT_WRONG_PASSWORD);return result;}//3、設定相應的tokenlong currentTime  = System.currentTimeMillis();String token = userId+"_"+currentTime;mUserDao.updateToken(connection, userId, token);result.setCode(0);result.setToken(token);return result;} catch (SQLException e) {e.printStackTrace();result.setCode(100);return result;}}}
寫好了 LoginService類之後,我們的服務端代碼就接近完成了,我們還需要做的就是寫一個BaseServlet的子類,然後複寫其onPost()方法,得到請求的參數,然後調用LoginService類擷取返回的參數,進行封裝後使用fastjson解析成json返回即可。

下面為LoginServlet類的源碼:

@WebServlet("/Login")public class LoginServlet extends BaseServlet {private static final long serialVersionUID = 7245361420327420429L;@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String userName = requestJson.getString("uname");String passWord = requestJson.getString("upwd");System.out.println("請求的userName為" + userName + "\n請求的passWord為" + passWord);LoginService service = new LoginService();LoginResult loginResult = service.login(userName, passWord);Map<String, Object> map = new HashMap<>();map.put("result", loginResult.getCode());//如果成功,還需要加上tokenif (loginResult.getCode() == 0) {Map<String, Object> dataMap = new HashMap<>();dataMap.put("token", loginResult.getToken());map.put("data", dataMap);}String result = JSON.toJSONString(map);System.out.println("結果為"+result);PrintWriter printWriter = resp.getWriter();printWriter.write(result);printWriter.close();}}
上面寫出了登陸介面實現的大部分分析,但是還時有一些源碼沒有貼出來,大家可以訪問此連結:   伺服器端代碼github地址  ,來得到和運行伺服器端的源碼。另外 ,Android端的代碼也寫好了登陸、註冊的介面,登陸的功能也已經實現。其地址為   Android端代碼github地址   。歡迎大家star 。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.