diff --git a/.gitignore b/.gitignore index e905c64..35780d2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ build/ *.iml out/ -classes/test/ +classes/ src/main/resources/static/lib/codemirror/mode/jade/ src/main/resources/static/lib/codemirror/mode/rpm/changes/ arget/ diff --git a/.gradle/2.12/taskArtifacts/cache.properties.lock b/.gradle/2.12/taskArtifacts/cache.properties.lock index 9528204..b61b621 100644 Binary files a/.gradle/2.12/taskArtifacts/cache.properties.lock and b/.gradle/2.12/taskArtifacts/cache.properties.lock differ diff --git a/.gradle/2.12/taskArtifacts/fileHashes.bin b/.gradle/2.12/taskArtifacts/fileHashes.bin index d009ecd..28a0b46 100644 Binary files a/.gradle/2.12/taskArtifacts/fileHashes.bin and b/.gradle/2.12/taskArtifacts/fileHashes.bin differ diff --git a/.gradle/2.12/taskArtifacts/fileSnapshots.bin b/.gradle/2.12/taskArtifacts/fileSnapshots.bin index 70fbc2a..4be4511 100644 Binary files a/.gradle/2.12/taskArtifacts/fileSnapshots.bin and b/.gradle/2.12/taskArtifacts/fileSnapshots.bin differ diff --git a/.gradle/2.12/taskArtifacts/outputFileStates.bin b/.gradle/2.12/taskArtifacts/outputFileStates.bin index 5b2b9ac..913fafd 100644 Binary files a/.gradle/2.12/taskArtifacts/outputFileStates.bin and b/.gradle/2.12/taskArtifacts/outputFileStates.bin differ diff --git a/.gradle/2.12/taskArtifacts/taskArtifacts.bin b/.gradle/2.12/taskArtifacts/taskArtifacts.bin index 3bf11bd..94c881f 100644 Binary files a/.gradle/2.12/taskArtifacts/taskArtifacts.bin and b/.gradle/2.12/taskArtifacts/taskArtifacts.bin differ diff --git a/README.md b/README.md index e084a2d..b970e93 100644 --- a/README.md +++ b/README.md @@ -30,33 +30,96 @@ #####后台管理 ![博客列表](http://jcalaz.github.io/img/jcala_blog.adlist.jpg) ![markdown编辑器](http://jcalaz.github.io/img/jcala_blog.adre.jpg) -####分支: -1. master主分支: 基于docker方式部署,可以动态更换头像,可以上传图片,用nginx做反向代理服务器。 -2. simple分支:基于jar包形式部署,不可以动态更改头像,不可以上传图片,不用niginx做反向代理服务器。 ####部署 -simple分支部署 -- 下载simple分支。打开部署目录,可以看到jcalaBlog-0.1.0.jar。(也可以自己用gradle打成jar包,shell进入项目主目录,执行gradle clean build,在项目目录/build/libs目录下可看到打成的jar包)将jar上传到服务器/home/jcala目录 +- 打开deploy目录,可以看到jcalaBlog-1.0.0.jar。(也可以自己用gradle打成jar包,shell进入项目主目录,执行gradle clean build,在项目目录/build/libs目录下可看到打成的jar包)将jar上传到服务器/home/jcala目录 - 服务器安装mysql,进入mysql创建jcala_blog数据库。(不创建的话HikariCP数据库连接池有时会出现问题) - 部署文件夹下的application-prod.yml配置文件为默认配置,运行时可以覆盖默认配置。例如运行:java -jar --spring.datasource.username=root --spring.datasource.password=123 --spring.datasource.initialize=true 设置数据库用户名为root,数据库密码为123,运行时自动导入数据库表结构和数据 -master分支部署 -... +####配置文件 +```yaml +server: + port: 80 #博客端口号 + compression: + min-response-size: 512 #压缩文件最小大小(kb) + enabled: true #是否压缩 + mime-types: text/html,text/css,text/javascript,application/javascript,image/gif,image/png,image/jpg #要压缩的文件格式 + undertow: + io-threads: 4 #io线程数 + worker-threads: 10 #工作线程数 + buffer-size: 16384 #每个缓冲的字节数 + accesslog: + enabled: true #是否开启undertow日志 + dir: /home/jcala/blog/log/server_log #undertow日志目录 + pattern: combined #日志格式 +logging: + config: classpath:logback-spring.xml #logback配置文件 + path: /home/jcala/blog/log/spring_log #logback日志目录 +spring: + velocity: + cache: true #velocity是否开启缓存 + charset: UTF-8 + view-names: error,index,projects,tags,tagView,archives,post,about,login,admin/blog_add,admin/project, + admin/moniter,admin/blog_modify,admin/blog_list,admin/info,admin/result,admin/resume + #允许的vm名称,新建的vm文件要想使用必须在此注册 + properties: + input.encoding: UTF-8 + output.encoding: UTF-8 + velocimacro.library: VM_global_library.vm #velocity的宏文件 + directive.parse.max.depth: 2 #parse解析的深度 + http: + encoding.charset: UTF-8 + encoding.force: false + multipart: + max-file-size: 3MB #上传文件最大的大小,因此上传的图片不可超过这个大小,否则抛出异常 + max-request-size: 10MB + cache: + cache-names: ehcache #设置缓存的实现为ehcache + ehcache: + config: ehcache.xml #ehcache的配置文件 + datasource: + type: com.zaxxer.hikari.HikariDataSource #数据库连接池为hikariCP + username: root #数据库访问用户名 + password: root #数据库访问密码 + url: jdbc:mysql://127.0.0.1:3306/jcala_blog?useUnicode:true&characterEncoding:UTF-8 + driverClassName: com.mysql.jdbc.Driver + schema: classpath:import.sql #数据库表结构 + data: classpath:data.sql #数据库初始化数据 + initialize: false #是否初始化数据库。true的话则执行import.sql,data.sql sql语句,导入表结构和初始化数据 + sql-script-encoding: UTF-8 #导入的sql文件编码 + hikari: + connection-timeout: 30000 + maximum-pool-size: 50 #数据库连接池最大连接数 + minimum-idle: 5 #初始连接池的连接数 +mybatis: + type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping + type-handlers-package: org.apache.ibatis.type.LocalDateTypeHandler + config-location: classpath:mybatis-config.xml #mybatis配置文件 +pic: + home: G:\home\jcala\xmarket\pic #图片在服务器上存放的目录 +``` + +####注意事项 +1. 运行后中文显示乱码:在linux下,vim /etc/mysql/my.cnf 。在[mysqld]下添加character-set-server=utf8 +2. 二次开发报错,没有getter,setter等方法:因为使用了lombok,需要idea或者Eclipse安装lombok插件 +3. 运行后,后台管理初始用户名admin,密码admin ####优点 1. 响应式,前端适配手机 2. cdn加速,gzip压缩 3. 前端页面用Ehcache缓存加速 4. 一键黑夜模式 -5. nginx反向代理加速 -6. 事务处理 - -####可能逐步加入的功能 -1. 项目代码托管 -2. 全文检索 -3. 云IDE -4. 后台管理适配手机客户端 +5. 事务处理 + +####2.0版本将要做出的改变 +1. 用react.js将前端重写为单页面应用,去除模板引擎,前端模拟路由。服务器端只负责收发json数据。 +2. 项目分模块,前后端分离,增强拓展性。 +3. 加入钩子,方便自定义插件。 +4. 前端模板化,可自定义定制主题。 +5. 增强安全性。 +6. jdk版本升级为java8。 +7. 还会逐步提供评论,全文检索,项目托管等功能或者插件。 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 1a8c329..1be272c 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ targetCompatibility = 1.7 compileJava.dependsOn(processResources) jar { baseName = 'jcalaBlog' - version = '0.1.0' + version = '1.0.0' } configurations { compile.exclude module: "spring-boot-starter-tomcat" diff --git a/deploy/jcalaBlog-1.0.0.jar b/deploy/jcalaBlog-1.0.0.jar new file mode 100644 index 0000000..aea70ac Binary files /dev/null and b/deploy/jcalaBlog-1.0.0.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ed9ec15..80182a5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jul 08 23:44:12 CST 2016 +#Sun Oct 30 21:33:27 CST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-all.zip diff --git a/issues b/issues deleted file mode 100644 index 1f8c776..0000000 --- a/issues +++ /dev/null @@ -1 +0,0 @@ -显示乱码:vim /etc/mysql/my.cnf 在[mysqld]下添加character-set-server=utf8 \ No newline at end of file diff --git a/src/main/java/me/jcala/blog/Application.java b/src/main/java/me/jcala/blog/Application.java index c32f14a..ad7724e 100644 --- a/src/main/java/me/jcala/blog/Application.java +++ b/src/main/java/me/jcala/blog/Application.java @@ -2,7 +2,6 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.cache.annotation.EnableCaching; diff --git a/src/main/java/me/jcala/blog/conf/ReverseConf.java b/src/main/java/me/jcala/blog/conf/ReverseConf.java deleted file mode 100644 index 52eb5b4..0000000 --- a/src/main/java/me/jcala/blog/conf/ReverseConf.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.jcala.blog.conf; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -/** - * Created by jcala on 2016/7/29 - */ -@Configuration -public class ReverseConf { - @Value("${reverse.domain}") - private String reverse_domain; - @Value("${reverse.port}") - private String reverse_port; - @Value("${reverse.prefix}") - private String reverse_prefix; - @Value("${reverse.path}") - private String reverse_path; - @Bean - public String getReverse(){ - return reverse_domain+reverse_port; - } -} \ No newline at end of file diff --git a/src/main/java/me/jcala/blog/conf/WebMvcConf.java b/src/main/java/me/jcala/blog/conf/WebMvcConf.java index c2f54aa..ca7c85d 100644 --- a/src/main/java/me/jcala/blog/conf/WebMvcConf.java +++ b/src/main/java/me/jcala/blog/conf/WebMvcConf.java @@ -1,16 +1,28 @@ package me.jcala.blog.conf; +import me.jcala.blog.domain.SystemSetting; import me.jcala.blog.interceptor.UserSecurityInterceptor; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import java.util.Arrays; + /** * web页面配置类,拦截器地址在此注册 */ @Configuration public class WebMvcConf extends WebMvcConfigurerAdapter{ + + @Value("${pic.home}") + private String picHome; + @Autowired private UserSecurityInterceptor securityInterceptor; @@ -19,4 +31,22 @@ public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(securityInterceptor).addPathPatterns("/admin/**");//配置登录拦截器拦截路径 } + @Bean + public CorsFilter corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowCredentials(true); + configuration.addAllowedOrigin("*"); + configuration.addAllowedHeader("*"); + configuration.setAllowedMethods(Arrays.asList("GET", "PUT", "POST","DELETE")); + source.registerCorsConfiguration("/**", configuration); + return new CorsFilter(source); + } + + @Bean + public SystemSetting systemSetting(){ + return SystemSetting.builder() + .picHome(picHome) + .build(); + } } diff --git a/src/main/java/me/jcala/blog/controller/FontEndCtrl.java b/src/main/java/me/jcala/blog/controller/FontEndCtrl.java index 51ce8f5..ed2deb6 100644 --- a/src/main/java/me/jcala/blog/controller/FontEndCtrl.java +++ b/src/main/java/me/jcala/blog/controller/FontEndCtrl.java @@ -3,9 +3,11 @@ import me.jcala.blog.domain.BlogView; import me.jcala.blog.domain.Info; import me.jcala.blog.service.inter.BlogSer; +import me.jcala.blog.service.inter.FileUploadSer; import me.jcala.blog.service.inter.InfoSer; import me.jcala.blog.service.inter.ProjectSer; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -22,12 +24,19 @@ */ @Controller public class FontEndCtrl { - @Autowired private BlogSer blogSer; - @Autowired private ProjectSer projectSer; - @Autowired private InfoSer infoSer; + private FileUploadSer fileUploadSer; + + @Autowired + public FontEndCtrl(BlogSer blogSer, ProjectSer projectSer, InfoSer infoSer, FileUploadSer fileUploadSer) { + this.blogSer = blogSer; + this.projectSer = projectSer; + this.infoSer = infoSer; + this.fileUploadSer = fileUploadSer; + } + @GetMapping("/archives/{page}") public String archives(@PathVariable int page,Model model){ model.addAttribute("info",infoSer.getInfo()); @@ -89,6 +98,7 @@ public String welcome(Model model) { } @GetMapping("/login") public String login(HttpServletRequest request, Model model) { + model.addAttribute("avatar",infoSer.getInfo().getAvatar()); String result = request.getParameter("result"); if (result != null && result.equals("fail")) { model.addAttribute("success", 0); @@ -112,4 +122,11 @@ public String logout(HttpServletRequest request) { infoSer.destroySession(request); return "redirect:/login"; } + + @GetMapping(value = "/pic/{dir}/{picName:.+}") + public ResponseEntity gainUserAvatar(@PathVariable String dir, @PathVariable String picName) + throws RuntimeException { + return fileUploadSer.gainPic(dir,picName); + } + } diff --git a/src/main/java/me/jcala/blog/controller/admin/BlogCtrl.java b/src/main/java/me/jcala/blog/controller/admin/BlogCtrl.java index fe0930a..e20fc1d 100644 --- a/src/main/java/me/jcala/blog/controller/admin/BlogCtrl.java +++ b/src/main/java/me/jcala/blog/controller/admin/BlogCtrl.java @@ -19,9 +19,14 @@ @Controller @RequestMapping("/admin") public class BlogCtrl { - @Autowired + private BlogSer blogSer; + @Autowired + public BlogCtrl(BlogSer blogSer) { + this.blogSer = blogSer; + } + /** *后台管理中添加博客页面的控制器 * @@ -40,7 +45,7 @@ public String blogAdd() { * @return templates下的admin/blog_add.vm页面 */ @GetMapping("/update{id:\\d+}") - public String blogModify(@PathVariable int id,Model model) { + public String blogModify(@PathVariable int id,Model model){ BlogView blogView=blogSer.adminGetBlog(id); if (blogView==null){ return "error"; @@ -94,7 +99,7 @@ public String update(BlogView view,Model model){ * @param id 要删除的博客id */ @GetMapping("/delete/{id}") - public String delete(@PathVariable int id,Model model) { + public String delete(@PathVariable int id,Model model){ boolean result= blogSer.deleteBlogById(id); if (result){ return "redirect:/admin/blogList/1"; diff --git a/src/main/java/me/jcala/blog/controller/admin/FileCtrl.java b/src/main/java/me/jcala/blog/controller/admin/FileCtrl.java index 40a02af..f128e83 100644 --- a/src/main/java/me/jcala/blog/controller/admin/FileCtrl.java +++ b/src/main/java/me/jcala/blog/controller/admin/FileCtrl.java @@ -11,15 +11,16 @@ import javax.servlet.http.HttpServletRequest; -/** - * Created by Administrator on 2016/9/24. - */ @Controller public class FileCtrl { - @Autowired private FileUploadSer uploadSer; + @Autowired + public FileCtrl(FileUploadSer uploadSer) { + this.uploadSer = uploadSer; + } + @PostMapping("/admin/file/uplPic.action") @ResponseBody public UploadPic uploadPic(HttpServletRequest request){ diff --git a/src/main/java/me/jcala/blog/controller/admin/InfoCtrl.java b/src/main/java/me/jcala/blog/controller/admin/InfoCtrl.java index 9ac4807..67ea841 100644 --- a/src/main/java/me/jcala/blog/controller/admin/InfoCtrl.java +++ b/src/main/java/me/jcala/blog/controller/admin/InfoCtrl.java @@ -19,11 +19,16 @@ */ @Controller public class InfoCtrl { - @Autowired + private InfoSer infoSer; + @Autowired + public InfoCtrl(InfoSer infoSer) { + this.infoSer = infoSer; + } + @GetMapping("/admin/info") - public String info(Model model) throws Exception { + public String info(Model model){ Info info = infoSer.getInfo(); model.addAttribute("info", info); return "admin/info"; @@ -43,7 +48,7 @@ public String updateInfo(Info info, Model model) { } @PostMapping("/admin/pass.action") - public String passModify(String old_pass, String new_pass, HttpServletRequest request) { + public String passModify(String old_pass, String new_pass, HttpServletRequest request){ int result = infoSer.modifyPw(old_pass, new_pass); if (result == 0) { infoSer.destroySession(request); @@ -58,7 +63,7 @@ public String resume(Model model) { } @PostMapping("/admin/resume.action") - public String resumeUpdate(Info info, Model model) { + public String resumeUpdate(Info info){ infoSer.updateResume(info); return "redirect:/admin/resume"; } diff --git a/src/main/java/me/jcala/blog/controller/admin/MoniterCtrl.java b/src/main/java/me/jcala/blog/controller/admin/MonitorCtrl.java similarity index 53% rename from src/main/java/me/jcala/blog/controller/admin/MoniterCtrl.java rename to src/main/java/me/jcala/blog/controller/admin/MonitorCtrl.java index e9c49c8..80aaaa1 100644 --- a/src/main/java/me/jcala/blog/controller/admin/MoniterCtrl.java +++ b/src/main/java/me/jcala/blog/controller/admin/MonitorCtrl.java @@ -1,6 +1,6 @@ package me.jcala.blog.controller.admin; -import me.jcala.blog.service.inter.MoniterSer; +import me.jcala.blog.service.inter.MonitorSer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,12 +13,18 @@ * 目前只包括内存占用的监控 */ @Controller -public class MoniterCtrl { +public class MonitorCtrl { + + private MonitorSer monitorSer; + @Autowired - private MoniterSer moniterSer; + public MonitorCtrl(MonitorSer monitorSer) { + this.monitorSer = monitorSer; + } + @GetMapping("/admin") - public String moniter(Model model, HttpServletRequest request) throws Exception { - model.addAttribute("freeMemory",moniterSer.getFreeMemery()); - return "admin/moniter"; + public String monitor(Model model, HttpServletRequest request){ + model.addAttribute("freeMemory", monitorSer.getFreeMemory()); + return "admin/monitor"; } } diff --git a/src/main/java/me/jcala/blog/controller/admin/ProjectCtrl.java b/src/main/java/me/jcala/blog/controller/admin/ProjectCtrl.java index 1545b87..b47fd2c 100644 --- a/src/main/java/me/jcala/blog/controller/admin/ProjectCtrl.java +++ b/src/main/java/me/jcala/blog/controller/admin/ProjectCtrl.java @@ -16,9 +16,15 @@ @Controller @RequestMapping("/admin") public class ProjectCtrl { - @Autowired + private ProjectSer projectSer; - @GetMapping("/project/{page}") + + @Autowired + public ProjectCtrl(ProjectSer projectSer) { + this.projectSer = projectSer; + } + + @GetMapping("/project/{page}") public String project(@PathVariable int page, Model model){ model.addAttribute("current",page); model.addAttribute("pageNum",projectSer.adminGetPageNum()); diff --git a/src/main/java/me/jcala/blog/domain/ReversePath.java b/src/main/java/me/jcala/blog/domain/ReversePath.java new file mode 100644 index 0000000..d92a203 --- /dev/null +++ b/src/main/java/me/jcala/blog/domain/ReversePath.java @@ -0,0 +1,18 @@ +package me.jcala.blog.domain; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +/** + * 封装反向代理服务器的路径信息 + */ +@Getter +@Setter +@ToString +public class ReversePath { + private String picFilePath;//图片文件所在基础路径,形如"/home/jcala/blog/static/img/" + private String picUrlPath;//图片的链接基础路径,形如"http://127.0.0.1:8090/static/img/" + private String cssUrlPath;//css文件链接基础路径,形如"http://127.0.0.1:8090/static/css/" + private String jsUrlPath;//js文件链接基础路径,形如"http://127.0.0.1:8090/static/js/" +} diff --git a/src/main/java/me/jcala/blog/domain/SystemSetting.java b/src/main/java/me/jcala/blog/domain/SystemSetting.java new file mode 100644 index 0000000..8ff622e --- /dev/null +++ b/src/main/java/me/jcala/blog/domain/SystemSetting.java @@ -0,0 +1,13 @@ +package me.jcala.blog.domain; + +import lombok.Builder; +import lombok.Getter; + +/** + * 全局配置类,用于储存自定义的全局变量 + */ +@Builder +public class SystemSetting { + @Getter + private String picHome; +} diff --git a/src/main/java/me/jcala/blog/exception/CtrlExceptionHandler.java b/src/main/java/me/jcala/blog/exception/CtrlExceptionHandler.java new file mode 100644 index 0000000..51210b7 --- /dev/null +++ b/src/main/java/me/jcala/blog/exception/CtrlExceptionHandler.java @@ -0,0 +1,24 @@ +package me.jcala.blog.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.ModelAndView; + +/** + * 全局异常处理类 + */ +@ControllerAdvice +@Slf4j +public class CtrlExceptionHandler { + + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(Exception.class) + public ModelAndView handleIOException(Exception e) { + log.info(e.getLocalizedMessage()); + return new ModelAndView("/error"); + } + +} diff --git a/src/main/java/me/jcala/blog/mapping/BlogMapper.java b/src/main/java/me/jcala/blog/mapping/BlogMapper.java index 71fe1b4..be1e80e 100644 --- a/src/main/java/me/jcala/blog/mapping/BlogMapper.java +++ b/src/main/java/me/jcala/blog/mapping/BlogMapper.java @@ -19,20 +19,20 @@ public interface BlogMapper { "from blog_view", "limit #{st},10" }) - List selectTenBlogs(@Param("st") int start) throws Exception; + List selectTenBlogs(@Param("st") int start) throws RuntimeException; @Select("select count(*) from blog_view") - int selectBlogNum() throws Exception; + int selectBlogNum() throws RuntimeException; @Select("select distinct name from view_tag") @ResultType(String.class) - List selectTags() throws Exception; + List selectTags() throws RuntimeException; @Select({"select vid,date,title", "from blog_view", "order by date desc", "limit #{st},12"}) - List selectArc(@Param("st") int start) throws Exception; + List selectArc(@Param("st") int start) throws RuntimeException; @Select({ "select title,tags,md", @@ -40,7 +40,7 @@ public interface BlogMapper { "where vid = #{id}", "limit 1" }) - BlogView selectAdmin(@Param("id") int id) throws Exception; + BlogView selectAdmin(@Param("id") int id) throws RuntimeException; @Select({ "select title,article", @@ -48,7 +48,7 @@ public interface BlogMapper { "where vid = #{id}", "limit 1" }) - BlogView selectView(@Param("id") int id) throws Exception; + BlogView selectView(@Param("id") int id) throws RuntimeException; @Select({ "select vid,title ", @@ -57,7 +57,7 @@ public interface BlogMapper { "order by vid desc", "limit 1" }) - BlogView selectPreView(@Param("id") int vid) throws Exception; + BlogView selectPreView(@Param("id") int vid) throws RuntimeException; @Select({ "select vid,title ", @@ -65,14 +65,14 @@ public interface BlogMapper { "where vid > #{id}", "limit 1" }) - BlogView selectNextView(@Param("id") int vid) throws Exception; + BlogView selectNextView(@Param("id") int vid) throws RuntimeException; @Select({ "select distinct vid", "from view_tag", "where name = #{tag}" }) - List selectVidBytag(@Param("tag") String tagName) throws Exception; + List selectVidBytag(@Param("tag") String tagName) throws RuntimeException; @Select({ "select date,title", @@ -80,7 +80,7 @@ public interface BlogMapper { "where vid = #{vid}", "limit 1" }) - BlogView selectTagView(@Param("vid") int vid) throws Exception; + BlogView selectTagView(@Param("vid") int vid) throws RuntimeException; @Insert({"insert into blog_view " , "(date,title,article,tags,md) " , @@ -88,16 +88,16 @@ public interface BlogMapper { "#{bv.article},#{bv.tags},#{bv.md})"}) @SelectKey(before=false,keyProperty="bv.vid",resultType=Integer.class, statementType= StatementType.STATEMENT,statement="SELECT LAST_INSERT_ID() AS id") - int insertBlog(@Param("bv") BlogView blogView) throws Exception; + int insertBlog(@Param("bv") BlogView blogView) throws RuntimeException; @Insert("insert ignore into view_tag (name,vid) values(#{tn},#{id})") - int insertViewTag(@Param("tn") String tagName, @Param("id") int vid) throws Exception; + int insertViewTag(@Param("tn") String tagName, @Param("id") int vid) throws RuntimeException; @Delete("delete from view_tag where vid = #{vid}") - int deleteViewTag(@Param("vid") int vid) throws Exception; + int deleteViewTag(@Param("vid") int vid) throws RuntimeException; @Delete("delete from blog_view where vid =#{vid} limit 1") - int deleteBlogView(@Param("vid") int vid) throws Exception; + int deleteBlogView(@Param("vid") int vid) throws RuntimeException; @Update({ "update blog_view", @@ -107,6 +107,6 @@ public interface BlogMapper { "article = #{bv.article}", "where vid = #{bv.vid}" }) - void updateBlogView(@Param("bv") BlogView blogView) throws Exception; + void updateBlogView(@Param("bv") BlogView blogView) throws RuntimeException; } diff --git a/src/main/java/me/jcala/blog/mapping/InfoMapper.java b/src/main/java/me/jcala/blog/mapping/InfoMapper.java index 5557897..995ac37 100644 --- a/src/main/java/me/jcala/blog/mapping/InfoMapper.java +++ b/src/main/java/me/jcala/blog/mapping/InfoMapper.java @@ -20,7 +20,7 @@ public interface InfoMapper { "github,twitter,avatar", "from admin limit 1" }) - Info select() throws Exception; + Info select() throws RuntimeException; @Select({ "select count(*) ", @@ -28,20 +28,20 @@ public interface InfoMapper { "where username = #{un} ", "and password = #{pw}" }) - int selectByPw(@Param("un") String username, @Param("pw") String password) throws Exception; + int selectByPw(@Param("un") String username, @Param("pw") String password) throws RuntimeException; @Select({ "select count(*) ", "from admin ", "where password = #{pw}" }) - int selectByOldPass(@Param("pw") String oldPass) throws Exception; + int selectByOldPass(@Param("pw") String oldPass) throws RuntimeException; @Select("select md from admin limit 1") - String selectMd() throws Exception; + String selectMd() throws RuntimeException; @Select("select resume from admin limit 1") - String selectResume() throws Exception; + String selectResume() throws RuntimeException; @Update({ "update admin set username = #{if.username},", @@ -56,7 +56,7 @@ public interface InfoMapper { "password = #{np} ", "limit 1" }) - int updataPass(@Param("np") String newPass) throws Exception; + int updataPass(@Param("np") String newPass) throws RuntimeException; @Update({ "update admin ", @@ -64,12 +64,12 @@ public interface InfoMapper { "resume = #{if.resume} ", "limit 1" }) - void updateResume(@Param("if") Info info) throws Exception; + void updateResume(@Param("if") Info info) throws RuntimeException; @Update({ "update admin", "set avatar = #{ava}", "limit 1" }) - void updateAvater(@Param("ava") String avatar) throws Exception; + void updateAvater(@Param("ava") String avatar) throws RuntimeException; } diff --git a/src/main/java/me/jcala/blog/mapping/ProjectMapper.java b/src/main/java/me/jcala/blog/mapping/ProjectMapper.java index 406861c..5124099 100644 --- a/src/main/java/me/jcala/blog/mapping/ProjectMapper.java +++ b/src/main/java/me/jcala/blog/mapping/ProjectMapper.java @@ -19,7 +19,7 @@ public interface ProjectMapper { "from project ", "limit #{st},5" }) - List select(@Param("st") int start) throws Exception; + List select(@Param("st") int start) throws RuntimeException; @Select({ "select id,name,url,tech,desp", @@ -27,17 +27,17 @@ public interface ProjectMapper { "where id = #{id}", "limit 1" }) - Project selectById(@Param("id") int id) throws Exception; + Project selectById(@Param("id") int id) throws RuntimeException; @Select({ "select id,name,url", "from project", "limit #{st},10" }) - List adminSelect(@Param("st") int start) throws Exception; + List adminSelect(@Param("st") int start) throws RuntimeException; @Select("select count(*) from project") - int count() throws Exception; + int count() throws RuntimeException; @Insert({ "insert into project", @@ -45,7 +45,7 @@ public interface ProjectMapper { "url = #{p.url},date=#{p.date},", "tech=#{p.tech},desp=#{p.desp}" }) - void insert(@Param("p") Project project) throws Exception; + void insert(@Param("p") Project project) throws RuntimeException; @@ -54,7 +54,7 @@ public interface ProjectMapper { "where id = #{id}", "limit 1" }) - void delete(@Param("id") int id) throws Exception; + void delete(@Param("id") int id) throws RuntimeException; @Update({ @@ -64,5 +64,5 @@ public interface ProjectMapper { "where id = #{p.id}", "limit 1" }) - void Update(@Param("p") Project project) throws Exception; + void Update(@Param("p") Project project) throws RuntimeException; } diff --git a/src/main/java/me/jcala/blog/service/BlogSerImpl.java b/src/main/java/me/jcala/blog/service/BlogSerImpl.java index db5583a..dbf347c 100644 --- a/src/main/java/me/jcala/blog/service/BlogSerImpl.java +++ b/src/main/java/me/jcala/blog/service/BlogSerImpl.java @@ -1,13 +1,12 @@ package me.jcala.blog.service; +import lombok.extern.slf4j.Slf4j; import me.jcala.blog.domain.Archive; import me.jcala.blog.domain.BlogView; import me.jcala.blog.mapping.BlogMapper; import me.jcala.blog.service.inter.BlogSer; import me.jcala.blog.utils.TimeTools; import me.jcala.blog.utils.Tools; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; @@ -22,23 +21,19 @@ import java.util.List; import java.util.Map; -/** - * Created by Administrator on 2016/9/3. - */ @Service +@Slf4j public class BlogSerImpl implements BlogSer { - private static final Logger LOGGER = LoggerFactory.getLogger(BlogSerImpl.class); - @Autowired private BlogMapper blogMapper; + + @Autowired + public BlogSerImpl(BlogMapper blogMapper) { + this.blogMapper = blogMapper; + } + @Override public BlogView adminGetBlog(int vid){ - BlogView blogView=null; - try { - blogView=blogMapper.selectAdmin(vid); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return blogView; + return blogMapper.selectAdmin(vid); } @Override @Caching(evict = { @@ -53,14 +48,14 @@ public boolean addBlog(BlogView blogView){ try { blogMapper.insertBlog(blogView); } catch (Exception e) { - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); result=false; } if (result){ try { addViewTag(blogView.getTags(),blogView.getVid()); } catch (Exception e) { - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); result=false; } } @@ -68,23 +63,12 @@ public boolean addBlog(BlogView blogView){ } @Override public List getBlogPage(int id){ - List blogList=new ArrayList<>(); - try { int start=(id-1)*10; - blogList=blogMapper.selectTenBlogs(start); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return blogList; + return blogMapper.selectTenBlogs(start); } @Override public int adminGetPageNum(){ - int num=0; - try { - num=blogMapper.selectBlogNum(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + int num=blogMapper.selectBlogNum(); return num%10==0?num/10:num/10+1; } @@ -100,13 +84,13 @@ public boolean updateBlog(BlogView blogView){ blogMapper.updateBlogView(blogView); } catch (Exception e) { result=false; - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); } if (result){ try { updateViewTag(blogView.getTags(),blogView.getVid()); } catch (Exception e) { - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); result=false; } } @@ -125,7 +109,7 @@ public boolean deleteBlogById(int vid) { try { blogMapper.deleteBlogView(vid); } catch (Exception e) { - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); result=false; } return result; @@ -133,62 +117,32 @@ public boolean deleteBlogById(int vid) { @Override @Cacheable(value = "tagList",key = "1") - public List getTagList() { - List tags=new ArrayList<>(); - try { - tags=blogMapper.selectTags(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return tags; + public List getTagList(){ + return blogMapper.selectTags(); } @Override @Cacheable(value = "archives",condition = "#page==1",key = "1") - public List getArchive(int page) { + public List getArchive(int page){ int start=(page-1)*12; - List archives=new ArrayList<>(); - try { - List blogViews=blogMapper.selectArc(start); - archives=bv2Ar(blogViews); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return archives; + return bv2Ar(blogMapper.selectArc(start)); } @Override @Cacheable(value = "archivePageNum",key = "1") - public int getArchiveNum() { - int blogNum=0; - try { - blogNum=blogMapper.selectBlogNum(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + public int getArchiveNum(){ + int blogNum=blogMapper.selectBlogNum(); return blogNum%12==0?blogNum/12:blogNum/12+1; } @Override - public BlogView getBlog(int vid) { - BlogView blogView=new BlogView(); - try { - blogView=blogMapper.selectView(vid); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return blogView; + public BlogView getBlog(int vid){ + return blogMapper.selectView(vid); } @Override - public BlogView getPrevBlog(int vid) { - BlogView blogView=null; - try { - blogView=blogMapper.selectPreView(vid); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return blogView; + public BlogView getPrevBlog(int vid){ + return blogMapper.selectPreView(vid); } @Override @@ -197,15 +151,14 @@ public BlogView getNextBlog(int vid) { try { blogView=blogMapper.selectNextView(vid); } catch (Exception e) { - LOGGER.error(e.getMessage()); + log.error(e.getMessage()); } return blogView; } @Override - public List getBlogByTag(String tagName) { + public List getBlogByTag(String tagName){ List views=new ArrayList<>(); - try { List vids=blogMapper.selectVidBytag(tagName); for (int vid:vids){ BlogView view=blogMapper.selectTagView(vid); @@ -216,13 +169,10 @@ public List getBlogByTag(String tagName) { views.add(view); } } - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } return views; } - private List bv2Ar(List views) throws Exception{ + private List bv2Ar(List views){ List archives=new ArrayList<>(); Map years2Ar=new HashMap<>(); for (BlogView view:views){ @@ -240,14 +190,14 @@ private List bv2Ar(List views) throws Exception{ } return archives; } - private void addViewTag(String tagStr,int vid) throws Exception{ + private void addViewTag(String tagStr,int vid){ List tagList=Tools.getTagList(tagStr); for (String tag:tagList){ blogMapper.insertViewTag(tag,vid); } } - private void updateViewTag(String tagStr,int vid) throws Exception{ + private void updateViewTag(String tagStr,int vid){ blogMapper.deleteViewTag(vid); List tagList=Tools.getTagList(tagStr); for (String tag:tagList){ diff --git a/src/main/java/me/jcala/blog/service/FileUploadSerImpl.java b/src/main/java/me/jcala/blog/service/FileUploadSerImpl.java index 6c77778..bb00a79 100644 --- a/src/main/java/me/jcala/blog/service/FileUploadSerImpl.java +++ b/src/main/java/me/jcala/blog/service/FileUploadSerImpl.java @@ -1,83 +1,82 @@ package me.jcala.blog.service; +import lombok.extern.slf4j.Slf4j; import me.jcala.blog.domain.Info; +import me.jcala.blog.domain.SystemSetting; import me.jcala.blog.domain.UploadPic; import me.jcala.blog.service.inter.FileUploadSer; import me.jcala.blog.service.inter.InfoSer; import me.jcala.blog.utils.FileTools; -import me.jcala.blog.utils.TimeTools; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; import java.io.File; -import java.util.Iterator; -/** - * Created by Administrator on 2016/9/25. - */ +@Slf4j @Service -public class FileUploadSerImpl implements FileUploadSer { - @Autowired +public class FileUploadSerImpl implements FileUploadSer{ private InfoSer infoSer; - private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadSerImpl.class); - //设置文件上传目录为操作系统目录/blog/pic - private static final String IMGDIR = System.getProperties().getProperty("user.home") + - File.separatorChar + "blog" + File.separatorChar + "img"; - private static final String NGINXIMG = "http://127.0.0.1:8090/img/"; + + private SystemSetting setting; + + @Autowired + public FileUploadSerImpl(InfoSer infoSer, SystemSetting setting){ + this.infoSer = infoSer; + this.setting = setting; + } @Override - public UploadPic uploadPic(HttpServletRequest request) { - MultipartFile multipartFile = getMultipartFile(request); - //设置图片名称 - String fileName = String.valueOf(System.currentTimeMillis()) + "." + - FileTools.getSuffix(multipartFile.getOriginalFilename()); - String yearMonth = TimeTools.getYearMonthOfNow(); - File path = new File(IMGDIR + File.separatorChar + yearMonth); - File targetFile = new File(IMGDIR + File.separatorChar + yearMonth + File.separatorChar + fileName); - final UploadPic upload = new UploadPic(); - boolean result = true; - String errorMsg = null; - try { - if (!path.exists()) { - path.mkdirs(); - } - multipartFile.transferTo(targetFile); + public UploadPic uploadPic(HttpServletRequest request){ + + String picUrl=""; + try { + picUrl=FileTools.updatePic("/pic/",setting.getPicHome(),request); } catch (Exception e) { - errorMsg = e.getMessage(); - LOGGER.error(errorMsg); - result = false; + log.warn("上传图片时发生错误:"+e.getLocalizedMessage()); } - if (result) { - upload.setSuccess(1); - upload.setMessage("Upload picture success!"); - upload.setUrl(NGINXIMG + yearMonth + "/" + fileName); - } else { + final UploadPic upload = new UploadPic(); + if ("".equals(picUrl)){ upload.setSuccess(0); - upload.setMessage("Upload picture fail!" + errorMsg); + upload.setMessage("Upload picture fail!"); upload.setUrl(""); + return upload; } + upload.setSuccess(1); + upload.setMessage("Upload picture success!"); + upload.setUrl(picUrl); return upload; } @Override @Transactional(isolation = Isolation.READ_COMMITTED) - public Info updateAvatar(HttpServletRequest request) { + public Info updateAvatar(HttpServletRequest request){ String url=uploadPic(request).getUrl(); - infoSer.updateAvatar(url); + if (!"".equals(url)){ + infoSer.updateAvatar(url); + } return infoSer.getInfo(); } - private MultipartFile getMultipartFile(HttpServletRequest request) { - MultipartHttpServletRequest multipartRequest = - (MultipartHttpServletRequest) request; - Iterator fileNames = multipartRequest.getFileNames(); - return multipartRequest.getFile(fileNames.next()); + @Override + public ResponseEntity gainPic(String dir, String picName){ + File file=new File(setting.getPicHome()+File.separatorChar+dir+File.separatorChar+picName); + byte[] bytes; + try { + bytes= FileTools.readFileToByteArray(file); + } catch (Exception e) { + log.warn(e.getLocalizedMessage()); + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + headers.setContentDispositionFormData("attachment", picName); + return new ResponseEntity<>(bytes, headers, HttpStatus.OK); } } diff --git a/src/main/java/me/jcala/blog/service/InfoSerImpl.java b/src/main/java/me/jcala/blog/service/InfoSerImpl.java index e566641..5fc94f5 100644 --- a/src/main/java/me/jcala/blog/service/InfoSerImpl.java +++ b/src/main/java/me/jcala/blog/service/InfoSerImpl.java @@ -15,9 +15,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -/** - * Created by Administrator on 2016/9/8. - */ @Service public class InfoSerImpl implements InfoSer { private static final int MODIFYPASSSUC=0;//修改密码成功 @@ -29,14 +26,8 @@ public class InfoSerImpl implements InfoSer { @Override @Cacheable(value = "profileOfInfo",key = "1") - public Info getInfo() { - Info info=new Info(); - try { - info=infoMapper.select(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return info; + public Info getInfo() throws RuntimeException{ + return infoMapper.select(); } @Override @@ -55,12 +46,7 @@ public boolean login(Info user) { } @Override public boolean checkPass(String oldPass){ - int num=0; - try { - num=infoMapper.selectByOldPass(oldPass); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + int num=infoMapper.selectByOldPass(oldPass); return num>0; } @Override @@ -129,22 +115,12 @@ public boolean updateResume(Info info){ @Override @Cacheable(value = "resumeView",key = "1") - public String getResumeView() { - String resume=""; - try { - resume=infoMapper.selectResume(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return resume; + public String getResumeView() throws RuntimeException{ + return infoMapper.selectResume(); } @Override @CacheEvict(value = "profileOfInfo",key = "1") - public void updateAvatar(String avatar) { - try { + public void updateAvatar(String avatar) throws RuntimeException{ infoMapper.updateAvater(avatar); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } } } diff --git a/src/main/java/me/jcala/blog/service/MoniterSerImpl.java b/src/main/java/me/jcala/blog/service/MonitorSerImpl.java similarity index 54% rename from src/main/java/me/jcala/blog/service/MoniterSerImpl.java rename to src/main/java/me/jcala/blog/service/MonitorSerImpl.java index 8581c59..59e7009 100644 --- a/src/main/java/me/jcala/blog/service/MoniterSerImpl.java +++ b/src/main/java/me/jcala/blog/service/MonitorSerImpl.java @@ -1,25 +1,19 @@ package me.jcala.blog.service; import com.sun.management.OperatingSystemMXBean; -import me.jcala.blog.service.inter.MoniterSer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import me.jcala.blog.service.inter.MonitorSer; import org.springframework.stereotype.Service; import java.lang.management.ManagementFactory; -/** - * Created by Administrator on 2016/9/13. - */ @Service -public class MoniterSerImpl implements MoniterSer { - private static final Logger LOGGER = LoggerFactory.getLogger(MoniterSerImpl.class); +public class MonitorSerImpl implements MonitorSer { @Override - public int getFreeMemery(){ + public int getFreeMemory(){ OperatingSystemMXBean osmxb = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class); - long totalvirtualMemory = osmxb.getTotalPhysicalMemorySize(); + long totalVirtualMemory = osmxb.getTotalPhysicalMemorySize(); long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize(); - Double compare = (freePhysicalMemorySize * 1.0 / totalvirtualMemory) * 100; + Double compare = (freePhysicalMemorySize * 1.0 / totalVirtualMemory) * 100; return compare.intValue(); } } diff --git a/src/main/java/me/jcala/blog/service/ProjectSerImpl.java b/src/main/java/me/jcala/blog/service/ProjectSerImpl.java index da03300..1c5e079 100644 --- a/src/main/java/me/jcala/blog/service/ProjectSerImpl.java +++ b/src/main/java/me/jcala/blog/service/ProjectSerImpl.java @@ -17,26 +17,21 @@ import java.util.ArrayList; import java.util.List; -/** - * Created by Administrator on 2016/9/16. - */ @Service public class ProjectSerImpl implements ProjectSer { - private static final Logger LOGGER = LoggerFactory.getLogger(ProjectSerImpl.class); - @Autowired + private ProjectMapper projectMapper; + @Autowired + public ProjectSerImpl(ProjectMapper projectMapper) { + this.projectMapper = projectMapper; + } + @Override @Cacheable(value = "projects",condition = "#page==1",key = "1") - public List getPros(int page) { - List projectList = new ArrayList<>(); + public List getPros(int page){ int start = (page - 1) * 5; - try { - projectList = projectMapper.select(start); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return projectList; + return projectMapper.select(start); } @Override @@ -45,36 +40,21 @@ public List getPros(int page) { @CacheEvict(value = "projectPageNum",key = "1") }) @Transactional(isolation = Isolation.READ_COMMITTED) - public void addPro(Project project) { + public void addPro(Project project){ Timestamp timestamp = new Timestamp(System.currentTimeMillis()); project.setDate(timestamp); - try { - projectMapper.insert(project); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + projectMapper.insert(project); } @Override - public List adminGetPros(int page) { + public List adminGetPros(int page){ int start = (page - 1) * 10; - List projectList = new ArrayList<>(); - try { - projectList = projectMapper.adminSelect(start); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return projectList; + return projectMapper.adminSelect(start); } @Override - public int adminGetPageNum() { - int count = 0; - try { - count = projectMapper.count(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + public int adminGetPageNum(){ + int count = projectMapper.count(); return count % 10 == 0 ? count / 10 : count / 10 + 1; } @@ -83,46 +63,26 @@ public int adminGetPageNum() { @CacheEvict(value = "projects",key = "1"), @CacheEvict(value = "projectPageNum",key = "1") }) - public void deletePro(int id) { - try { + public void deletePro(int id){ projectMapper.delete(id); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } } @Override - public Project getProById(String idStr) { - int id = 1; - Project project = new Project(); - try { - id = Integer.valueOf(idStr); - project = projectMapper.selectById(id); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - return project; + public Project getProById(String idStr){ + int id = Integer.valueOf(idStr); + return projectMapper.selectById(id); } @Override @CacheEvict(value = "projects",key = "1") public void updatePro(Project project) { - try { projectMapper.Update(project); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } } @Override @Cacheable(value = "projectPageNum",key = "1") - public int getPageNum() { - int count = 0; - try { - count = projectMapper.count(); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + public int getPageNum(){ + int count = projectMapper.count(); return count % 5 == 0 ? count / 5 : count / 5 + 1; } } diff --git a/src/main/java/me/jcala/blog/service/inter/FileUploadSer.java b/src/main/java/me/jcala/blog/service/inter/FileUploadSer.java index 45753c6..69cf2c2 100644 --- a/src/main/java/me/jcala/blog/service/inter/FileUploadSer.java +++ b/src/main/java/me/jcala/blog/service/inter/FileUploadSer.java @@ -2,14 +2,13 @@ import me.jcala.blog.domain.Info; import me.jcala.blog.domain.UploadPic; +import org.springframework.http.ResponseEntity; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; -/** - * Created by Administrator on 2016/9/25. - */ public interface FileUploadSer { UploadPic uploadPic(HttpServletRequest request); Info updateAvatar(HttpServletRequest request); + ResponseEntity gainPic(String dir, String picName); } diff --git a/src/main/java/me/jcala/blog/service/inter/MoniterSer.java b/src/main/java/me/jcala/blog/service/inter/MonitorSer.java similarity index 62% rename from src/main/java/me/jcala/blog/service/inter/MoniterSer.java rename to src/main/java/me/jcala/blog/service/inter/MonitorSer.java index 240dd89..a27b6f4 100644 --- a/src/main/java/me/jcala/blog/service/inter/MoniterSer.java +++ b/src/main/java/me/jcala/blog/service/inter/MonitorSer.java @@ -3,7 +3,7 @@ /** * 监控页面的service接口 */ -public interface MoniterSer { +public interface MonitorSer { // List getVisiters();//获取访问人数列表 - int getFreeMemery();//获取剩余内存百分比 + int getFreeMemory();//获取剩余内存百分比 } diff --git a/src/main/java/me/jcala/blog/utils/FileTools.java b/src/main/java/me/jcala/blog/utils/FileTools.java index fbb1df1..85f34b8 100644 --- a/src/main/java/me/jcala/blog/utils/FileTools.java +++ b/src/main/java/me/jcala/blog/utils/FileTools.java @@ -1,8 +1,21 @@ package me.jcala.blog.utils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +import static org.springframework.util.StreamUtils.copy; + /** * 文件操作工具类 */ +@Slf4j public class FileTools { /** * 获取文件后缀 @@ -16,4 +29,77 @@ public static String getSuffix(String fileName){ return ""; } } + public static boolean isLinuxPath(String path){ + return path.contains("/"); + } + + /** + * 读取文件为字节数组 + */ + public static byte[] readFileToByteArray(final File file) throws IOException { + InputStream in = openInputStream(file); + final ByteArrayOutputStream output = new ByteArrayOutputStream(); + copy(in, output); + return output.toByteArray(); + } + private static FileInputStream openInputStream(final File file) throws IOException { + if (file.exists()) { + if (file.isDirectory()) { + throw new IOException("File '" + file + "' exists but is a directory"); + } + if (!file.canRead()) { + throw new IOException("File '" + file + "' cannot be read"); + } + } else { + throw new RuntimeException("File '" + file + "' does not exist"); + } + return new FileInputStream(file); + } + public static String updatePic(String restUrl,String picHome,HttpServletRequest request) + throws Exception { + + MultipartFile multipartFile = getMultipartFile(request); + + //设置图片名称为currentTimeMillis+文件后缀 + String fileName = String.valueOf(System.currentTimeMillis()) + "." + + FileTools.getSuffix(multipartFile.getOriginalFilename()); + //获取当前年月 + String yearMonth = TimeTools.getYearMonthOfNow(); + + //图片存储路径为根路径/年月。比如user/jcala/xmarket/201608 + File path = new File(picHome+File.separatorChar+ yearMonth); + + //合成图片在服务器上的绝对路径 + File targetFile = new File(picHome+File.separatorChar + yearMonth + File.separatorChar + fileName); + if (!path.exists()) { + path.mkdirs(); + } + //保存图片 + multipartFile.transferTo(targetFile); + return getServerRoot(request) + restUrl + yearMonth + "/" + fileName; + } + + /** + * 从HttpServletRequest中获取MultipartFile + */ + private static MultipartFile getMultipartFile(HttpServletRequest request) { + MultipartHttpServletRequest multipartRequest = + (MultipartHttpServletRequest) request; + Iterator fileNames = multipartRequest.getFileNames(); + return multipartRequest.getFile(fileNames.next()); + } + + /** + * 获取web服务器访问url根路径 + */ + private static String getServerRoot(HttpServletRequest request){ + String serverRoot = ""; + try { + serverRoot=new URL(request.getScheme(), request.getServerName(), request.getServerPort(), + request.getContextPath()).toString(); + } catch (MalformedURLException e) { + log.warn(e.getLocalizedMessage()); + } + return serverRoot; + } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index f183da7..5c4ca93 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -20,7 +20,7 @@ spring: cache: true charset: UTF-8 view-names: error,index,projects,tags,tagView,archives,post,about,login,admin/blog_add,admin/project, - admin/moniter,admin/blog_modify,admin/blog_list,admin/info,admin/result,admin/resume + admin/monitor,admin/blog_modify,admin/blog_list,admin/info,admin/result,admin/resume properties: input.encoding: UTF-8 output.encoding: UTF-8 @@ -54,8 +54,5 @@ mybatis: type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping type-handlers-package: org.apache.ibatis.type.LocalDateTypeHandler config-location: classpath:mybatis-config.xml -reverse: - domain: http://127.0.0.1 - port: 8090 - prefix: jcala_blog - path: /home/jcala/blog +pic: + home: G:\home\jcala\xmarket\pic diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 6c9c9ad..43d11b7 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -19,8 +19,8 @@ spring: velocity: cache: true charset: UTF-8 - view-names: error,index,projects,tags,tagView,archives,post,about,login,admin/blog_add,admin/project, - admin/moniter,admin/blog_modify,admin/blog_list,admin/info,admin/result,admin/resume + view-names: error,error500,index,projects,tags,tagView,archives,post,about,login,admin/blog_add,admin/project, + admin/monitor,admin/blog_modify,admin/blog_list,admin/info,admin/result,admin/resume properties: input.encoding: UTF-8 output.encoding: UTF-8 @@ -54,8 +54,5 @@ mybatis: type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping type-handlers-package: org.apache.ibatis.type.LocalDateTypeHandler config-location: classpath:mybatis-config.xml -reverse: - domain: http://127.0.0.1 - port: 8090 - prefix: jcala_blog - path: /home/jcala/blog \ No newline at end of file +pic: + home: /home/jcala/blog/pic \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index caf4dfc..90385b2 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: dev \ No newline at end of file + active: prod \ No newline at end of file diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql new file mode 100644 index 0000000..1a855aa --- /dev/null +++ b/src/main/resources/data.sql @@ -0,0 +1,15 @@ +/*Data for the table `admin` */ + +insert into `admin`(`username`,`password`,`email`,`github`,`twitter`,`md`,`resume`,`avatar`) values ('jcala','21232f297a57a5a743894a0e4a801fc3','#','#','#','### 联系方式\r\n- **Email:** jcalaz@163.com\r\n- ** QQ:** 1142966796\r\n\r\n---\r\n\r\n###个人信息\r\n- **姓名:** 左志鹏\r\n- **性别:** 男\r\n- **学历:** 西南交通大学(2013-2017)本科,信息科学与技术学院电科专业\r\n- **技术博客:** http://www.jcala.me\r\n- **Github:** https://github.com/jcalaz\r\n- **工作年限:** 半年\r\n- **期望职位:**java web开发工程师,java后端工程师\r\n- **期望城市:**成都,天津\r\n\r\n---\r\n\r\n###优势\r\n\r\n\r\n---\r\n\r\n\r\n','

联系方式

\r\n
\r\n

个人信息

    \r\n
  • 姓名: 左志鹏
  • 性别:
  • 学历: 西南交通大学(2013-2017)本科,信息科学与技术学院电科专业
  • 技术博客: http://www.jcala.me
  • Github: https://github.com/jcalaz
  • 工作年限: 半年
  • 期望职位:java web开发工程师,java后端工程师
  • 期望城市:成都,天津
\r\n
\r\n

优势


\r\n','/img/avatar.jpg'); + +/*Data for the table `blog_view` */ + +insert into `blog_view`(`vid`,`date`,`title`,`article`,`tags`,`md`) values (23,'2016-09-10','springBoot整合mybatis','

为什么使用Mybatis?

\r\n

Mybatis是目前很火的SSM框架中的ORM组件,相比Hibernate更加灵活小巧,学习成本也更低,我觉得可维护性也更好些。

\r\n
\r\n

但是spring boot官方更只提供了自家的spring data jpa及hibernate的整合方案,而没有给出Mybatis的整合组件。于是上Github,发现了Mybatis提供了它的spring-boot-starter。

\r\n

整合方法

    \r\n
  1. gradle中加入依赖

    1. compile(\"org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1\")
    \r\n
    spring.boot:mybatis-spring-boot-starter中已经包含了对mybatis和mybatis-spring的依赖
  2. 在application.yml中配置mybatis

    1. mybatis:
    2. #指定mapper和domain(实体)所在的包
    3. type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping
    4. #指定使用的类型转换器
    5. type-handlers-package: org.apache.ibatis.type.LocalDateTypeHandler

    除此之外mybatis还提供了一下配置

    \r\n
    1. mybatis:
    2. config-location: #mybatis的xml注册文件位置
    3. mapper-locations: #Mapper xml config files (optional)
    4. executor-type: #执行类型为: SIMPLE, REUSE还是BATCH
    5. configuration: #mybatis的其他配置
  3. 在Spring Boot中配置好数据源DataSource

    可以使用任意数据源,mybatis会自动使用spring boot中所配置的数据库连接池
\r\n

以上就完成了spring boot对mybatis的整合,超级简单啊

\r\n

测试一下

因为在type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping中指定的mapping扫描包为me.jcala.blog.mapping,所以要把写的mapper放到me.jcala.blog.mapping包下。

\r\n

在me.jcala.blog.mapping下新建一个TestMapper接口

  1. @Repository
  2. @Mapper
  3. public interface TestMapper {
  4. @Insert(\"insert into users set username=\'zzp\',password=\'zzp105\'\")
  5. void insert();
  6. }
\r\n

再随便写一个测试的类

  1. public class TestForMapper{
  2. @Autowired
  3. TestMapper testMapper;
  4. @Test
  5. public void testInsert(){
  6. testMapper.insert();
  7. }
  8. }
','spring,springBoot,java,mybatis','#### 为什么使用Mybatis?\r\n> Mybatis是目前很火的SSM框架中的ORM组件,相比Hibernate更加灵活小巧,学习成本也更低,我觉得可维护性也更好些。\r\n\r\n但是spring boot官方更只提供了自家的spring data jpa及hibernate的整合方案,而没有给出Mybatis的整合组件。于是上Github,发现了Mybatis提供了它的spring-boot-starter。\r\n##整合方法\r\n\r\n1. #### gradle中加入依赖\r\n```groovy\r\ncompile(\"org.mybatis.spring.boot:mybatis-spring-boot-starter:1.1.1\")\r\n```\r\n###### spring.boot:mybatis-spring-boot-starter中已经包含了对mybatis和mybatis-spring的依赖\r\n\r\n2. #### 在application.yml中配置mybatis\r\n```\r\nmybatis:\r\n #指定mapper和domain(实体)所在的包\r\n type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping\r\n #指定使用的类型转换器\r\n type-handlers-package: org.apache.ibatis.type.LocalDateTypeHandler\r\n```\r\n除此之外mybatis还提供了一下配置\r\n```\r\nmybatis:\r\n config-location: #mybatis的xml注册文件位置\r\n mapper-locations: #Mapper xml config files (optional)\r\n executor-type: #执行类型为: SIMPLE, REUSE还是BATCH\r\n configuration: #mybatis的其他配置\r\n```\r\n3. #### 在Spring Boot中配置好数据源DataSource\r\n 可以使用任意数据源,mybatis会自动使用spring boot中所配置的数据库连接池\r\n\r\n以上就完成了spring boot对mybatis的整合,超级简单啊\r\n\r\n## 测试一下\r\n因为在type-aliases-package: me.jcala.blog.domain,me.jcala.blog.mapping中指定的mapping扫描包为me.jcala.blog.mapping,所以要把写的mapper放到me.jcala.blog.mapping包下。\r\n#### 在me.jcala.blog.mapping下新建一个TestMapper接口\r\n```java\r\n@Repository\r\n@Mapper\r\npublic interface TestMapper {\r\n @Insert(\"insert into users set username=\'zzp\',password=\'zzp105\'\")\r\n void insert();\r\n}\r\n```\r\n#### 再随便写一个测试的类\r\n```\r\npublic class TestForMapper{\r\n@Autowired\r\nTestMapper testMapper;\r\n@Test\r\npublic void testInsert(){\r\n testMapper.insert();\r\n }\r\n}\r\n```'),(34,'2016-10-05','undertow嵌入式web服务器初体验','

Github源码
做的一个项目,在这里开源,删除了大部分业务代码,将逐步改为一个基于netty5的框架,目前只算得上是一个手脚架吧

\r\n
\r\n

netty同时处理HTTP和Websocket,并将HTTP请求路由到相应Action中;使用ehcache实现Session;spring IOC做管理容器,mybatis
做sql数据库ORM;spring data mongoDB做mongo的ORM;HikariCP做sql数据库连接池;Gson用于json解析和生成;logback日志处理

\r\n
\r\n

netty处理HTTP和websocket

    \r\n
  • smart.core.netty.HttpHandler:是一个自定义的ChannelHandler用于处理HTTP
    和Websocket请求
  • Handler分别处理HTTP和Websocket
    1. public void messageReceived(ChannelHandlerContext ctx, Object msg) {
    2. if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作
    3. handleHttpRequest(ctx, (FullHttpRequest) msg);
    4. } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作
    5. handleWebSocketFrame(ctx, (WebSocketFrame) msg);
    6. }
    7. }
    \r\n
  • 由于websocket也是基于HTTP的,需要判断是websocket后,将HTTP升级为Websocket
    1. private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
    2. logger.warn(\"uri:\" + req.uri());
    3. if (req.uri().startsWith(\"/ws/join\")) {//如果urL开头为/ws/join则升级为websocket
    4. mac = wsBeforeHandler(ctx, req);
    5. if (mac == null || mac.length() < 1) {
    6. RespTools.paraErrorBack(ctx,req,null);
    7. return;
    8. }
    9. WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
    10. getWebSocketLocation(req), null, true);
    11. handshaker = wsFactory.newHandshaker(req);
    12. if (handshaker == null) {
    13. WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
    14. } else {
    15. handshaker.handshake(ctx.channel(), req);
    16. }
    17. } else {//是HTTP请求则路由到Action
    18. RouteResult<Action> routeResult = rs.getRouter().route(req.method(), req.uri());
    19. Action action = routeResult.target();
    20. action.act(ctx, req);
    21. }
    22. }
    \r\n
  • websocket请求处理,这里是从websocket请求中获取客户端传来的json字符串,并将字符串转为javabean
\r\n
  1. private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
  2. // Check for closing frame
  3. if (frame instanceof CloseWebSocketFrame) {
  4. handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
  5. return;
  6. }
  7. if (frame instanceof PingWebSocketFrame) {
  8. ctx.write(new PongWebSocketFrame(frame.content().retain()));
  9. return;
  10. }
  11. if (frame instanceof TextWebSocketFrame) {
  12. devicePool.join(ctx.channel(), mac);
  13. String json = ((TextWebSocketFrame) frame).text();
  14. Logic.ReqRespType data= JsonTools.read(json,Logic.ReqRespType.class);
  15. //...
  16. return;
  17. }
  18. }
\r\n
    \r\n
  • 如果是HTTP则需在RouterSetting中配置路由.
    比如r.POST(“api/get_verify_code”, getVerifyCodeAct):
    将url为”api/get_verify_code”的POST请求路由到LoginAct中

    \r\n
    1. public class RouterSetting {
    2. @Autowired
    3. private Router<Action> router;
    4. @Autowired
    5. private GetVerifyCodeAct getVerifyCodeAct;//w
    6. @Autowired
    7. private LoginAct loginAct;
    8. @Autowired
    9. private RegisterAct registerAcc;
    10. public Router<Action> getRouter() {
    11. routerConfig(this.router);
    12. return this.router;
    13. }
    14. private void routerConfig(Router<Action> r) {
    15. r.POST(\"api/get_verify_code\", getVerifyCodeAct);
    16. r.ANY(\"api/login\", loginAct);
    17. r.GET(\"api/register\", registerAcc);
    18. }
    19. }
    \r\n
  • Action处理HTTP请求并返回
\r\n
  1. @Controller
  2. public class LoginAct implements Action {
  3. private static final Logger logger = LoggerFactory.getLogger(LoginAct.class);
  4. @Override
  5. public void act(ChannelHandlerContext ctx, FullHttpRequest req) {
  6. String ip = HttpTools.getIp(req);
  7. String body = Convert.buf2Str(req.content());
  8. Get.Login get = JsonTools.read(body, Get.Login.class);//1.得到HTTP传来的json数据解析为javabean
  9. Sub.Register back;//构建返回给客户端的javabean的实例
  10. //...
  11. HttpTools.sendCorrectResp(ctx, req, back);//返回给客户端HTTP Response
  12. }
  13. }
\r\n
    \r\n
  • 添加Session(依靠ehcache)
\r\n
  1. private void addSession(long userId, String ip) {
  2. Logic.DeviceSession session = new Logic.DeviceSession(ip, \"\");
  3. Cache.add(userId + \"\", session, \"6mn\");//设置session的缓存时间为6分钟
  4. //debugSession(userId);
  5. }
\r\n
    \r\n
  • 从HTTP请求中获取IP地址
    1. String ip = HttpTools.getIp(req);

    netty参数设置

    1. port=8090
    2. netty.boss.thread.count=2
    3. netty.worker.thread.count=1
    4. netty.so.keepalive=true
    5. netty.so.backlog=100

    项目依赖

    1. //---------------------单元测试----------------------------
    2. testCompile group: \'junit\', name: \'junit\', version: \'4.11\'
    3. //--------------------数据库驱动----------------------------
    4. compile \'org.mongodb:mongodb-driver:3.2.2\'
    5. compile \'mysql:mysql-connector-java:5.1.38\'
    6. //-------------------数据库连接池---------------------------
    7. compile \'com.zaxxer:HikariCP:2.4.5\'
    8. //----------------------ORM------------------------------
    9. compile group: \'org.mybatis\', name: \'mybatis\', version:mybatisVersion
    10. compile group: \'org.mybatis\', name: \'mybatis-spring\', version:mybatisSpringVersion
    11. //-----------------------缓存----------------------------
    12. compile group: \'net.sf.ehcache\', name: \'ehcache\', version:ehcacheVersion
    13. //----------------------工具包----------------------------
    14. compile \'commons-httpclient:commons-httpclient:3.1-rc1\'
    15. compile \'org.javassist:javassist:3.20.0-GA\'
    16. //---------------------日志处理----------------------------
    17. compile \'org.slf4j:slf4j-api:1.7.21\'
    18. compile \'ch.qos.logback:logback-core:1.1.7\'
    19. compile \'ch.qos.logback:logback-classic:1.1.7\'
    20. //---------------------json处理---------------------------
    21. compile \'com.google.code.gson:gson:2.6.2\'
    22. //---------------------netty-----------------------------
    23. compile group: \'io.netty\', name: \'netty-all\', version:nettyVersion
    24. //---------------------spring----------------------------
    25. compile group: \'org.springframework\', name: \'spring-test\', version:springVersion
    26. compile group: \'org.springframework\', name: \'spring-jdbc\', version:springVersion
    27. compile(group: \'org.springframework\', name: \'spring-context\', version:springVersion) {
    28. exclude(module: \'commons-logging\')
    29. }
    \r\n
\r\n','undertow','[Github源码](https://github.com/jcalaz/nettyServer)\r\n做的一个项目,在这里开源,删除了大部分业务代码,将逐步改为一个基于netty5的框架,目前只算得上是一个手脚架吧\r\n\r\n> netty同时处理HTTP和Websocket,并将HTTP请求路由到相应Action中;使用ehcache实现Session;spring IOC做管理容器,mybatis\r\n做sql数据库ORM;spring data mongoDB做mongo的ORM;HikariCP做sql数据库连接池;Gson用于json解析和生成;logback日志处理\r\n\r\n####netty处理HTTP和websocket\r\n- smart.core.netty.HttpHandler:是一个自定义的ChannelHandler用于处理HTTP\r\n和Websocket请求\r\n- Handler分别处理HTTP和Websocket\r\n```java\r\npublic void messageReceived(ChannelHandlerContext ctx, Object msg) {\r\n if (msg instanceof FullHttpRequest) {//如果是HTTP请求,进行HTTP操作\r\n handleHttpRequest(ctx, (FullHttpRequest) msg);\r\n } else if (msg instanceof WebSocketFrame) {//如果是Websocket请求,则进行websocket操作\r\n handleWebSocketFrame(ctx, (WebSocketFrame) msg);\r\n }\r\n }\r\n```\r\n- 由于websocket也是基于HTTP的,需要判断是websocket后,将HTTP升级为Websocket\r\n```java\r\nprivate void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {\r\n logger.warn(\"uri:\" + req.uri());\r\n if (req.uri().startsWith(\"/ws/join\")) {//如果urL开头为/ws/join则升级为websocket\r\n mac = wsBeforeHandler(ctx, req);\r\n if (mac == null || mac.length() < 1) {\r\n RespTools.paraErrorBack(ctx,req,null);\r\n return;\r\n }\r\n WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(\r\n getWebSocketLocation(req), null, true);\r\n handshaker = wsFactory.newHandshaker(req);\r\n if (handshaker == null) {\r\n WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());\r\n } else {\r\n handshaker.handshake(ctx.channel(), req);\r\n }\r\n } else {//是HTTP请求则路由到Action\r\n RouteResult routeResult = rs.getRouter().route(req.method(), req.uri());\r\n Action action = routeResult.target();\r\n action.act(ctx, req);\r\n }\r\n }\r\n```\r\n- websocket请求处理,这里是从websocket请求中获取客户端传来的json字符串,并将字符串转为javabean\r\n\r\n```java\r\nprivate void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {\r\n\r\n // Check for closing frame\r\n if (frame instanceof CloseWebSocketFrame) {\r\n handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());\r\n return;\r\n }\r\n if (frame instanceof PingWebSocketFrame) {\r\n ctx.write(new PongWebSocketFrame(frame.content().retain()));\r\n return;\r\n }\r\n if (frame instanceof TextWebSocketFrame) {\r\n devicePool.join(ctx.channel(), mac);\r\n String json = ((TextWebSocketFrame) frame).text();\r\n Logic.ReqRespType data= JsonTools.read(json,Logic.ReqRespType.class);\r\n //...\r\n return;\r\n }\r\n }\r\n```\r\n- 如果是HTTP则需在RouterSetting中配置路由.\r\n比如r.POST(\"api/get_verify_code\", getVerifyCodeAct):\r\n将url为\"api/get_verify_code\"的POST请求路由到LoginAct中\r\n```java\r\npublic class RouterSetting {\r\n @Autowired\r\n private Router router;\r\n @Autowired\r\n private GetVerifyCodeAct getVerifyCodeAct;//w\r\n @Autowired\r\n private LoginAct loginAct;\r\n @Autowired\r\n private RegisterAct registerAcc;\r\n\r\n public Router getRouter() {\r\n routerConfig(this.router);\r\n return this.router;\r\n }\r\n\r\n private void routerConfig(Router r) {\r\n r.POST(\"api/get_verify_code\", getVerifyCodeAct);\r\n r.ANY(\"api/login\", loginAct);\r\n r.GET(\"api/register\", registerAcc);\r\n }\r\n}\r\n```\r\n- Action处理HTTP请求并返回\r\n\r\n```java\r\n@Controller\r\npublic class LoginAct implements Action {\r\n private static final Logger logger = LoggerFactory.getLogger(LoginAct.class);\r\n @Override\r\n public void act(ChannelHandlerContext ctx, FullHttpRequest req) {\r\n String ip = HttpTools.getIp(req);\r\n String body = Convert.buf2Str(req.content());\r\n Get.Login get = JsonTools.read(body, Get.Login.class);//1.得到HTTP传来的json数据解析为javabean\r\n Sub.Register back;//构建返回给客户端的javabean的实例\r\n //...\r\n HttpTools.sendCorrectResp(ctx, req, back);//返回给客户端HTTP Response\r\n }\r\n}\r\n\r\n```\r\n- 添加Session(依靠ehcache)\r\n\r\n```java\r\nprivate void addSession(long userId, String ip) {\r\n Logic.DeviceSession session = new Logic.DeviceSession(ip, \"\");\r\n Cache.add(userId + \"\", session, \"6mn\");//设置session的缓存时间为6分钟\r\n //debugSession(userId);\r\n }\r\n```\r\n- 从HTTP请求中获取IP地址\r\n```\r\nString ip = HttpTools.getIp(req);\r\n```\r\n####netty参数设置\r\n```\r\nport=8090\r\nnetty.boss.thread.count=2\r\nnetty.worker.thread.count=1\r\nnetty.so.keepalive=true\r\nnetty.so.backlog=100\r\n```\r\n####项目依赖\r\n```groovy\r\n //---------------------单元测试----------------------------\r\n testCompile group: \'junit\', name: \'junit\', version: \'4.11\'\r\n //--------------------数据库驱动----------------------------\r\n compile \'org.mongodb:mongodb-driver:3.2.2\'\r\n compile \'mysql:mysql-connector-java:5.1.38\'\r\n //-------------------数据库连接池---------------------------\r\n compile \'com.zaxxer:HikariCP:2.4.5\'\r\n //----------------------ORM------------------------------\r\n compile group: \'org.mybatis\', name: \'mybatis\', version:mybatisVersion\r\n compile group: \'org.mybatis\', name: \'mybatis-spring\', version:mybatisSpringVersion\r\n //-----------------------缓存----------------------------\r\n compile group: \'net.sf.ehcache\', name: \'ehcache\', version:ehcacheVersion\r\n //----------------------工具包----------------------------\r\n compile \'commons-httpclient:commons-httpclient:3.1-rc1\'\r\n compile \'org.javassist:javassist:3.20.0-GA\'\r\n //---------------------日志处理----------------------------\r\n compile \'org.slf4j:slf4j-api:1.7.21\'\r\n compile \'ch.qos.logback:logback-core:1.1.7\'\r\n compile \'ch.qos.logback:logback-classic:1.1.7\'\r\n //---------------------json处理---------------------------\r\n compile \'com.google.code.gson:gson:2.6.2\'\r\n //---------------------netty-----------------------------\r\n compile group: \'io.netty\', name: \'netty-all\', version:nettyVersion\r\n //---------------------spring----------------------------\r\n compile group: \'org.springframework\', name: \'spring-test\', version:springVersion\r\n compile group: \'org.springframework\', name: \'spring-jdbc\', version:springVersion\r\n compile(group: \'org.springframework\', name: \'spring-context\', version:springVersion) {\r\n exclude(module: \'commons-logging\')\r\n }\r\n```'); + +/*Data for the table `project` */ + +insert into `project`(`id`,`name`,`url`,`tech`,`desp`,`date`) values (1,'jcalaBlog','https://github.com/jcalaz/jcalaBlog','springBoot+springMVC+undertow+mybatis+velocity+lombok\r\n+。。。','基于springboot的响应式个人博客','2016-11-16 14:40:56'); + +/*Data for the table `view_tag` */ + +insert into `view_tag`(`name`,`vid`) values ('java',23),('mybatis',23),('spring',23),('springBoot',23),('undertow',34); \ No newline at end of file diff --git a/src/main/resources/import.sql b/src/main/resources/import.sql new file mode 100644 index 0000000..45fbe9b --- /dev/null +++ b/src/main/resources/import.sql @@ -0,0 +1,73 @@ +/*!40101 SET NAMES utf8 */; + +/*!40101 SET SQL_MODE=''*/; + +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +CREATE DATABASE IF NOT EXISTS `jcala_blog` /*!40100 DEFAULT CHARACTER SET utf8 */; + +USE `jcala_blog`; + +/*Table structure for table `admin` */ + +DROP TABLE IF EXISTS `admin`; + +CREATE TABLE `admin` ( + `username` varchar(50) NOT NULL, + `password` varchar(50) NOT NULL, + `email` varchar(64) DEFAULT '#', + `github` varchar(64) NOT NULL DEFAULT '#', + `twitter` varchar(64) NOT NULL DEFAULT '#', + `md` text, + `resume` text, + `avatar` varchar(80) NOT NULL DEFAULT '/img/avatar.jpg', + PRIMARY KEY (`username`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*Table structure for table `blog_view` */ + +DROP TABLE IF EXISTS `blog_view`; + +CREATE TABLE `blog_view` ( + `vid` int(11) NOT NULL AUTO_INCREMENT, + `date` date NOT NULL, + `title` varchar(50) NOT NULL, + `article` text NOT NULL, + `tags` varchar(80) NOT NULL, + `md` text NOT NULL, + PRIMARY KEY (`vid`) +) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8; + +/*Table structure for table `project` */ + +DROP TABLE IF EXISTS `project`; + +CREATE TABLE `project` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `url` varchar(60) NOT NULL DEFAULT '#', + `tech` varchar(250) NOT NULL, + `desp` text NOT NULL, + `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; + + +/*Table structure for table `view_tag` */ + +DROP TABLE IF EXISTS `view_tag`; + +CREATE TABLE `view_tag` ( + `name` varchar(40) NOT NULL, + `vid` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`name`,`vid`), + KEY `fk_vid` (`vid`), + CONSTRAINT `fk_vid` FOREIGN KEY (`vid`) REFERENCES `blog_view` (`vid`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/src/main/resources/templates/admin/info.vm b/src/main/resources/templates/admin/info.vm index bb0e8c7..f9f1172 100644 --- a/src/main/resources/templates/admin/info.vm +++ b/src/main/resources/templates/admin/info.vm @@ -16,6 +16,7 @@
@@ -56,6 +57,16 @@
+
+
+ +
+
+ + +
+
+ diff --git a/src/main/resources/templates/admin/moniter.vm b/src/main/resources/templates/admin/monitor.vm similarity index 100% rename from src/main/resources/templates/admin/moniter.vm rename to src/main/resources/templates/admin/monitor.vm diff --git a/src/main/resources/templates/login.vm b/src/main/resources/templates/login.vm index a8c423d..0176328 100644 --- a/src/main/resources/templates/login.vm +++ b/src/main/resources/templates/login.vm @@ -8,7 +8,8 @@ - +