基于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的SpringBoot博客论坛管理系统(java+springboot+jsp+layui+maven+mysql)(含设计报告)
项目介绍
本系统分为管理员、游客两种角色; 管理员角色包含以下功能: 登录,用户增删改查,文章增删改查,链接增删改查,日志查看,查看近期数据,类别管理等功能。 游客角色包含以下功能:
首页,查看文章,注册账号,登录,管理自己写的文章,管理自己的文章,评论文章等功能。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
4.数据库:MySql 5.7版本;
技术栈
-
后端:SpringBoot
-
前端:JSP+CSS+JavaScript+LayUI
使用说明
运行项目,在浏览器中输入http://localhost:8090/ 登录
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
private MailUtil mailUtil;
@Value("${mail.href}")
public String href;
/**
* 重新发送激活邮件
* @param user
* 微博 授权
* @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 "";
}
/**
* 微博 取消授权
* @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 {
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 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inString(String str, String... strs){
if (str != null){
for (String s : strs){
if (str.equals(trim(s))){
return true;
}
}
}
return false;
}
/**
* 替换掉HTML标签方法
*/
public static String replaceHtml(String html) {
if (isBlank(html)){
return "";
}
String regEx = "<.+?>";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(html);
String s = m.replaceAll("");
return s;
}
@Controller
@RequestMapping("/link")
public class LinkController {
@Autowired
private LinkService linkService;
/**
* 跳转到友情链接列表页
* @return
*/
@GetMapping("/list")
@RequiresPermissions("base:link:views")
public String list(){
return Views.LINK_LIST;
}
/**
* 友情链接搜索
* @param page
* @param link
* @return
*/
@PostMapping("/search")
@RequiresPermissions("base:link:views")
@ResponseBody
public Page<Link> search(Page<Link> page,Link link){
return linkService.findPageList(page,link);
}
/**
* 删除友情链接
* @param link
* @return
*/
@PostMapping("/delete")
@RequiresPermissions("base:link:edit")
@ResponseBody
public String delete(Link link){
link.setStatus("1");
linkService.save(link);
return "success";
}
/**
* 批量删除
* @param ids
* @return
}
if (fileStream == null) {
return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
}
String savePath = (String) conf.get("savePath");
String originFileName = fileStream.getName();
String suffix = FileType.getSuffixByFilename(originFileName);
originFileName = originFileName.substring(0,
originFileName.length() - suffix.length());
savePath = savePath + suffix;
long maxSize = ((Long) conf.get("maxSize")).longValue();
if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
}
savePath = PathFormat.parse(savePath, originFileName);
String physicalPath = (String) conf.get("rootPath") + savePath;
InputStream is = fileStream.openStream();
State storageState = StorageManager.saveFileByInputStream(is,
physicalPath, maxSize);
is.close();
if (storageState.isSuccess()) {
storageState.putInfo("url", PathFormat.format(savePath));
storageState.putInfo("type", suffix);
storageState.putInfo("original", originFileName + suffix);
}
return storageState;
} catch (FileUploadException e) {
return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR);
} catch (IOException e) {
}
return new BaseState(false, AppInfo.IO_ERROR);
}
private static boolean validType(String type, String[] allowTypes) {
List<String> list = Arrays.asList(allowTypes);
return list.contains(type);
}
}
public String invoke() {
if ( actionType == null || !ActionMap.mapping.containsKey( actionType ) ) {
return new BaseState( false, AppInfo.INVALID_ACTION ).toJSONString();
}
if ( this.configManager == null || !this.configManager.valid() ) {
return new BaseState( false, AppInfo.CONFIG_ERROR ).toJSONString();
}
State state = null;
int actionCode = ActionMap.getType( this.actionType );
Map<String, Object> conf = null;
switch ( actionCode ) {
case ActionMap.CONFIG:
return this.configManager.getAllConfig().toString();
case ActionMap.UPLOAD_IMAGE:
case ActionMap.UPLOAD_SCRAWL:
case ActionMap.UPLOAD_VIDEO:
case ActionMap.UPLOAD_FILE:
conf = this.configManager.getConfig( actionCode );
state = new Uploader( request, conf ).doExec();
break;
case ActionMap.CATCH_IMAGE:
conf = configManager.getConfig( actionCode );
String[] list = this.request.getParameterValues( (String)conf.get( "fieldName" ) );
state = new ImageHunter( conf ).capture( list );
break;
case ActionMap.LIST_IMAGE:
case ActionMap.LIST_FILE:
conf = configManager.getConfig( actionCode );
int start = this.getStartIndex();
state = new FileManager( conf ).listFile( start );
break;
}
return state.toJSONString();
}
/**
* 日志工具类
*/
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;
private Object handler;
private Exception ex;
public SaveLogThread(Log log, Object handler, Exception ex) {
*/
@PostMapping("/search")
@RequiresPermissions("base:link:views")
@ResponseBody
public Page<Link> search(Page<Link> page,Link link){
return linkService.findPageList(page,link);
}
/**
* 删除友情链接
* @param link
* @return
*/
@PostMapping("/delete")
@RequiresPermissions("base:link:edit")
@ResponseBody
public String delete(Link link){
link.setStatus("1");
linkService.save(link);
return "success";
}
/**
* 批量删除
* @param ids
* @return
*/
@PostMapping("/bathDelete")
@RequiresPermissions("base:link:del")
@ResponseBody
public String bathDelete(@RequestParam("ids[]") String[] ids){
linkService.bathDelete(ids);
return "success";
}
/**
* 更新链接
*/
@RequiresPermissions("base:link:edit")
@PostMapping("/update")
@ResponseBody
public String update(Link link){
linkService.save(link);
return "success";
}
/**
* 添加链接
* @param link
*/
private String getRequestUrl(ServletRequest request) {
HttpServletRequest req = (HttpServletRequest)request;
String queryString = req.getQueryString();
queryString = StringUtils.isBlank(queryString)?"": "?"+queryString;
return req.getRequestURI()+queryString;
}
}
@Controller
public class UploadController {
@PostMapping("/file/upload")
@ResponseBody
public JSONObject uploadImg(@RequestParam("file") MultipartFile file,
HttpServletRequest request) {
String filePath = request.getSession().getServletContext().getRealPath("upload/");
String date=new SimpleDateFormat("yyyyMMdd").format(new Date());
String reName=date+"/"+UUID.randomUUID()+".jpg";
String str="";
try {
File targetFile = new File(filePath+date);
if(!targetFile.exists()){
targetFile.mkdirs();
}
FileOutputStream out = new FileOutputStream(filePath+reName);
out.write(file.getBytes());
out.flush();
out.close();
str=String.format("{code:0,msg:'success',data:{src:'/upload/%s'}}",reName);
} catch (Exception e) {
str="{msg:'接口调用异常'}";
e.printStackTrace();
}
return JSON.parseObject(str);
}
/**
* 替换为手机识别的HTML,去掉样式及属性,保留回车。
* @param html
* @return
*/
public static String replaceMobileHtml(String html){
if (html == null){
return "";
}
return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
}
/**
* 替换为手机识别的HTML,去掉样式及属性,保留回车。
* @param txt
* @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) {
// 保存日志信息
log.preInsert();
logDao.insert(log);
}
}
/**
* 获取菜单名称路径(如:系统设置-机构用户-用户管理-编辑)
*/
public static String getMenuinfoNamePath(String requestUrl, String permission) {
String title=(String) CacheUtils.get(CacheNames.MENU_CACHE,requestUrl+permission);
if (title==null){
Menu menu=new Menu();
menu.setPermission(permission);
menu.setUrl(requestUrl);
title=menuDao.getMenuinfoNamePath(menu);
CacheUtils.put(CacheNames.MENU_CACHE,requestUrl+permission,title);
}
return title;
}
}
/**
* 登录管理页
*/
@Controller
public class LoginController {
@Autowired
private UserService userService;
/**
* 跳转到登录页
*/
case ActionMap.LIST_IMAGE:
case ActionMap.LIST_FILE:
conf = configManager.getConfig( actionCode );
int start = this.getStartIndex();
state = new FileManager( conf ).listFile( start );
break;
}
return state.toJSONString();
}
public int getStartIndex () {
String start = this.request.getParameter( "start" );
try {
return Integer.parseInt( start );
} catch ( Exception e ) {
return 0;
}
}
/**
* callback参数验证
*/
public boolean validCallbackName ( String name ) {
if ( name.matches( "^[a-zA-Z_]+[\\w0-9_]*$" ) ) {
return true;
}
return false;
}
}
}else{
break;
}
}
projectPath = file.toString();
}
} catch (IOException e) {
e.printStackTrace();
}
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();
}
}
* @return
*/
@GetMapping("/register")
public String register(){
return Views.REGISTER;
}
/**
* 注册
* @param user
* @param model
* @return
*/
@PostMapping("/register")
public String addUser(User user, Model model){
User user1 = userService.findByAccount(user.getUsername());
User user2 = userService.findByAccount(user.getEmail());
if(user1==null&&user2==null){
//设置Gravatar图片链接
String gravatarImg = "/static/images/qqtouxiang.jpg";
//设置激活码code
String code = UUID.randomUUID().toString();
user.setAvatar(gravatarImg);
user.setCode(code);
user.setPassword(MD5.md5(user.getUsername(),user.getPassword()));
// user.setStatus(User.STATUS_AUDIT);
// userService.save(user);
// mailUtil.sendHtmlMail(new String[]{user.getEmail()},"hblog账户激活邮件","<h1>请点击<a href='"+href+"activate/"+code+"'>此链接</a>以激活账号</h1>");
// model.addAttribute("msg","٩(๑❛ᴗ❛๑)۶注册成功,激活邮件已经发送到您的邮箱请及时激活!");
user.setStatus(User.STATUS_NORMAL);
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.REGISTER;
}
}
/**
* 用户账号激活
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 accessToken
* @param uid
* @return
* @throws IOException
*/
private String getUserInfo(String accessToken,String uid) throws IOException {
String api = "https://api.weibo.com/2/users/show.json";
Map<String, String> data = new HashMap<String, String>();
data.put("access_token", accessToken);
data.put("uid", uid);
String result = HttpUtil.httpGet(api, data, null);
return result;
}
}
private HttpServletRequest request = null;
private String rootPath = null;
private String contextPath = null;
private String actionType = null;
private ConfigManager configManager = null;
public ActionEnter ( HttpServletRequest request, String rootPath ) {
this.request = request;
this.rootPath = rootPath;
this.actionType = request.getParameter( "action" );
this.contextPath = request.getContextPath();
this.configManager = ConfigManager.getInstance( this.rootPath, this.contextPath, request.getRequestURI() );
}
public String exec () {
String callbackName = this.request.getParameter("callback");
if ( callbackName != null ) {
if ( !validCallbackName( callbackName ) ) {
return new BaseState( false, AppInfo.ILLEGAL ).toJSONString();
}
return callbackName+"("+this.invoke()+");";
} else {
return this.invoke();
}
}
public String invoke() {
if ( actionType == null || !ActionMap.mapping.containsKey( actionType ) ) {
return new BaseState( false, AppInfo.INVALID_ACTION ).toJSONString();
}
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;
}
// 保存日志信息
log.preInsert();
logDao.insert(log);
}
}
/**
* 获取菜单名称路径(如:系统设置-机构用户-用户管理-编辑)
*/
public static String getMenuinfoNamePath(String requestUrl, String permission) {
String title=(String) CacheUtils.get(CacheNames.MENU_CACHE,requestUrl+permission);
if (title==null){
Menu menu=new Menu();
menu.setPermission(permission);
menu.setUrl(requestUrl);
title=menuDao.getMenuinfoNamePath(menu);
CacheUtils.put(CacheNames.MENU_CACHE,requestUrl+permission,title);
}
return title;
}
}






更多推荐

所有评论(0)