基于javaweb+mysql的springboot博客论坛管理系统(java+springboot+jsp+layui+maven+mysql)(含设计报告)
运行环境
Java≥8、MySQL≥5.7
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的SpringBoot博客论坛管理系统(java+springboot+jsp+layui+maven+mysql)(含设计报告)
项目介绍
本系统分为管理员、游客两种角色; 管理员角色包含以下功能: 登录,用户增删改查,文章增删改查,链接增删改查,日志查看,查看近期数据,类别管理等功能。 游客角色包含以下功能:
首页,查看文章,注册账号,登录,管理自己写的文章,管理自己的文章,评论文章等功能。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
5.数据库:MySql 5.7版本;
6.是否Maven项目:是;
技术栈
-
后端:SpringBoot
-
前端:JSP+CSS+JavaScript+LayUI
使用说明
-
使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;
-
使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;
若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;
- 将项目中application.yml配置文件中的数据库配置改为自己的配置; 4. 运行项目,在浏览器中输入http://localhost:8090/ 登录
* @return
*/
/* public static String toHtml(String txt){
if (txt == null){
return "";
}
return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", " ");
}*/
/**
* 缩略字符串(不区分中英文字符)
* @param str 目标字符串
* @param length 截取长度
* @return
*/
public static String abbr(String str, int length) {
if (str == null) {
return "";
}
try {
StringBuilder sb = new StringBuilder();
int currentLength = 0;
for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
currentLength += String.valueOf(c).getBytes("GBK").length;
if (currentLength <= length - 3) {
sb.append(c);
} else {
sb.append("...");
break;
}
}
return sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
public static String abbr2(String param, int length) {
if (param == null) {
return "";
}
StringBuffer result = new StringBuffer();
int n = 0;
char temp;
boolean isCode = false; // 是不是HTML代码
*/
private UserInfo getUserInfo(String accessToken,String openId) throws IOException {
String api = "https://graph.qq.com/user/get_user_info";
Map<String, String> data = new HashMap<String, String>();
data.put("access_token", accessToken);
data.put("oauth_consumer_key", APP_ID);
data.put("openid", openId);
String result = HttpUtil.httpGet(api, data, null);
JSONObject jsonObject = JSONObject.parseObject(result);
UserInfo userInfo = JSONObject.parseObject(result,UserInfo.class);
String figureurl = jsonObject.getString("figureurl_qq_1");
userInfo.setAvatar(figureurl);
return userInfo;
}
}
@Controller
public class UserController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Autowired
}
/**
* 搜索用户
* @param pages
* @param user
* @return
*/
@RequiresPermissions("base:user:views")
@PostMapping("/user/search")
@ResponseBody
public Page<User> search(Page<User> pages,User user){
return userService.findPageList(pages,user);
}
/**
* 删除用户
* @param user
* @return
*/
@RequiresPermissions("base:user:del")
@PostMapping("/user/delete")
@ResponseBody
public String delete(User user){
user.setStatus("1");
userService.save(user);
return "success";
}
/**
* 更新用户
* @param user
* @return
*/
@RequiresPermissions("base:user:edit")
@PostMapping("/user/update")
@ResponseBody
public String update(User user,@RequestParam("roleIds[]") String[] roleIds){
if(StringUtils.isNotBlank(user.getPassword())){
user.setPassword(MD5.md5(user.getUsername(),user.getPassword()));
userService.save(user);
}
roleService.updateUserRole(user.getId(),roleIds);
return "success";
}
String remoteAddr = request.getHeader("X-Real-IP");
if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("X-Forwarded-For");
}else if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("Proxy-Client-IP");
}else if (isNotBlank(remoteAddr)) {
remoteAddr = request.getHeader("WL-Proxy-Client-IP");
}
return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
}
/**
* 驼峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCamelCase(String s) {
if (s == null) {
return null;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 驼峰命名法工具
* @return
* toCamelCase("hello_world") == "helloWorld"
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
* toUnderScoreCase("helloWorld") = "hello_world"
*/
public static String toCapitalizeCamelCase(String s) {
public class StringUtils extends org.apache.commons.lang3.StringUtils {
private static final char SEPARATOR = '_';
private static final String CHARSET_NAME = "UTF-8";
/**
* 转换为字节数组
* @param str
* @return
*/
public static byte[] getBytes(String str){
if (str != null){
try {
return str.getBytes(CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return null;
}
}else{
return null;
}
}
/**
* 转换为字节数组
*/
public static String toString(byte[] bytes){
try {
return new String(bytes, CHARSET_NAME);
} catch (UnsupportedEncodingException e) {
return EMPTY;
}
}
/**
* 是否包含字符串
* @param str 验证字符串
/**
* 日志工具类
*/
public class LogUtils {
private static LogDao logDao = SpringContextHolder.getBean(LogDao.class);
private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
/**
* 保存日志
*/
public static void saveLog(HttpServletRequest request, String title) {
saveLog(request, null, null, title);
}
/**
* 保存日志
*/
public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title) {
User Userinfo = UserUtils.getUser();
if (Userinfo.getId() != 0) {
Log log = new Log();
log.setTitle(title);
log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);
log.setRemoteAddr(StringUtils.getRemoteAddr(request));
log.setUserAgent(request.getHeader("user-agent"));
log.setRequestUrl(request.getRequestURI());
log.setParams(request.getParameterMap());
log.setMethod(request.getMethod());
// 异步保存日志
new SaveLogThread(log, handler, ex).start();
}
}
/**
* 保存日志线程
*/
public static class SaveLogThread extends Thread {
private Log log;
/**
* 登录验证
*
* @param user
* @param map
* @return
*/
@PostMapping("/login")
public String login(User user, ModelMap map) {
if (user != null) {
if (StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) {
return Views.LOGIN;
}
AuthenticationToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword(), true);
if (token == null) {
map.put("message", "用户名或密码错误");
return Views.LOGIN;
}
//记住我
((UsernamePasswordToken) token).setRememberMe(true);
try {
SecurityUtils.getSubject().login(token);
return Views.REDIRECT_ADMIN;
} catch (AuthenticationException e) {
if (e instanceof UnknownAccountException) {
map.put("message", "用户不存在");
} else if (e instanceof LockedAccountException) {
map.put("message", "账户未激活");
map.put("status", 2);
map.put("user", user);
} else if (e instanceof DisabledAccountException) {
map.put("message", "账户未启用");
}
e.printStackTrace();
map.put("message", "用户认证失败");
}
return Views.LOGIN;
} else {
map.put("message", "未知异常");
return Views.LOGIN;
}
}
/**
* 安卓端登录
*
* @param user
* @return
*/
@PostMapping("/loginAndroid")
// 异步保存日志
new SaveLogThread(log, handler, ex).start();
}
}
/**
* 保存日志线程
*/
public static class SaveLogThread extends Thread {
private Log log;
private Object handler;
private Exception ex;
public SaveLogThread(Log log, Object handler, Exception ex) {
super(SaveLogThread.class.getSimpleName());
this.log = log;
this.handler = handler;
this.ex = ex;
}
@Override
public void run() {
// 获取日志标题
if (StringUtils.isBlank(log.getTitle())) {
String permission = "";
if (handler instanceof HandlerMethod) {
Method m = ((HandlerMethod) handler).getMethod();
RequiresPermissions rp = m.getAnnotation(RequiresPermissions.class);
permission = (rp != null ? StringUtils.join(rp.value(), ",") : "");
}
log.setTitle(getMenuinfoNamePath(log.getRequestUrl(), permission));
}
// 如果有异常,设置异常信息
if (ex == null) {
log.setException("");
} else {
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
log.setException(stringWriter.toString());
}
// 如果无标题并无异常日志,则不保存信息
if (StringUtils.isBlank(log.getTitle()) && StringUtils.isBlank(log.getException())) {
return "success";
}
/**
* 根据id获取用户
* @param id
* @return
*/
@RequiresPermissions("base:user:views")
@PostMapping("/user/read")
@ResponseBody
public User read(@RequestParam("id") int id){
return UserUtils.get(id);
}
/**
* 批量删除用户
* @param ids
* @return
*/
@RequiresPermissions("base:user:del")
@PostMapping("/user/batchDelete")
@ResponseBody
public String batchDelete(@RequestParam("ids[]") String[] ids){
userService.batchDelete(ids);
return "success";
}
/**
* 跳转到用户添加页
* @param model
* @return
*/
@RequiresPermissions("base:user:views")
@GetMapping("/user/add")
public String add(Model model){
model.addAttribute("roles",roleService.findRole(null));
return Views.USER_ADD;
}
/**
* 通过用户名查找用户
* @param username
* @return
/**
* 跳转到用户添加页
* @param model
* @return
*/
@RequiresPermissions("base:user:views")
@GetMapping("/user/add")
public String add(Model model){
model.addAttribute("roles",roleService.findRole(null));
return Views.USER_ADD;
}
/**
* 通过用户名查找用户
* @param username
* @return
*/
@RequiresPermissions("base:user:views")
@PostMapping("/user/findCount")
@ResponseBody
public String findByCount(@RequestParam("username") String username){
User user=userService.findByAccount(username);
if(user!=null){
return "false";
}
return "true";
}
/**
* 添加用户
* @param user
* @param role
* @return
*/
@RequiresPermissions("base:user:edit")
@PostMapping("/user/add")
@ResponseBody
public String add(User user,@RequestParam("userRoles[]")String[] role){
user.setPassword(MD5.md5(user.getUsername(),user.getPassword()));
user.setStatus("0");
user.setAvatar("/static/images/photo.jpg");
userService.save(user);
//添加权限
roleService.insertUserRole(user.getId(),role);
return "ture";
}
}
private static LogDao logDao = SpringContextHolder.getBean(LogDao.class);
private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
/**
* 保存日志
*/
public static void saveLog(HttpServletRequest request, String title) {
saveLog(request, null, null, title);
}
/**
* 保存日志
*/
public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title) {
User Userinfo = UserUtils.getUser();
if (Userinfo.getId() != 0) {
Log log = new Log();
log.setTitle(title);
log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);
log.setRemoteAddr(StringUtils.getRemoteAddr(request));
log.setUserAgent(request.getHeader("user-agent"));
log.setRequestUrl(request.getRequestURI());
log.setParams(request.getParameterMap());
log.setMethod(request.getMethod());
// 异步保存日志
new SaveLogThread(log, handler, ex).start();
}
}
/**
* 保存日志线程
*/
public static class SaveLogThread extends Thread {
private Log log;
private Object handler;
private Exception ex;
public SaveLogThread(Log log, Object handler, Exception ex) {
super(SaveLogThread.class.getSimpleName());
this.log = log;
public String index(){
try {
StringBuffer authUrl = new StringBuffer(GET_CODE_URL);
authUrl.append("?client_id=" + APP_ID);
authUrl.append("&redirect_uri=" + URLEncoder.encode(loginCallback, "utf-8"));
authUrl.append("&response_type=code");
authUrl.append("&state="+"Test");
return ("redirect:" + authUrl);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
/**
* 微博 授权
* @return
*/
@RequestMapping("/authLoginCallback")
public String authLoginCallback(HttpServletRequest request){
try {
String state = request.getParameter("state");
String code = request.getParameter("code");
String api = "https://api.weibo.com/oauth2/access_token";
Map<String, String> data = new HashMap<String, String>();
data.put("client_id", APP_ID);
data.put("client_secret", APP_KEY);
data.put("code", code);
data.put("grant_type", "authorization_code");
data.put("redirect_uri", loginCallback);
String result = HttpUtil.httpPostByKeyValue(api, data, null);
JSONObject tokenInfo = JSONObject.parseObject(result);
result = getUserInfo(tokenInfo.getString("access_token"),tokenInfo.getString("uid"));
System.out.println(result);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* 跳转到用户列表页
*/
@RequiresPermissions("base:user:views")
@GetMapping("/user/list")
public String list(Model model){
model.addAttribute("roleList", JSONArray.toJSON(roleService.findRole(null)));
return Views.USER_LIST;
}
/**
* 搜索用户
* @param pages
* @param user
* @return
*/
@RequiresPermissions("base:user:views")
@PostMapping("/user/search")
@ResponseBody
public Page<User> search(Page<User> pages,User user){
return userService.findPageList(pages,user);
}
/**
* 删除用户
* @param user
* @return
*/
@RequiresPermissions("base:user:del")
@PostMapping("/user/delete")
@ResponseBody
public String delete(User user){
user.setStatus("1");
userService.save(user);
return "success";
}
/**
* 更新用户
* @param user
* @return
*/
@RequiresPermissions("base:user:edit")
@PostMapping("/user/update")
@ResponseBody
public String update(User user,@RequestParam("roleIds[]") String[] roleIds){
if(StringUtils.isNotBlank(user.getPassword())){
user.setPassword(MD5.md5(user.getUsername(),user.getPassword()));
userService.save(user);
}
roleService.updateUserRole(user.getId(),roleIds);
return "success";
/**
* 前台管理类
*/
@Controller
public class IndexController {
@Autowired
private NewsService newsService;
@Autowired
private LinkService linkService;
@Autowired
private CommentService commentService;
/**
* 跳转到首页
* @param model
* @param page
* @return
*/
@GetMapping({"/","/index"})
public String index(Model model, Page<News> page){
model.addAttribute("typeList",newsService.findTypeList());
Page<News> page1=newsService.findPageList(page,new News());
model.addAttribute("page",page1);
model.addAttribute("links",linkService.findList(null));
return Views.INDEX;
}
/**
* 跳转到二级页面
* @param model
* @return
*/
@GetMapping("/second/{typeId}")
public String second(Model model,@PathVariable("typeId")Integer typeId,Page<News> page){
News news=new News();
news.setTypeId(typeId);
model.addAttribute("typeList",newsService.findTypeList());
model.addAttribute("typeId",typeId);
model.addAttribute("page",newsService.findPageList(page,news));
return Views.SECOND;
}
/**
}
return projectPath;
}
/**
* 如果不为空,则设置值
* @param target
* @param source
*/
public static void setValueIfNotBlank(String target, String source) {
if (isNotBlank(source)){
target = source;
}
}
/**
* 转换为JS获取对象值,生成三目运算返回结果
* @param objectString 对象串
* 例如:row.user.id
* 返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
*/
public static String jsGetVal(String objectString){
StringBuilder result = new StringBuilder();
StringBuilder val = new StringBuilder();
String[] vals = split(objectString, ".");
for (int i=0; i<vals.length; i++){
val.append("." + vals[i]);
result.append("!"+(val.substring(1))+"?'':");
}
result.append(val.substring(1));
return result.toString();
}
}
@RequestMapping("/authLoginCallback")
public String authLoginCallback(HttpServletRequest request){
try {
String state = request.getParameter("state");
String code = request.getParameter("code");
String api = "https://api.weibo.com/oauth2/access_token";
Map<String, String> data = new HashMap<String, String>();
data.put("client_id", APP_ID);
data.put("client_secret", APP_KEY);
data.put("code", code);
data.put("grant_type", "authorization_code");
data.put("redirect_uri", loginCallback);
String result = HttpUtil.httpPostByKeyValue(api, data, null);
JSONObject tokenInfo = JSONObject.parseObject(result);
result = getUserInfo(tokenInfo.getString("access_token"),tokenInfo.getString("uid"));
System.out.println(result);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* 微博 取消授权
* @return
*/
@RequestMapping("/authReduceCallback")
public String authReduceCallback(HttpServletRequest request){
String state = request.getParameter("state");
String code = request.getParameter("code");
String api = "https://graph.qq.com/oauth2.0/token";
Map<String, String> data = new HashMap<String, String>();
data.put("client_id", APP_ID);
data.put("client_secret", APP_KEY);
data.put("code", code);
data.put("grant_type", "authorization_code");
data.put("redirect_uri", loginCallback);
String result = null;
try {
result = HttpUtil.httpPostByKeyValue(api, data, null);
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
}
/**
* 用户账号激活
* @param code
* @param model
* @return
*/
@GetMapping("/activate/{code}")
public String activateUser(@PathVariable("code") String code,
Model model){
User user =userService.getUserByCode(code);
if(user!=null){
user.setStatus("0");
user.setCode("0");
userService.save(user);
String[] roleIds={"1","5"};
roleService.insertUserRole(user.getId(),roleIds);
model.addAttribute("msg","٩(๑❛ᴗ❛๑)۶账号激活成功!");
return Views.SUCCESS;
}else{
model.addAttribute("msg","o(╥﹏╥)o账号激活码不存在!");
return Views.ERROR;
}
}
}