前端:
LayuiAdmin+Jquery
后端:
Servlet+Jdbc
数据库:
Mysql
开发工具:
Idea+VSCode
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter("/*")
public class MyCustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CustomFilter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 统一全站编码
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
HttpServletRequest request = (HttpServletRequest) servletRequest;
// 设置允许跨域的域名,可以根据需要进行修改
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
// 处理预检请求
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {
System.out.println("CustomFilter destroy");
}
}
import com.fasterxml.jackson.databind.ObjectMapper;
import com.renli.utils.ApiResult;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String operation = req.getParameter("operation");
Method[] methods = this.getClass().getDeclaredMethods();
boolean invoked = false;
for (Method method : methods) {
if (method.getName().equals(operation)) {
try {
method.invoke(this, req, resp);
} catch (Exception e) {
Throwable rootCause = findRootCause(e);
if (rootCause != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
rootCause.printStackTrace(pw);
String stackTrace = sw.toString();
System.err.println(stackTrace);
sendJsonResponse(resp, new ApiResult<>(500, "乱搞个鸡8、草泥马 error了。", stackTrace));
}
}
invoked = true;
}
}
if (!invoked) {
sendJsonResponse(resp, new ApiResult<>(500, "别tm乱访问,未指定operation或没有该方法。", null));
}
}
private Throwable findRootCause(Throwable throwable) {
Throwable rootCause = throwable;
while (rootCause.getCause() != null) {
rootCause = rootCause.getCause();
}
return rootCause;
}
// 响应json
protected static void sendJsonResponse(HttpServletResponse response, Object responseObject) throws IOException {
// 使用 ObjectMapper 将 Java 对象转换为 JSON 字符串
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(responseObject);
// 设置响应的内容类型为 "application/json"
response.setContentType("application/json");
// 将 JSON 字符串作为响应的内容写入输出流
PrintWriter out = response.getWriter();
out.print(json);
out.flush();
}
}
前端:
openlived 或者nginx
后端:
tomcat
该注解用于忽略json串中冗余字段
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Timestamp joinDate;
db中使用:datetime类型 ,Java实体类使用:Timestamp (能直接接收前端的yyyy-MM-dd HH:mm:ss格式类型)
private static Object execute(String sql, Object... params) throws SQLException {
Connection connection = getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i + 1, params[i]);
}
// 根据SQL语句中的关键字来确定操作类型
boolean isSelectQuery = sql.trim().toLowerCase().startsWith("select");
// 记录日志
if (isSelectQuery) {
logger.info("Executing SQL query: {}", sql);
return preparedStatement.executeQuery();
} else {
logger.info("Executing SQL update: {}", sql);
int rowsAffected = preparedStatement.executeUpdate();
// 如果需要获取生成的主键等信息,可以在这里添加代码
return rowsAffected;
}
}
html代码:
js代码:
layui.use(['form'], function () {
var form = layui.form,
layer = layui.layer,
$ = layui.$;
var laydate = layui.laydate;
// 渲染日期选择组件
laydate.render({
elem: '#joinDate', // 绑定到指定的input元素
type: 'date', // 设置日期类型,可选值:year、month、date、time、datetime
format: 'yyyy-MM-dd HH:mm:ss', // 设置日期格式
// 其他配置项,可根据需求自行设置
});
});
特别说明:时间回显,先把时间组件渲染出来、再通过form.val() 即可正确回显。
html代码:
<div class="layui-form-item">
<label class="layui-form-label">部门label>
<div class="layui-input-inline">
<select id="departmentSelect" name="department" lay-verify="required">
select>
div>
div>
js代码:
layui.use(['form'], function () {
var form = layui.form,
layer = layui.layer,
$ = layui.$;
// 使用Ajax请求获取部门数据
$.ajax({
type: 'GET',
url: 'http://localhost:8080/api/job_position?operation=getAllJobPositions',
dataType: 'json',
success: function (response) {
console.log(response.data)
if (response.code === 0) {
var jobPositions = response.data; // 假设响应中的数据字段名为data
// 获取下拉列表的 DOM 元素
var departmentSelect = document.getElementById('departmentSelect');
// 遍历响应数据,创建选项并添加到下拉列表中
for (var i = 0; i < jobPositions.length; i++) {
var option = document.createElement('option');
option.value = jobPositions[i].department;
option.text = jobPositions[i].department; // 假设部门名称字段名为positionName
departmentSelect.appendChild(option);
}
// 使用layui的form模块重新渲染下拉列表
form.render('select');
} else {
// 请求失败,处理错误情况
console.error('请求失败:' + response.msg);
}
},
error: function (error) {
// 请求出错,处理错误情况
console.error('请求出错:' + JSON.stringify(error));
}
});
});
下拉框回显方案,核心代码如下: (得先ajax获取下拉框内容,设置 $(‘#departmentSelect’).val()之后、再渲染方可正常回显。)
//接参,回填form表单
form.getFormVal = function (rowdata) {
//可以写其他业务请求。
var data1 = JSON.parse(rowdata);
console.log(data1)
// 数据回填
form.val("editForm", data1);
// 图片回显
// 检查输入框是否有值
var imageUrl = $('#avatarUpload').val();
if (imageUrl) {
// 如果有值,将其回填到的src属性中
$('#avatarPreview').attr('src', imageUrl);
}
var inputValue = data1.department;
// 使用Ajax请求获取部门数据
$.ajax({
type: 'GET',
url: 'http://localhost:8080/api/job_position?operation=getAllJobPositions',
dataType: 'json',
success: function (response) {
if (response.code === 0) {
var jobPositions = response.data; // 假设响应中的数据字段名为data
// 获取下拉列表的 DOM 元素
var departmentSelect = document.getElementById('departmentSelect');
// 遍历响应数据,创建选项并添加到下拉列表中
for (var i = 0; i < jobPositions.length; i++) {
var option = document.createElement('option');
option.value = jobPositions[i].department; //
option.text = jobPositions[i].department; // 假设部门名称字段名为positionName
departmentSelect.appendChild(option);
}
// 设置下拉框的值为 input 的值
$('#departmentSelect').val(inputValue);
// 使用 layui 的 form 模块重新渲染下拉框,以便选项生效
layui.use(['form'], function () {
var form = layui.form;
form.render('select');
});
} else {
// 请求失败,处理错误情况
console.error('请求失败:' + response.msg);
}
},
error: function (error) {
// 请求出错,处理错误情况
console.error('请求出错:' + JSON.stringify(error));
}
});
}
时间组件,下拉框回显完整代码如下:
layui