需求:
採用前後端分離的方式編寫用於登錄和獲取用戶列表的接口
接口返回的數據類型是json
使用MySQL作爲數據庫,採用C3P0連接池,DBUtils
首先搭建項目基本環境,採用idea來開發。
導入jar包
配置c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- c3p0配置文件 配置數據源 -->
<!-- default-config 默認 -->
<default-config>
<!-- 驅動 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- url -->
<property name="jdbcUrl">jdbc:mysql://localhost:3306/sms</property>
<!-- 用戶名 -->
<property name="user">root</property>
<!-- 密碼 -->
<property name="password">***</property>
</default-config>
<!-- 在這裏是說明可以配置其他的數據庫 與此案例無關named-config 通過名字指定 -->
<named-config name="WusuoWei">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///mydemo</property>
<property name="user">root</property>
<property name="password">***</property>
</named-config>
</c3p0-config>
書寫C3P0Utils工具類
package com.cx.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
/**
*
*/
public class C3P0Utils {
// 定義 ComboPooledDataSource 對象,來使用默認配置
// 因爲 c3p0-config 是默認的名字,如果不寫也是可以的
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 如果 c3p0 管理了多個數據源,除開默認的,其他的需要指定名字纔可以去調用到 p
// rivate static ComboPooledDataSource dataSource = new ComboPooledDataSource("mydemo");
public static DataSource getDatasource(){
return dataSource;
}
}
書寫一個bean類
package com.cx.bean;
/**
*
*/
public class Student {
private Integer id;
private String username;
private String password;
public Student() {
}
public Student(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
Controller層
登錄LoginServlet
package com.cx.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cx.bean.Student;
import com.cx.service.StuService;
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 java.io.IOException;
/**
*
*/
@WebServlet(name = "LoginServlet",urlPatterns = "/loginServlet")
public class LoginServlet extends HttpServlet {
private StuService stuService;
@Override
public void init() throws ServletException {
stuService = new StuService();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決跨域問題,在響應頭中明確指出,對方是可信的
//*表示 允許所有來源的跨域訪問 (測試時用,正式部署需要指定爲靜態資源服務器地址)
// response.setHeader("Access-Control-Allow-Origin","*");
//獲取請求參數
String username = request.getParameter("username");
String password = request.getParameter("password");
Student stu = stuService.checkLogin(username,password);
//創建一個空的json對象
JSONObject jsonObject = new JSONObject();
if (username == "" || username == null || password == "" || password == null){
jsonObject.put("msg","用戶名或密碼爲空");
jsonObject.put("status",-1);
}else if (stu != null){
jsonObject.put("msg","登錄成功");
jsonObject.put("status",1);
}else {
jsonObject.put("msg","登錄失敗");
jsonObject.put("status",0);
}
//告訴客戶端返回值的類型是json
response.setContentType("application/json;charset=utf-8");
//將jsonObject轉成json格式
response.getWriter().print(jsonObject.toJSONString());
}
}
查看所有用戶ListServlet
package com.cx.controller;
import com.alibaba.fastjson.JSONObject;
import com.cx.bean.Student;
import com.cx.service.StuService;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
@WebServlet(name = "ListServlet",urlPatterns = "/listServlet")
public class ListServlet extends HttpServlet {
private StuService stuService;
@Override
public void init() throws ServletException {
stuService = new StuService();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解決跨域問題,在響應頭中明確指出,對方是可信的
//*表示 允許所有來源的跨域訪問 (測試時用,正式部署需要指定爲靜態資源服務器地址)
//response.setHeader("Access-Control-Allow-Origin","*");
//告訴客戶端,返回的是json類型
response.setContentType("application/json;charset=utf-8");
//定義一個空的json對象
JSONObject jsonObject = new JSONObject();
List<Student> list = stuService.selectAll();
response.getWriter().print(jsonObject.toJSONString(list));
}
}
service層
package com.cx.service;
import com.cx.bean.Student;
import com.cx.dao.StuDao;
import java.util.List;
/**
*
*/
public class StuService {
private StuDao stuDao;
public StuService() {
stuDao = new StuDao();
}
public Student checkLogin(String username, String password) {
return stuDao.checkLogin(username,password);
}
public List<Student> selectAll() {
return stuDao.selectAll();
}
}
dao層
package com.cx.dao;
import com.cx.bean.Student;
import com.cx.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException;
import java.util.List;
/**
*
*/
public class StuDao {
//初始化 QueryRunner的時候直接提供 DataSource
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDatasource());
public Student checkLogin(String username, String password) {
//書寫SQL語句
String sql = "select * from student where username=? and password = ?";
//執行SQL語句
try {
// 如果你要查的數據是多個的話,使用 BeanListHandler 來自動封裝即可
// 指定 Student.class 是想 DBUtils 查到數據之後,自動幫我們封裝到 Student 類上
Student student = queryRunner.query(sql,new BeanHandler<Student>(Student.class),username,password);
return student;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<Student> selectAll() {
String sql = "select * from student";
try {
List<Student> list = queryRunner.query(sql, new BeanListHandler<Student>(Student.class));
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
這樣後端的接口就準備好了,運行結果如下:在地址欄輸入http://localhost:8080/qianHouDFL/loginServlet?username=張三&password=123
如果用戶名或密碼有錯則
如果用戶名或密碼爲空
下面準備前端
首先寫查看所有用戶列表
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery-2.1.0.js"></script>
</head>
<body>
<table id="tab" border="1">
<tr>
<th>id</th>
<th>姓名</th>
<th>密碼</th>
</tr>
</table>
<button onclick="req()">請求數據</button>
</body>
<script>
function req(){
$.ajax({
url:"http://localhost:8080/qianHouDFL/listServlet",
success:function(data){
console.log(data)
for (var i = 0; i < data.length; i++) {
a = data[i];
var row = "<tr><td>id</td><td>username</td><td>password</td></tr>"
row = row.replace("id",a.id);
row = row.replace("username",a.username);
row = row.replace("password",a.password);
document.getElementById("tab").insertAdjacentHTML("beforeend",row);
}
},
error:function(err){
console.log(err);
}
});
}
</script>
</html>
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery-2.1.0.js"></script>
</head>
<body>
<form id="fm">
姓名<input type="text" name="username" /><br />
密碼<input type="password" name="password" /><br />
<input type="button" onclick="login()" value="登錄" />
</form>
</body>
<script>
function login(){
$.ajax({
url:"http://localhost:8080/qianHouDFL/loginServlet",
data:$("#fm").serialize(),
success:function(data){
console.log(data)
},
error:function(err){
console.log(err);
}
});
}
</script>
</html>
訪問卻發現報錯。。。。。。
沒錯前後端分離後的常見問題跨域又來了,解決方案很簡單,告訴客戶端是可信的就可以了,但是我們這個小案例中兩個servlet類,可以在裏面加入允許跨域的地址,但是多了比較麻煩,此處使用過濾器
package com.cx.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
/**
*
*/
@WebFilter(urlPatterns = "/*")
public class CROSFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//動態設置 通過代碼獲取origin 判斷要不要允許跨域
//允許跨域的主機地址列表
ArrayList<String> hosts = new ArrayList<>();
hosts.add("http://127.0.0.1:8020");
hosts.add("http://localhost:8020");
HttpServletRequest request = (HttpServletRequest)servletRequest;
//判斷對方是否在允許的範圍
if (hosts.contains(request.getHeader("Origin"))){
//從請求中獲取Origin的值
((HttpServletResponse)servletResponse).setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
運行結果:
登錄:
查看所有用戶
那麼簡單的前後端分離就寫好了,後續還可以加入分頁,MD5加密,CSS樣式