大佬教程收集整理的这篇文章主要介绍了你敢信?开发一个管理系统我只用了两天时间,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
前言: 由于疫情原因c;学校通知本学期要提前放暑假c;于是老师提前将期末作业公布于众c;按照要求开发一个百货中心供应链管理系统c;开发周期为半个月c;不能更改题目c;包括前期的数据库设计、系统的需求文档c;后期都要以文本的形式进行提交。到这里c;说实话c;我慌了!!这不就是让我们从0到1自己搭建一个项目呗c;关键还是一人一组的形式!
🏡 博客首页:派 大 星
⛳️ 欢迎关注 🐳 点赞 🎒 收藏 ✏️ 留言
🎢 本文由派大星原创编撰
🚧 系列专栏:项目从0搭建
虽然但是听到这个消息的时候c;内心还是挺震惊的c;毕竟是一个完整的管理系统c;功能界面还不能太过简陋。而且从数据库设计到整个系统的交付全由自己一人完成c;挑战效果直接拉满!但是冷静下来思考一下c;其实也并不是很难c;整体的项目流程即为:设计——>文档——>编码——>交付。整体的流程划清之后c;就开始一步步从无到有的实现c;没想到到最后一步的时候c;我竟然才用一天半的时间!!后面又用了半天的时间对整体的项目做了一个优化处理!
登录模块、用户模块管理以及对用户的角色分配c;新闻公告模块的管理、商品模块(包括对商品、商品分类、订单)的管理、角色模块的管理;对于前端某资源是否有权限操作该资源c;使用的是thymeleaf
模板语法进行判断鉴别以及文件上传等基本功能。
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:@H_155_166@mysql://localhost:3306/supplier?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
# thymeleaf 配置
thymeleaf:
# 关闭缓存
cache: false
prefix: classpath:/templates/
@H_687_165@mybatis-plus:
@H_687_165@mapper-LOCATIOns: classpath*:/mapper/**/*.xml
在搭建一个项目的初期c;为了让系统显得更规范化c;我一般会提前做好基础的配置和声明c;一个项目从开始设想时所涉及到技术以及这些技术对应的一些基础配置c;都要提前规划清楚(个人习惯)。比如:异常处理、拦截器、过滤器、常量类等等。
@ControllerAdvice
public class ExceptionHandler {
private final org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
@org.springframework.web.bind.Annotation.ExceptionHandler(Exception.class)
public @H_86_257@modelAndView exception(httpServletrequest request, Exception e ) throws Exception {
logger.error("request URL:{},Exception:{}",request.getrequestuRL(),e);
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class )!= null){
throw e;
}
@H_86_257@modelAndView mv = new @H_86_257@modelAndView();
mv.addObject("url",request.getrequestuRL());
mv.addObject("exception",e);
mv.setViewName("error/error");
return mv;
}
}
拦截器主要是对一些资源做的处理c;类似于某些资源需要用户登录后才能访问的c;某些是不需要的c;比如:登录功能就不需要有所拦截c;而对用户的各种管理就需要添加拦截操作c;这样才能使系统的安全性有所提高。
登录拦截
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public Boolean preHandle(httpServletrequest request, httpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute("user") == null){
response.sendRedirect("/api");
return false;
}
return true;
}
}
资源放行
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api","/api/doLogin");
}
}
首先创建一个FileController
类
//跳转文件上传的页面
@requestMapping("/file-upload")
public String userList(){
return "file-upload";
}
@requestMapping("/doAddForUser")
public String doAdd(User user, @requestParam("file") @H_86_257@multipartFile files, httpServletrequest request) throws IOException {
//String path = null;
if (files != null && !files.isEmpty()){
String name = UUID.randomUUID().toString().replace("-","");
//获取文件的扩展名
String ext = FilenameUtils.getExtension(files.getOriginalFilename());
//设置文件上传的路径
String url =request.getSession().getServletContext().getRealPath("/upload/");
File file = new File(url);
if (!file.exists()){
file.@H_121_280@mkdir();
}
//测试路径
System.out.println(request.getServletPath()+ "/upload");
System.out.println(request.getContextPath() + "/upload/");
//以绝对路径保存重命名后的文件
files.transferTo(new File(url+"/"+name+"."+ext));
user.setAvatar(request.getContextPath() + "/upload/"+name+"."+ext);
}
user.setId(UUID.randomUUID().toString());
String salt = passwordUtils.getSalt();
String password = user.getpassword();
String encode = passwordUtils.encode(password, salt);
user.setSalt(salt) ;
user.setpassword(encode);
user.setCreateTime(new Date());
userservice.save(user);
return "redirect:/api/users";
}
注: 如何想要实现多文件上传需要更改的地方如下:
在这个项目中并未实现多文件上传功能
private void commons(Object obj, @requestParam("file") CommonsMultipartFile[] files, httpServletrequest request) throws IOException {
//String path = null;
for (int i = 0; i < files.length; i++) {
if (files[i] != null && !files[i].isEmpty()){
String name = UUID.randomUUID().toString().replace("-","");
//获取文件的扩展名
String ext = FilenameUtils.getExtension(files[i].getOriginalFilename());
//设置文件上传的路径
String url =request.getSession().getServletContext().getRealPath("/upload/");
File file = new File(url);
if (!file.exists()){
file.@H_121_280@mkdir();
}
//测试路径
System.out.println(request.getServletPath()+ "/upload");
System.out.println(request.getContextPath() + "/upload/");
//以绝对路径保存重命名后的文件
files[i].transferTo(new File(url+"/"+name+"."+ext));
if (i == 0){
obj.setUrl1(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 1){
obj.setUrl2(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 2){
obj.setUrl3(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 3){
obj.setUrl4(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 4){
obj.setUrl5(request.getContextPath() + "/upload/"+name+"."+ext);
}
}
}
}
对于前后端不分离的项目c;多数使用的是页面缓存优化
c;当系统某一瞬间遭受巨大流量时c;当第一个用户进行页面访问时可以将该页面数据进行缓存c;这样c;后来的用户访问到的页面都是从缓存中获取的c;这样就减少了 对数据库的操作c;减轻了数据库的压力c;从而达到优化的处理。
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--commons-pools2 对象池依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
## redis配置
redis:
# 服务器地址
host: localhost
# 端口
port: 6379
# 数据库
database: 0
# 超时时间
connect-timeout: 10000ms
lettuce:
pool:
# 最大连接数
@H_687_165@max-active: 8
# 最大连接阻塞等待时间 默认 -1
@H_687_165@max-wait: 10000ms
# 最大空闲时间 默认8
@H_687_165@max-idle: 200
# 最小空闲连接 默认8
@H_687_165@min-idle: 5
@Configuration
public class redisConfig {
@Bean
public redisTemplate@H_552_1976@<String,Object> redisTemplate(redisConnectionFactory redisConnectionFactory){
redisTemplate@H_552_1976@<String,Object> redisTemplate = new redisTemplate@H_552_1976@<>();
//key序列化
redisTemplate.setKeyserializer(new Stringredisserializer());
//value序列化
redisTemplate.SETVALueserializer(new GenericJackson2Jsonredisserializer());
//hash类型key的序列化
redisTemplate.setHashKeyserializer(new Stringredisserializer());
//hash类型value的序列化
redisTemplate.setHashValueserializer(new GenericJackson2Jsonredisserializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
@Autowired
private Newsservice newsservice;
@Autowired
private redisTemplate redisTemplate;
@Autowired
private ThymeleafViewResolver viewResolver;
@requestMapping(value = "/news",produces = "text/html;charset=utf-8")
@ResponseBody
public String roles(@H_86_257@model model, @requestParam(value = "pageNo",DefaultValue = "1")Integer pageNo
, @requestParam(value = "pageSize",DefaultValue = "10")Integer pageSize
, httpServletrequest request, httpServletResponse response){
//redis中获取页面c;如果不为空c;则直接返回页面
ValueOperations valueOperations = redisTemplate.opsForValue();
String html = (String) valueOperations.get("news-list");
if (!StringUtils.isEmpty(html)){
return html;
}
PageHelper.startPage(pageNo,pageSize);
List@H_552_1976@<News> list = newsservice.list();
PageInfo@H_552_1976@<News> pageInfo = new PageInfo@H_552_1976@<>(list);
model.addAttribute("news",list);
model.addAttribute("pageInfo",pageInfo);
//如果为空c;手动渲染c;存入redis中并返回
WebContext context = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asmap());
html = viewResolver.getTemplateENGIne().process("news-list", context);
if (!StringUtils.isEmpty(html)){
//给缓存设置过期时间
valueOperations.set("news-list",html,60, TimeUnit.SECONDS);
}
return html;
}
注意@Controller
和@RestController
的区别c;本项目使用的是模板渲染页面c;而@Controller
就是用来响应页面的;而@RestController
是用来返回Json
在项目优化阶段需要在方法上添加注解@ResponseBody
c;因为我们是将整个页面进行缓存 c;所以要将页面转换成JSON
进行存储。
@H_801_2557@
注入Thymeleaf解析器c;将具体的 页面进行解析成Json
字符串进行存储
将存入redis中的数据加上过期时间c;因为页面中的数据要和数据库保持一致c;如果用户看到是几十秒之前或一分钟之前的数据还是勉强可以接受的。
目前代码已经同步到 派大星百货中心管理系统 如果有需要的自行前去仓库拉取c;还请各位大佬不要吝啬手中的三连哟!
以上是大佬教程为你收集整理的你敢信?开发一个管理系统我只用了两天时间全部内容,希望文章能够帮你解决你敢信?开发一个管理系统我只用了两天时间所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。