一、基于Servlet项目的基本框架
如图所示:
二、基于Servlet项目的具体操作
1、建立数据库连接:使用JDBC连接数据库。加载数据库驱动程序,建立与数据库的连接,获取连接对象。
2、插入数据:在Servlet中处理插入数据的请求。获取请求参数,创建一个包含插入语句的PreparedStatement对象,并设置参数,然后执行插入操作。
3、查询数据:在Servlet中处理查询数据的请求。获取请求参数,创建一个包含查询语句的PreparedStatement对象,并设置参数,然后执行查询操作。通过ResultSet对象获取查询结果。
4、更新数据:在Servlet中处理更新数据的请求。获取请求参数,创建一个包含更新语句的PreparedStatement对象,并设置参数,然后执行更新操作。
5、删除数据:在Servlet中处理删除数据的请求。获取请求参数,创建一个包含删除语句的PreparedStatement对象,并设置参数,然后执行删除操作。
6、返回结果:将查询结果或操作结果返回给客户端,可以使用PrintWriter对象将结果输出到响应流中。
7、关闭连接:在完成对数据库的操作后,记得关闭连接,释放资源。关闭Statement、PreparedStatement和ResultSet对象,最后关闭连接对象。
三、SQL注入问题
当SQL语句由字符串拼接而成时,条件后面加上or true,就会发生SQL注入。
如:username = " a ' or ' 1 = 1 ' ",这样就会使结果恒为true。为了避免这样的情况,可以使用更加强大的statement的子类preparedstatement。
preparedstatement的优势有:
1、提前传入sql,执行的时候不传sql
2、支持传入sql中的参数
3、解决sql注入逻辑漏洞
4、提高执行效率
例如:
public static int update(String sql, Object... params) {
try {
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/summer-camp2023?characterEncoding=utf8", "root", "123456");
//需要创建statement
PreparedStatement statement = con.prepareStatement(sql);
//在执行前,给sql传递参数
for (int i = 0; i < params.length; i++) {
statement.setObject(i + 1, params[i]);
}
//statement执行sql,返回结果集
int i = statement.executeUpdate(sql);
//关闭资源
statement.close();
con.close();
return i;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
//测试登录
@Test
public void testLogin() {
String username = "cc ' or '1'='1";
String password = "cc ' or '1'='1";
User user = selectRow("select * from t_users where username=? and password= ?", User.class, username, password);
System.out.println(user != null ? "登录成功" : "登录失败");
}
四、用Vue和Servlet实现前后端分离项目
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/vue/vue.min.js"></script>
<script src="/vue/axios.min.js"></script>
</head>
<body>
<div id="app">
<button @click="showDept">点击显示数据</button>
<table border="1" cellpadding="20" cellspacing="0">
<tr>
<th>序号</th>
<th>部门名称</th>
<th>部门位置</th>
<th>部门领导</th>
</tr>
<tr v-for="dept in deptList">
<td>{{dept.did}}</td>
<td>{{dept.dname}}</td>
<td>{{dept.dlocation}}</td>
<td>{{dept.leader}}</td>
</tr>
</table>
</div>
</body>
<script>
new Vue({
el:'#app',
data:{
deptList:[]
},
methods:{
showDept(){
axios.get('http://localhost:8080/deptC').then((resp)=>{
console.log(resp,resp.data)
this.deptList=resp.data
})
}
}
})
</script>
</html>
后端主要代码:
//每一个类,继承HttpServlet,该类就是一个Servlet,每一个Servlet都有一个访问路径
@WebServlet("/deptC")
public class DeptC extends HttpServlet {
//引用service层
private IDeptService deptService=new DeptServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Dept> list=deptService.list();
System.out.println(list);
//数据转化成json格式,再相应给浏览器
JsonUtil.transJson(list,resp);
}
}
public static void transJson(Object obj, HttpServletResponse resp){
try{
//数据转化成json格式,再相应给浏览器
String json_string= JSON.toJSONString(obj);
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write(json_string);
}catch (Exception e){
e.printStackTrace();
}
}
效果如下:
总结:
前后端可以分离开发,提高团队协作效率。前端负责UI设计和交互逻辑,后端负责业务逻辑和数据处理。通过API接口的方式进行通信,实现了前后端的解耦。总而言之,使用Vue.js和Servlet结合开发,可以构建出高效、可维护的前后端分离应用,提供良好的用户体验和高性能的数据处理能力。