基于javaweb+mysql的springboot博客论坛管理系统(java+springboot+jsp+layui+maven+mysql)(含设计报告)

基于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项目:是;

技术栈

  1. 后端:SpringBoot

  2. 前端:JSP+CSS+JavaScript+LayUI

使用说明

  1. 使用Navicat或者其它工具,在mysql中创建对应名称的数据库,并导入项目的sql文件;

  2. 使用IDEA/Eclipse/MyEclipse导入项目,Eclipse/MyEclipse导入时,若为maven项目请选择maven;

若为maven项目,导入成功后请执行maven clean;maven install命令,然后运行;

  1. 将项目中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", "&nbsp; &nbsp; ");
		}*/

		/**
		 * 缩略字符串(不区分中英文字符)
		 * @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;
		}
	}

}

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

jnu_forum是基于Java论坛系统。前端使用Html+CSS+JS实现,后端使用Java语言开发,技术栈包括但不限于Spring/SpringMVC/SpringBoot、MyBatis、Redis、PageHelper、MySQLMaven等,开发工具为Eclipse。 功能 1、登录和注册 2、(分类)浏览话题 3、发表话题 4、上传照片 5、评论以及评论赞踩 6、站内信通知 7、用户积分排行榜 8、关注和共同关注 主要功能实现 1、登录注册:使用SpringSecurity4框架,即使用已经包装好的接口来实现,简单易用。 2、上传照片:照片是存储在第三方服务器,即七牛云。 3、站内信通知:通过异步队列来实现的站内信通知,其中选择Redis来作为队列。 4、排行榜:排行榜是通过Redis的有序集合来实现的,可以快速实现topK排序。 5、关注和共同关注:通过Redis的集合数据结构实现。 页面展示 1、首页 2、注册 3、登录 4、话题浏览页面 5、话题详情页面与评论 6、个人简介页面 7、发表话题页面 8、站内信页面 9、照片墙页面 10、关注和粉丝界面 10、排行榜界面 备注: 1、本项目的Redis已经换成集群了,本地跑的时候先建立集群,否则自行将集群换成单机Redis,具体修改application.propertie和com.xzp.forum.util.JedisAdapter.java即可(再具体如何修改可以参考提交记录或联系我~) 2、因项目中七牛云过期了,上传的所有照片都失效了,所以项目中有照片的都被和谐了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值