网站建设品牌营销,网站开发需要多少钱,建设北京公司网站,wordpress标签是干什么的访问地址:用户登录
代码获取:基于Spring实现博客项目: Spring项目写博客项目 一.项目开发
1.项目开发阶段
需求评审,需求分析项目设计(接口设计,DB设计等#xff0c;比较大的需求,需要设计流程图#xff0c;用例图,UML, model中的字段)开发#xff0b;自测提测(提交测试…访问地址:用户登录
代码获取:基于Spring实现博客项目: Spring项目写博客项目 一.项目开发
1.项目开发阶段
需求评审,需求分析项目设计(接口设计,DB设计等比较大的需求,需要设计流程图用例图,UML, model中的字段)开发自测提测(提交测试)验收:预发布环境/预生产环境部署测试(开发,测试,产品)上线
2.前端页面
1.登录页面: 根据用户名和密码,进行登录 2.博客列表页:显示所有博客列表,以及显示登录用户的个人信息 3.博客详情页:显示当前博客的详细信息,以及作者信息 4.博客插入/编辑页
3.需求分析
1.登录接口(根据用户名和密码,来判断是否登录成功) 2.根据用户ID,获取用户相关信息 3.获取所有的博客列表 4.根据博客ID,获取博客的详情信息(作者ID) 5.根据博客ID,更新博客内容 6.插入博客 7.删除博客
4.数据库设计 --建表sqlcreate database if not exists java_blog_spring charset utf8mb4;--用户表drop table if exists java_blog_spring.user;create table java_blog_spring.user (id int not null auto_increment,user_name varchar(128) not null,password varchar(128) not null,github_url varchar(128) null,delete_flag tinyint(4) null default 0,create_time timestamp null default current_timestamp(),primary key (id),unique index user_name_unique (user_name asc))engine innodb default character set utf8mb4 comment ⽤户表;--博客表drop table if exists java_blog_spring.blog;create table java_blog_spring.blog (id int not null auto_increment,title varchar(200) null,content text null,user_id int(11) null,delete_flag tinyint(4) null default 0,create_time timestamp null default current_timestamp(),primary key (id))engine innodb default charset utf8mb4 comment 博客表;--新增用户信息insert into java_blog_spring.user (user_name, password,github_url)values(zhangsan,123456,https://gitee.com/bubble-fish666/class-java45);insert into java_blog_spring.user (user_name, password,github_url)values(lisi,123456,https://gitee.com/bubble-fish666/class-java45);insert into java_blog_spring.blog (title,content,user_id) values(第一篇博客,111我是博客正文我是博客正文我是博客正文,1);insert into java_blog_spring.blog (title,content,user_id) values(第二篇博客,222我是博客正文我是博客正文我是博客正文,2);
二.Java项目
1.创建Spring项目 创建好之后为以下页面 2.创建实体类 用户实体类
Data
public class User {private Integer id;private String userName;private String password;private String githubUrl;private Byte deleteFlag;private Date createTime;
}
博客实体类
Data
public class Blog {private Integer id;private String title;private String content;private Integer userId;private Byte deleteFlag;private Date createTime;
}3.创建Mapper
userMapper.java
Mapper
public interface UserMapper {Select(select * from user where id#{id})User selectById(Integer id);Select(select * from user where user_name#{name})User selectByName(String name);
}userMapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.javastudy.blog_spring.mapper.UserMapper/mapper
blogMapper.java
Mapper
public interface BlogMapper {Select(select * from blog where delete_flag0)ListBlog selectAll();Select(select * from blog where id#{id} and delete_flag0)Blog selectById(Integer id);Integer updateBlog(Blog blog);Insert(insert into blog(content,title,user_id) values(#{content},#{title},#{userId}))Integer insertBlog(Blog blog);
}blogMapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.javastudy.blog_spring.mapper.BlogMapperupdate idupdateBlogupdate blogsetif testtitle!nulltitle#{title},/ifif testcontent!nullcontent#{content},/ifif testuserId!nulluser_id#{userId},/ifif testdeleteFlag!nulldelete_flag#{deleteFlag},/if/setwhere id#{id};/update/mapper
4.配置文件
application.yml
spring:profiles:active: dev# 日志信息
logging:file:path: logs/level:root: info
application-dev.yml
server:port: 8080# 数据库连接配置
spring:datasource:url: jdbc:mysql://localhost:13306/java_blog_spring?characterEncodingutf8useSSLfalseusername: rootpassword: woaini520driver-class-name: com.mysql.cj.jdbc.Driver# mybatis xml 配置路径
mybatis:mapper-locations: classpath:mapper/**Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true #驼峰转换
application-prod.yml
server:port: 8080# 数据库连接配置
spring:datasource:url: jdbc:mysql://localhost:3306/java_blog_spring?characterEncodingutf8useSSLfalseusername: rootpassword: woaini520driver-class-name: com.mysql.cj.jdbc.Driver# mybatis xml 配置路径
mybatis:mapper-locations: classpath:mapper/**Mapper.xmlconfiguration:map-underscore-to-camel-case: true
5.测试类
userMapper
SpringBootTest
Slf4j
class UserMapperTest {AutowiredUserMapper userMapper;Testvoid selectById() {User user userMapper.selectById(1);log.info(user.toString());}Testvoid selectByName() {User user userMapper.selectByName(zhangsan);log.info(user.toString());}
} blogMapper
SpringBootTest
Slf4j
class BlogMapperTest {AutowiredBlogMapper blogMapper;Testvoid selectAll() {ListBlog blogs blogMapper.selectAll();log.info(blogs.toString());}Testvoid selectById() {Blog blog blogMapper.selectById(1);log.info(blog.toString());}Testvoid updateBlog() {Blog blog new Blog();blog.setId(1);blog.setTitle(测试的第一篇博客);blog.setTitle(测试的第一篇博客的正文内容);blogMapper.updateBlog(blog);}Testvoid insertBlog() {Blog blog new Blog();blog.setTitle(第三篇博客);blog.setContent(第三篇博客的正文内容);blog.setUserId(1);blogMapper.insertBlog(blog);}
} 6.Common包
1.Result
Data
public class Result {//业务处理状态码 200成功 0表示失败 (注意与请求状态码区分)private Integer code;//业务返回信息private String msg;//业务数据private Object data;/*** 业务处理失败** param code* param message* return*/public static Result fail(Integer code, String message) {Result result new Result();result.setCode(code);result.setMsg(message);result.setData();return result;}public static Result fail(Integer code, String message, Object data) {Result result new Result();result.setCode(code);result.setMsg(message);result.setData(data);return result;}public static Result success(Object data) {Result result new Result();result.setCode(200);result.setMsg();result.setData(data);return result;}public static Result success(String message, Object data) {Result result new Result();result.setCode(200);result.setMsg(message);result.setData(data);return result;}}2.ErrorAdvice(统一异常返回)
ControllerAdvice
public class ErrorAdvice {ExceptionHandlerpublic Result error(Exception e) {return Result.fail(-1, e.getMessage());}
}3.统一返回格式处理
ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}SneakyThrowsOverridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof Result) {return body;}if (body instanceof String) {ObjectMapper objectMapper new ObjectMapper();return objectMapper.writeValueAsString(Result.success(body));}return Result.success(body);}}
7.导入前端代码
前端代码在这取:基于Spring实现博客项目: Spring项目写博客项目
三.业务代码
1.约定前后端交互接口 [请求] /blog/getlist [响应] [ { blogId: 1, title: 第⼀篇博客, content: 博客正⽂, userId: 1, postTime: 2021-07-07 12:00:00 }, { blogId: 2, title: 第⼆篇博客, content: 博客正⽂, userId: 1, postTime: 2021-07-07 12:10:00 }, 2.Service层
UserService
Service
public class UserService {Autowiredprivate UserMapper userMapper;Autowiredprivate BlogMapper blogMapper;public User selectById(Integer id) {return userMapper.selectById(id);}public User selectByName(String name) {return userMapper.selectByName(name);}public User getAuthorInfoByBlogId(Integer id) {Blog blog blogMapper.selectById(id);if (blog null || blog.getUserId() 0) {return null;}return userMapper.selectById(blog.getUserId());}
}BlogService
Service
public class BlogService {Autowiredprivate BlogMapper blogMapper;public ListBlog getAll() {return blogMapper.selectAll();}public Blog getBlogById(Integer id) {return blogMapper.selectById(id);}public Integer updateBlog(Blog blog) {return blogMapper.updateBlog(blog);}public Integer addBlog(Blog blog) {return blogMapper.insertBlog(blog);}}3.Controller层
BlogController
RestController
RequestMapping(/blog)
public class BlogController {AutowiredBlogService blogService;RequestMapping(/getlist)public ListBlog getBlogList() {return blogService.getAll();}RequestMapping(/getBlogDetail)public Result getBlogDetail(Integer id, HttpSession httpSession) {if (id null || id 0) {return Result.fail(-1, 非法的参数);}Blog blog blogService.getBlogById(id);User user (User) httpSession.getAttribute(Constants.USER_INFO_SESSION);if (blog.getUserId() user.getId()) {blog.setIsLoginUser(true);}return Result.success(blog);}RequestMapping(/add)public Result addBlog(String title, String content, HttpSession httpSession) {if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {return Result.fail(-1, 内容不能为空);}User user (User) httpSession.getAttribute(Constants.USER_INFO_SESSION);if (user null || user.getId() 0) {return Result.fail(-1, 用户不存在);}Blog blog new Blog();blog.setContent(content);blog.setTitle(title);blog.setUserId(user.getId());blogService.addBlog(blog);return Result.success(true);}RequestMapping(/update)public Result updateBlog(Blog blog) {if (!StringUtils.hasLength(blog.getContent()) || !StringUtils.hasLength(blog.getTitle()) || blog.getId() null) {return Result.fail(-1, 内容不能为空);}blogService.updateBlog(blog);return Result.success(true);}RequestMapping(/delete)public Result deleteBlog(RequestParam(id) Integer blogId) {if (blogId null || blogId 0) {return Result.fail(-1, 博客id不合法或者为空);}Blog blog new Blog();blog.setId(blogId);blog.setDeleteFlag((byte) 1);blogService.updateBlog(blog);return Result.success(true);}
}UserController
RestController
RequestMapping(/user)
public class UserController {AutowiredUserService userService;RequestMapping(/login)public Result login(HttpServletRequest request, String username, String password) {//参数校验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return Result.fail(-2, 账号或密码不能为空);}//密码校验User user userService.selectByName(username);if (user null || !user.getPassword().equals(password)) {return Result.fail(-3, 用户名不存在或者密码错误);}//参数返回user.setPassword();HttpSession session request.getSession(true);session.setAttribute(Constants.USER_INFO_SESSION, user);return Result.success(登陆成功);}RequestMapping(/getUserInfo)public Result getUserInfo(HttpSession session) {if (session null || session.getAttribute(Constants.USER_INFO_SESSION) null) {return Result.fail(-1, 用户未登录);}return Result.success(session.getAttribute(Constants.USER_INFO_SESSION));}RequestMapping(/getAuthorInfo)public Result getAuthorInfoByBlogId(RequestParam(id) Integer blogId) {if (blogId null || blogId 0) {return Result.fail(-1, id参数错误);}User user userService.getAuthorInfoByBlogId(blogId);if (user null) {return Result.fail(-1, 不存在文章作者);}user.setPassword();return Result.success(user);}RequestMapping(/logout)public Result logout(HttpSession session) {session.removeAttribute(Constants.USER_INFO_SESSION);return Result.success(true);}
}4.登录接口拦截器
Component
public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session request.getSession(false);if (session null || session.getAttribute(Constants.USER_INFO_SESSION) null) {response.setStatus(401);return false;}return true;}
}
Configuration
public class AppConfig implements WebMvcConfigurer {Autowiredprivate LoginInterceptor loginInterceptor;private final ListString excludes Arrays.asList(/**/*.html,/blog-editormd/**,/css/**,/js/**,/pic/**,/user/login);Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns(/**). //拦截所有路径excludePathPatterns(excludes);}
}在blog_list.html和blog_detail的ajax请求添加 error: function (error) {if (error ! null error.status 401) {location.assign(/blog_login.html);}}
四.前端代码
有些代码重复出现,可以抽象为一个函数,我们放在./js/common.js中
function logout() {$(#logout).click(function () {$.ajax({type: get,url: /user/logout,success: function (result) {if (result ! null result.data true) {location.assign(/blog_login.html)}},})})
}1.blog_list.html
先来个前置知识:日期格式化
方式一:将日期格式改为(java.sql.Date适用) private Timestamp createTime; 然后引入js包
function formatDate(time) {var date new Date(time);var year date.getFullYear(),month date.getMonth() 1,//月份是从0开始的day date.getDate(),hour date.getHours(),min date.getMinutes(),sec date.getSeconds();var newTime year - (month 10 ? 0 month : month) - (day 10 ? 0 day : day) (hour 10 ? 0 hour : hour) : (min 10 ? 0 min : min) : (sec 10 ? 0 sec : sec);return newTime;
} 直接进行转化即可
script src./js/common.js/script
formatDate(blog.createTime)
方式二:(java.util.Date适用)
工具类
public class DateUtils {public static String formatDate(Date date) {SimpleDateFormat simpleDateFormat new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);return simpleDateFormat.format(date);}
}博客实体类
Data
public class Blog {private Integer id;private String title;private String content;private Integer userId;private Byte deleteFlag;private Date createTime;public String getCreateTime() {return DateUtils.formatDate(createTime);}
}此时就不需要多余的操作了 finalHtml div classdateblog.createTime/div;之后javascrip代码 script src./js/jquery.min.js/scriptscript src./js/common.js/scriptscript$(function () {$.ajax({type: get,url: /blog/getlist,success: function (result) {var finalHtml ;if (result.code 200 result.data ! null result.data.length 0) {var dataHtml result.data;for (var i 0; i dataHtml.length; i) {var blog dataHtml[i];finalHtml div classblog;finalHtml div classtitle blog.title /div;finalHtml div classdate blog.createTime /div;finalHtml div classdesc blog.content /div;finalHtml a classdetail hrefblog_detail.html?id blog.id 查看全文gt;gt;/a;finalHtml /div;}$(.right).html(finalHtml);}},error: function (error) {if (error ! null error.status 401) {location.assign(/blog_login.html);}}});$.ajax({type: get,url: /user/getUserInfo,success: function (result) {if (result ! null result.code 200 result.data ! null) {$(.container .left .card h3).text(result.data.userName);$(.container .left .card a).attr(href, result.data.githubUrl)}},error: function (error) {if (error ! null error.status 401) {location.assign(/blog_login.html);}}});logout();})/script
2.blog_detail.html script src./js/jquery.min.js/scriptscript srcblog-editormd/editormd.js/scriptscript srcblog-editormd/lib/marked.min.js/scriptscript srcblog-editormd/lib/prettify.min.js/scriptscript srcjs/common.js/scriptscript$(function () {$.ajax({type: get,url: /blog/getBlogDetail location.search,success: function (result) {if (result.code 200 result.data ! null) {var blog result.data;$(.title).text(blog.title);$(.date).text(blog.createTime);editormd.markdownToHTML(content, {markdown: blog.content,});if (result.data.isLoginUser true) {var innerhtml ;innerhtml button onclickwindow.location.href \blog_update.html?id blog.id \编辑/button;innerhtml button onclickdeleteBlog()删除/button;$(.operating).html(innerhtml);}}},error: function (error) {if (error ! null error.status 401) {location.assign(/blog_login.html);}}});$.ajax({type: get,url: /user/getAuthorInfo location.search,success: function (result) {if (result ! null result.code 200 result.data ! null) {$(.container .left .card h3).text(result.data.userName);$(.container .left .card a).attr(href, result.data.githubUrl)}},error: function (error) {if (error ! null error.status 401) {location.assign(/blog_login.html);}}});// jQuery(#deleteButton).click(function () {// if (confirm(确定要删除吗?)) {// $.ajax({// type: post,// url: /blog/delete location.search,// success: function (result) {// if (result ! null result.data true) {// location.assign(blog_list.html);// }// }// })// }// });})function deleteBlog() {if (confirm(确定要删除吗?)) {$.ajax({type: post,url: /blog/delete location.search,success: function (result) {if (result ! null result.data true) {location.assign(blog_list.html);}}})}};logout();/script
3.blog_login.html script src./js/jquery.min.js/scriptscript$(function () {$(#submit).click(function () {//获取用户名var username jQuery(#username);if (!username.val()) {alert(用户名不能为空);username.focus();return;}//获取密码var password jQuery(#password);if (!password.val()) {alert(密码不能为空);password.focus();return;}$.ajax({type: post,url: /user/login,data: {username: username.val(),password: password.val()},success: function (result) {if(result.code200){//跳转到主页location.hrefblog_list.html;return;}else{//业务处理失败alert(result.msg);return;}},error: function () {}})})})/script
4.blog_edit.html script srcjs/jquery.min.js/scriptscript srcblog-editormd/editormd.min.js/scriptscript typetext/javascript$(function () {var editor editormd(editor, {width: 100%,height: 550px,path: blog-editormd/lib/});$(#submit).click(function () {$.ajax({type: post,url: /blog/add,data: {title: $(#title).val(),content: $(#content).val()},success: function (result) {if (result ! null result.data ! null result.data true) {location.assign(blog_list.html);}},error: function (result) {if (result ! null result.status 401) {alert(请登录之后再进行操作);}}})})});/script
5.blog_update.html script srcjs/jquery.min.js/scriptscript srcblog-editormd/editormd.min.js/scriptscript srcjs/common.js/scriptscript typetext/javascript$(function () {var editor editormd(editor, {width: 100%,height: 550px,path: blog-editormd/lib/});$.ajax({type: get,url: /blog/getBlogDetail location.search,success: function (result) {var blog result.data;if (result ! null result.code 200 result.data ! null) {$(#title).val(blog.title);$(#content).val(blog.content);$(#blogId).val(blog.id);}},error: function (result) {if (result ! null result.status 401) {alert(请登录之后再进行操作);}}});$(#submit).click(function () {$.ajax({type: post,url: /blog/update,data: {title: $(#title).val(),content: $(#content).val(),id: $(#blogId).val()},success: function (result) {if (result ! null result.data true) {location.assign(blog_list.html);}},error: function (result) {if (result ! null result.status 401) {alert(请登录之后再进行操作);}}})})});/script
五.加密措施
1.加密
假设我们的数据库被黑客进行劫持,那么用户的一些重要信息(比如密码,身份证号)就可能被获取,这样对用户是十分不利的,因此我们需要对数据库中一些重要的信息进行加密存储.
目前有许多的加密算法,包括可逆加密和非可逆加密,可逆加密在http和https的时候就有使用,通过密钥就可以使明文变为密文,同时也可以让密文变为明文,但是非可逆加密就不同了,非可逆加密只能使明文加密为密文,不能从密文变为明文,一般在数据库中我们采用非可逆加密.
常用的非可逆加密有MD5加密,通过对明文加密,可以得到长度固定的MD5值,MD5加密就可以得到32位或者16位的加密后的结果. Java中使用MD5加密
SpringBootTest
class BlogSpringApplicationTests {Testvoid contextLoads() {String finalPassword DigestUtils.md5DigestAsHex(123456.getBytes());System.out.println(第一次加密: finalPassword);finalPassword DigestUtils.md5DigestAsHex(123456.getBytes());System.out.println(第二次加密: finalPassword);finalPassword DigestUtils.md5DigestAsHex(123456.getBytes());System.out.println(第三次加密: finalPassword);}}可以观察到:MD5加密后得到的值是都是一样的,并且无论进行多少次MD5加密(对产生的MD5值多次进行加密),得到的结果都是一样的.
那么这样会不会产生安全问题呢?当然会!虽然说MD5加密是不可逆的加密,但是可以通过提前生成对应的明文和密文对应的表,然后通过需要破解的密文与之前生成表的密文进行对应,从而找到相应的明文,但是这种方法是十分低效的,但是也可以进行破解明文,尤其对于密码不复杂且短的很容易破解,那么怎么样可以避免这种情况呢?
首先可以在用户端进行,我们在设置的密码的时候,通常网站都要求需要字母与数字的组合,并且长度都要求大于一定的值,这样密码的安全等级很高,不容易被破解,(比如纯数字组合就10种,字母加数字就有2610种,大小写字母加数字组合就有26*210种,长度越长组合自然也就越多).
接下来通过服务端通过加盐的方式存储密码.
2.盐值
假设用户的密码安全很低,如果在存储的时候将密码与随机的字符串的进行拼接,然后再通过MD5加密的方式进行存储的话,同样也可以时密码难以破解,并且可以通过生成多个不同的随机字符串,可以解决MD5不能实现多次加密的问题.随机生成的字符串也要存储到数据库中,通常与生成的MD5数值拼接存储.
代码展示,通过UUID生成随机的字符串. Testvoid contextLoads() {String salt UUID.randomUUID().toString();String finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第一次salt: salt);System.out.println(第一次加密: finalPassword);salt UUID.randomUUID().toString();finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第二次salt: salt);System.out.println(第二次加密: finalPassword);salt UUID.randomUUID().toString();finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第三次salt: salt);System.out.println(第三次加密: finalPassword);}我们不希望产生的salt含有特殊字符,因此我们可以通过以下的方式将-去掉 Testvoid contextLoads() {String salt UUID.randomUUID().toString().replace(-, );String finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第一次salt: salt);System.out.println(第一次加密: finalPassword);salt UUID.randomUUID().toString().replace(-, );finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第二次salt: salt);System.out.println(第二次加密: finalPassword);salt UUID.randomUUID().toString().replace(-, );finalPassword DigestUtils.md5DigestAsHex((123456 salt).getBytes());System.out.println(第三次salt: salt);System.out.println(第三次加密: finalPassword);} 3.实现
public class SecurityUtils {/*** 将密码进行加密* 根据明文,返回密文(saltMD5)** param password* return*/public static String encry(String password) {//生成盐值String salt UUID.randomUUID().toString().replace(-, );//进行加密String finalPassword DigestUtils.md5DigestAsHex((password salt).getBytes());return salt finalPassword;}/*** param inputPassword 输入的密码* param finalPassword 数据库存储的密码* return 输入的密码和存储的密码是否相同*/public static boolean decrypt(String inputPassword, String finalPassword) {if (!StringUtils.hasLength(inputPassword) || !StringUtils.hasLength(finalPassword)) {return false;}if (finalPassword.length() ! 64) {return false;}String salt finalPassword.substring(0, 32);String password DigestUtils.md5DigestAsHex((inputPassword salt).getBytes());return (salt password).equals(finalPassword);}}
修改密码验证的接口 RequestMapping(/login)public Result login(HttpServletRequest request, String username, String password) {//参数校验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return Result.fail(-2, 账号或密码不能为空);}//密码校验User user userService.selectByName(username);if (user null || !SecurityUtils.decrypt(password, user.getPassword())) {return Result.fail(-3, 用户名不存在或者密码错误);}//参数返回user.setPassword();HttpSession session request.getSession(true);session.setAttribute(Constants.USER_INFO_SESSION, user);return Result.success(登陆成功);}
六.上线发布
1.多平台开发 profilesprofileiddev/idpropertiesenvdev/env/propertiesactivationactiveByDefaulttrue/activeByDefault/activation/profileprofileidprod/idpropertiesenvprod/env/propertiesactivationactiveByDefaultfalse/activeByDefault/activation/profile/profiles
如果需要跳过test,可以点击 application.yml文件 此时打包即可
2.部署linux服务器
1.创建数据库
可以将sql语句变成一个文件,然后执行下面的 source /root/java78/create.sql 2.将代码打包 打包完成之后,将jar包拖拽到linux服务器上
3.运行代码 后台启动项目 nohup java -jar Blog_Spring-0.0.1-SNAPSHOT.jar 查看日志 cd logs/ tail -f spring.log 终止当前的服务 ps -ef | grep [ ] 注意:如果开启多个服务,需要开端口,给防火墙添加端口号
查看防火墙状态(如果没开启,建议开启,不开启可以直接访问,开启了需要进行已下的操作访问) systemctl status firewalld 启动防火墙和关闭防火墙 systemctl start firewalld systemctl stop firewalld 查看开放的端口号 firewall-cmd --list-ports 开启8080端口 firewall-cmd --permanent --add-port8080/tcp 重启防火墙 firewall-cmd --reload 设置开机启动 systemctl enable firewalld 添加安全组 否则无法正常访问