控制技术难度预测
虽然但听见这个最新消息的这时候,内心深处还是挺愤慨的,即便是两个完备的管理工作控制系统,机能介面还不能太过破旧。所以从资料库结构设计到整座控制系统的交货全由自己三人顺利完成,考验效用间接齐广君!但平静下来思索呵呵,只不过也并不是极难,总体的工程项目流程即为:结构设计——>文档格式——>代码——>交货。总体的流程摈弃之后,就开始一点一点刘天祺的同时实现,居然到最终一步的这时候,我居然才用六天半的天数!!前面又用了一会的天数对总体的工程项目做了两个强化处置!
工程项目简述
最终效用模拟:
控制技术THF1:
SpringBootThymeleafMybatis-PlusMySQLPageHelperLombokRedis(中后期网页强化采用)工程项目业务流程概要
登入组件、采用者组件管理工作和对采用者的配角重新分配,新闻报道报告书组件的管理工作、货品组件(包括对货品、货品进行分类、订货)的管理工作、配角组件的管理工作;对前端某天然资源与否有职权操作方式该天然资源,采用的是thymeleaf模版句法进行推论辨别和文档上载等基本要素。
工程项目构筑(采用模版发动机)
1. 具体来说建立Maven工程项目导入适当的倚赖,构筑所需二百一十三
2. 编写yaml配置文档server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/supplier?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
# thymeleaf 配置thymeleaf:
# 关闭缓存 cache: falseprefix: classpath:/templates/
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
3. 工程项目初期基本构筑在构筑两个工程项目的初期,为了让控制系统显得更规范化,我一般会提前做好基础的配置和声明,两个工程项目从开始设想时所涉及到控制技术和这些控制技术对应的一些基础配置,都要提前规摈弃楚(个人习惯)。比如:异常处置、拦截器、过滤器、常量类等等。
①异常处置
@ControllerAdvice
public class ExceptionHandler {
private final org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
public ModelAndView exception(HttpServletRequest request, Exception e ) throws Exception {
logger.error(“Request URL:{},Exception:{}”,request.getRequestURL(),e);
if(AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class )!= ){
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject(“url”,request.getRequestURL());
mv.addObject(“exception”,e);
mv.setViewName(“error/error”);
returnmv;
}
}
② 拦截器
拦截器主要是对一些天然资源做的处置,类似于某些天然资源需要采用者登入后才能访问的,某些是不需要的,比如:登入机能就不需要有所拦截,而对采用者的各种管理工作就需要添加拦截操作方式,这样才能使控制系统的安全性有所提高。
登入拦截
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute(“user”) == ){
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”);
}
}
4. 编写Controller后端控制器代码具体来说建立两个FileController类
① 跳转文档上载的网页
//跳转文档上载的网页
@RequestMapping(“/file-upload”)
public String userList(){
return “file-upload”;
}
② 同时实现文档上载的机能
@RequestMapping(“/doAddForUser”)
public String doAdd(User user, @RequestParam(“file”) MultipartFile files, HttpServletRequest request) throws IOException {
//String path = ;
if(files != && !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.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 = ;
for(int i = 0; i < files.length; i++) {
if(files[i] != && !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.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);
}
}
}
}
5. 工程项目强化对前后端不分离的工程项目,多数采用的是网页缓存强化,当控制系统某一瞬间遭受巨大流量时,当第两个采用者进
① 导入倚赖
② yaml配置
## Redis配置redis:
# 服务器地址host: localhost
# 端口port: 6379
# 资料库database: 0
# 超时天数connect-timeout: 10000ms
lettuce:
pool:
# 最大连接数max-active: 8
# 最大连接阻塞等待天数 默认 -1max-wait: 10000ms
# 最大空闲天数 默认8max-idle: 200
# 最小空闲连接 默认8min-idle: 5
④ Redis序列化处置
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate
RedisTemplate
//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);
returnredisTemplate;
}
}
③ 强化处置
@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(Model model, @RequestParam(value = “pageNo”,defaultValue = “1”)Integer pageNo
, @RequestParam(value = “pageSize”,defaultValue = “10”)Integer pageSize
, HttpServletRequest request, HttpServletResponse response){
ValueOperations valueOperations = redisTemplate.opsForValue();
String html = (String) valueOperations.get(“news-list”);
if(!StringUtils.isEmpty(html)){
returnhtml;
}
PageHelper.startPage(pageNo,pageSize);
List
PageInfo
,list);
model.addAttribute(“pageInfo”,pageInfo);
//如果为空,手动渲染,存入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);
}
returnhtml;
}
④ Redis查看
6. 注意事项注意@Controller和@RestController的区别,本工程项目采用的是模版渲染网页,而@Controller就是用来响应网页的;而@RestController是用来返回Json
在工程项目强化阶段需要在方法上添加注解@ResponseBody,因为我们是将整座网页进行缓存 ,所以要将网页转换成JSON进行存储。
注入Thymeleaf解析器,将具体的 网页进行解析成Json字符串进行存储
将存入Redis中的数据加上过期天数,因为网页中的数据要和资料库保持一致,如果采用者看到是几十秒之前或一分钟之前的数据还是勉强可以接受的。
目前代码已经同步到Gitee:
https://gitee.com/gao-wumao/supplier
如果有需要的自行前去仓库拉取