无框架开发登录接口
前言:最近在社团里面引导新生怎么去开发后端接口,所以我自己手敲了一个简单的登录接口,通过一个接口例子来演示怎么规范开发一个接口。不使用spring,mabatis等框架,以几乎原始的方式开发,引入几个必须的依赖。代码只给出核心代码,源代码给出网盘链接需要者自取。
首先是创建maven项目,在pom.xml中导入servlet,jdbc,junit,json四个依赖。
<dependencies> <!--测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!--json数据格式--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> </dependencies>
讯享网
在javaweb中,我们使用传统的三层架构,dao,service,controller。dao是与数据库相关的操作,service是与业务相关的操作,controller是与客户端进行交互的操作。
分析客户端与服务端的一次交互:浏览器发起请求,请求参数被封装到httprequest,服务端controller通过httprequest接收到参数,解析参数后,调用service业务,业务对应的dao层关于数据库进行操作,controller层接受业务层的返回结果,通过httpresponse响应json数据到客户端。
因此整个项目架构为
- controller
- service
- dao
- domain 表实体,接受对象和响应对象实体
- util 连接jdbc工具和返回json工具
选择自底向上的模式进行开发登录接口。首先创建数据库和对应用户表
讯享网
CREATE datebase teach_demo; USE teach_demo; CREATE TABLE `user`( `id` INT(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `username` VARCHAR(64) NOT NULL COMMENT '用户名', `password` VARCHAR(64) NOT NULL COMMENT '密码', PRIMARY KEY(`id`), UNIQUE KEY(`username`) )ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO `user` VALUES(NULL,'zhangsan','');第二,创建参数接受对象在domain下
package cn.homyit.domain; public class User { private Long id; private String username; private String password; public User(String username, String password) { this.username = username; this.password = password; } public Long getId() { return id; } public void setId(Long 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; } }第三,创建UserDao接口,并且实现方法

讯享网
package cn.homyit.dao; import cn.homyit.domain.User; /*连接数据库与用户相关*/ public interface UserDao { boolean login(User user) throws Exception; }package cn.homyit.dao.impl; import cn.homyit.dao.UserDao; import cn.homyit.domain.User; import cn.homyit.util.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; /*用户处理数据库实现*/ public class UserDaoImpl implements UserDao { @Override public boolean login(User user) throws Exception { boolean flag = false; Connection conn = JDBCUtil.getConnection(); String sql = "select * from user where username =? and password=?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, user.getUsername()); ps.setString(2, user.getPassword()); ResultSet rs = ps.executeQuery(); if(rs.next()){ flag = true; } return flag; } }连接数据库时我们使用JDBCUtil
讯享网
package cn.homyit.util; import java.sql.*; / * 数据库连接工具类 */ public class JDBCUtil { private static String URL = "jdbc:mysql://localhost:3306/teach_demo?" + "useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimeZone=Asia/Shanghai"; private static String USERNAME = "root"; private static String PASSWORD = ""; private static Connection connection = null; private static PreparedStatement statement = null; private static ResultSet resultSet = null; public static Connection getConnection() throws Exception { Class.forName("com.mysql.jdbc.Driver"); return DriverManager.getConnection(URL, USERNAME, PASSWORD); } public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) { try { if (resultSet != null) { resultSet.close(); } if (statement != null) { statement.close(); } if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } }第四,测试我们的实现方法是否符合我们的预期,在src下创建一个test文件夹,创建对应的包和类
import cn.homyit.domain.User; import org.junit.Test; public class UserDaoTest { @Test public void testLogin() throws Exception { UserDao userDao = new UserDaoImpl(); boolean flag = userDao.login(new User("zhangsan", "")); System.out.println(flag); } }第五,创建service类和实现
讯享网
package cn.homyit.service; import cn.homyit.domain.User; /*业务接口*/ public interface UserService { boolean login(User user) throws Exception; }package cn.homyit.service.impl; import cn.homyit.dao.UserDao; import cn.homyit.dao.impl.UserDaoImpl; import cn.homyit.domain.User; import cn.homyit.service.UserService; / * @author 州牧 * @description 业务实现 * @since 2022-04-24 19:57 */ public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); @Override public boolean login(User user) throws Exception { // int i = 1/0; return userDao.login(user); } }第六,创建cotroller,我们导入的依赖为javax.servlet-api,其中有注解的实现,我们选择注解来注册访问路径而不是再使用web.xml。登录为了安全我们使用的是dopost方法。我这里还做了简单的异常处理,这是需要做的,为了给用户更好的体验。
讯享网
package cn.homyit.controller; import cn.homyit.domain.Result; import cn.homyit.domain.User; import cn.homyit.service.UserService; import cn.homyit.service.impl.UserServiceImpl; import cn.homyit.util.JSONUtil; 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 javax.servlet.http.HttpSession; import java.io.IOException; / * @author 州牧 * @description 登录 * @since 2022-04-24 19:59 */ @WebServlet("/user/login") public class LoginServlet extends HttpServlet { private UserService userService = new UserServiceImpl(); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String password = req.getParameter("password"); User user = new User(username, password); Result result = new Result(); try { boolean flag = userService.login(user); if(flag ==true){ result.setCode(200); result.setMsg("登录成功"); //服务端记录登录状态 HttpSession session = req.getSession(); session.setAttribute("USER",user); }else { result.setCode(201); result.setMsg("登录失败,用户名或密码错误"); } JSONUtil.returnJSON(resp,result); } catch (Exception e) { result.setCode(500); result.setMsg("服务器出错,请联系管理员"); JSONUtil.returnJSON(resp,result); e.printStackTrace(); } } }其中前后端交互中,后端返回数据以json格式返回,我们使用下面这个工具类
package cn.homyit.util; import cn.homyit.domain.Result; import com.alibaba.fastjson.JSONObject; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; / * @author 州牧 * @description 响应浏览器 * @since 2022-04-24 20:07 */ public class JSONUtil { public static void returnJSON(HttpServletResponse resp, Result result) throws IOException { PrintWriter writer = resp.getWriter(); JSONObject jsonObject = new JSONObject(); jsonObject.put("code",result.getCode()); jsonObject.put("msg",result.getMsg()); jsonObject.put("data",result.getData()); writer.print(jsonObject); writer.close(); } }但是呢,响应有时候需要一个返回的数据对象而不是只有状态码和提示信息,因此我们创建一个返回对象,对象中使用一个数据对象的泛型。
讯享网
package cn.homyit.domain; / * @author 州牧 * @description 返回对象实体 * * @since 2022-04-24 20:08 */ public class Result<T> { private int code; private String msg; private T data; public Result() { } public Result(int code, String msg) { this.code = code; this.msg = msg; } public Result(int code, String msg, T data) { this.code = code; this.msg = msg; this.data = data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } }第七,配置tomcat和默认项目路径,使用postman测试该接口

测试发现呢,返回的信息中文为乱码,因此我们需要设置响应的编码。我们可以在每一个servlet中设置编码,但是这是一个重复性操作,所以我们这里使用过滤器来实现这个功能。使用webfilter设置过滤路径,编码的过滤当然是所有请求和响应都过滤。
package cn.homyit.fliter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; / * @author 州牧 * @description 设置编码 * @since 2022-04-24 20:22 */ @WebFilter("/*") public class MyFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException {
} @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=UTF-8"); chain.doFilter(req,resp);//放行 } @Override public void destroy() {
} }
再次启动,我们可得

综上,一个简单的登录接口就完成了。
此外,我们可以使用Filter过滤些需要用户登录的访问路径,以session或cookie保持用户的登录的状态。可以自定义异常处理,来返回一些业务异常信息,这使得这个项目更加完善。这里不再补充。
源码在网盘中,需要自取。
讯享网链接:https://pan.baidu.com/s/1tMyrW1k9_-Ha20B3XZD39w 提取码:zhou



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/57496.html