基于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
*/
@ResponseBody
public List<Type> newsList(){
return newsService.findTypeList();
}
}
package com.baidu.ueditor;
public class ActionEnter {
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 class ActionEnter {
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 {
*/
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代码
boolean isHTML = false; // 是不是HTML特殊字符,如
for (int i = 0; i < param.length(); i++) {
temp = param.charAt(i);
if (temp == '<') {
isCode = true;
} else if (temp == '&') {
isHTML = true;
} else if (temp == '>' && isCode) {
n = n - 1;
isCode = false;
} else if (temp == ';' && isHTML) {
isHTML = false;
}
try {
if (!isCode && !isHTML) {
n += String.valueOf(temp).getBytes("GBK").length;
}
} catch (UnsupportedEncodingException e) {
* @return
*/
@RequestMapping("/qqLogin")
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 "";
}
/**
* qq回调 applications over the unaudited use restrictions
* @return
*/
@RequestMapping("/afterlogin")
public String afterlogin(HttpServletRequest request){
// state 用户携带的信息
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.httpGet(api, data, null);
Map<String,Object> map = stringToMap(result);
if (result != null) {
// 获取用户的openId
result = getMemberInfo(map.get("access_token").toString());
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);
}
}
package com.ruixin.controller;
@Controller
@RequestMapping("/link")
public class LinkController {
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
*/
@GetMapping("/font/test")
public String test(){
System.out.println("跳进测试的页面");
return Views.TEXT_PAGE;
}
/**
* 跳转到三级页面
* @param model
* @param id
* @return
*/
@GetMapping("/third/{id}")
public String third(Model model, @PathVariable("id")int id, Page<Comment> page){
//加载内容
model.addAttribute("typeList",newsService.findTypeList());
News news=newsService.get(id);
model.addAttribute("news",news);
news.setRead(String.valueOf(Integer.parseInt(news.getRead())+1));
newsService.save(news);
//加载评论
Page<Comment> commentPage=commentService.getFindId(page,new Comment(),id);
model.addAttribute("commentPage",commentPage);
return Views.THIRD;
* 添加链接
* @param link
* @return
*/
@PostMapping("/add")
@RequiresPermissions("base:link:edit")
@ResponseBody
public String add(Link link){
linkService.save(link);
return "success";
}
/**
* 跳转到链接添加页
*/
@GetMapping("/add")
@RequiresPermissions("base:link:views")
public String add(){
return Views.LINK_ADD;
}
}
package com.ruixin.controller;
/**
* 测试邮件发送
*/
@RestController
public class TestMailController {
@Autowired
private MailUtil mailUtil;
@GetMapping("/testMail1")
@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
*/
@GetMapping("/font/test")
public String test(){
System.out.println("跳进测试的页面");
return Views.TEXT_PAGE;
}
/**
/**
* qq回调 applications over the unaudited use restrictions
* @return
*/
@RequestMapping("/afterlogin")
public String afterlogin(HttpServletRequest request){
// state 用户携带的信息
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.httpGet(api, data, null);
Map<String,Object> map = stringToMap(result);
if (result != null) {
// 获取用户的openId
result = getMemberInfo(map.get("access_token").toString());
// 因为返回的值是 callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} ); 需要获取括号里的值
result = result.substring(result.indexOf("(") + 1,result.indexOf(")"));
// 将 {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} 转成对象
JSONObject jsonObject = JSONObject.parseObject(result);
// 获取用户信息
UserInfo userInfo = getUserInfo(map.get("access_token").toString(),jsonObject.get("openid").toString());
System.out.println(JSON.toJSONString(userInfo));
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* grant_type=333&grant_type=666&grant_type=444 转成map形式
boolean isHTML = false; // 是不是HTML特殊字符,如
for (int i = 0; i < param.length(); i++) {
temp = param.charAt(i);
if (temp == '<') {
isCode = true;
} else if (temp == '&') {
isHTML = true;
} else if (temp == '>' && isCode) {
n = n - 1;
isCode = false;
} else if (temp == ';' && isHTML) {
isHTML = false;
}
try {
if (!isCode && !isHTML) {
n += String.valueOf(temp).getBytes("GBK").length;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (n <= length - 3) {
result.append(temp);
} else {
result.append("...");
break;
}
}
// 取出截取字符串中的HTML标记
String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)",
"$1$2");
// 去掉不需要结素标记的HTML标记
temp_result = temp_result
.replaceAll(
"</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
"");
// 去掉成对的HTML标记
temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>",
"$2");
// 用正则表达式取出标记
Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
Matcher m = p.matcher(temp_result);
List<String> endHTML = Lists.newArrayList();
while (m.find()) {
endHTML.add(m.group(1));
}
// 补全不成对的HTML标记
}
package com.ruixin.controller;
@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")
@Controller
@RequestMapping("/sys")
public class SysController {
@Autowired
private NewsService newsService;
@Autowired
private TypeService typeService;
/**
* 跳转到系统数据页
* @return
*/
@GetMapping("/data/list")
@RequiresPermissions("base:data:views")
public String dataList(){
return Views.SYS_DATA_LIST;
}
/**
* 跳转到系统数据页
* @return
*/
@GetMapping("/data/list1")
@RequiresPermissions("base:data:views")
public String dataList1(){
return Views.SYS_DATA_LIST1;
}
/**
* 获取数据
*/
@PostMapping("/data/getData")
@RequiresPermissions("base:data:views")
@ResponseBody
public List<Map<String,Object>> getData(){
return newsService.getData();
@Controller
@RequestMapping("/sys")
public class SysController {
@Autowired
private NewsService newsService;
@Autowired
private TypeService typeService;
/**
* 跳转到系统数据页
* @return
*/
@GetMapping("/data/list")
@RequiresPermissions("base:data:views")
public String dataList(){
return Views.SYS_DATA_LIST;
}
/**
* 跳转到系统数据页
* @return
*/
@GetMapping("/data/list1")
@RequiresPermissions("base:data:views")
public String dataList1(){
return Views.SYS_DATA_LIST1;
}
/**
* 获取数据
*/
@PostMapping("/data/getData")
@RequiresPermissions("base:data:views")
@ResponseBody
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 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;
}
}
package com.ruixin.controller;
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 验证字符串
* @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;
}
}
}
*/
@RestController
public class TestMailController {
@Autowired
private MailUtil mailUtil;
@GetMapping("/testMail1")
public String simpleMail() throws Exception {
String[] revicer={"3128341058@qq.com","1299077789@qq.com"};
mailUtil.sendSimpleMail(revicer,"这是一个测试邮件1","这是一个测试邮件!");
return "success";
}
@GetMapping("/testMail2")
public String sendHtmlMail() throws Exception {
String[] revicer={"3128341058@qq.com","1299077789@qq.com"};
mailUtil.sendHtmlMail(revicer,"<h1>这是一个测试邮件2</h1>","<h1 style='color:red;'>这是一个测试邮件!</h1>");
return "success";
}
@GetMapping("/testMail3")
public String sendInlineMail() throws Exception {
String[] revicer={"3128341058@qq.com","1299077789@qq.com"};
File file=new File("C:\\Users\\Administrator\\IdeaProjects\\hblog\\src\\main\\webapp\\static\\images\\photo.jpg");
mailUtil.sendInlineMail(revicer,"<h1>这是一个测试邮件3</h1>","<h1 style='color:red;'>这是一个测试邮件!<img src='cid:photo'/></h1>",file,"photo");
return "success";
}
@GetMapping("/testMail4")
public String sendAttachmentsMail() throws Exception {
String[] revicer={"3128341058@qq.com","1299077789@qq.com"};
File file=new File("C:\\Users\\Administrator\\IdeaProjects\\hblog\\src\\main\\webapp\\static\\images\\photo.jpg");
mailUtil.sendAttachmentsMail(revicer,"<h1>这是一个测试邮件4</h1>","<h1 style='color:red;'>这是一个测试邮件!</h1>",file,"photo");
return "success";
}
}
package com.ruixin.common.security;
/**
* 连接权限管理类
*/
@Controller
public class QQLoginController {
private final static String APP_ID = "101392599";
private final static String APP_KEY = "47af19b47870932e2ba4d1008a705961";
private final static String GET_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
private final static String loginCallback = "http://www.xulian.net.cn:8088/afterlogin";
static final String[] EMPTY_STRING_ARRAY = new String[0];
@RequestMapping("/qqTest")
public String qqTest(){
return "login";
}
/**
* qq 授权
* @return
*/
@RequestMapping("/qqLogin")
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 true;
}
return false;
}
}
package com.ruixin.controller;
@Controller
@RequestMapping("/sys")
public class SysController {
@Autowired
private NewsService newsService;
@Autowired
private TypeService typeService;
/**
* 跳转到系统数据页
* @return