springboot怎么设置多个路径全部跳转首页_SpringBoot(四)—Web开发(二)

这篇文章准备来记录一下一个restful风格小项目的流程,上篇文章为它做了一个基础,如果有什么错误希望大家能够指出。

目录

  • 首页
  • 国际化
  • 登录
  • 拦截器
  • CRUD

一、首页

  1. 在访问localhost:8080/的时候,默认访问首页
  • 在自己配置的SpringMVC的配置类中
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Bean//将这个组件注册到容器中public WebMvcConfigurer webMvcConfigurer(){WebMvcConfigurer webMvcConfigurer = new WebMvcConfigurer() {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("login");registry.addViewController("/login.html").setViewName("login");}};return webMvcConfigurer;}
}

二、国际化

  1. 步骤
  • 编写国际化配置文件,抽取页面需要显示的国际化消息

目录结构

login.properties代表默认的;下面的两个分别代表英文和中文的

c1b66aec596c40a057486616a277c385.png

在编写页面需要的国际化消息时,可以点击任意的一个properties文件,然后切换到Resource Bundle视图,然后使用+进行每个消息的编写

49c140bb133d89ec4ce6a0795aa72401.png
  • 使用ResourceBundleMessageSource管理国际化资源文件

如果是在SpringMVC中使用的时候,需要我们自己去编写;但是在SpringBoot中是给自动配置好了的

我们在编写的时候是在resourses目录下的i18n文件夹下写了配置文件,但是在观察源码发现他表示配置文件是放在类路径下的message.properties中,所以我们需要在application.propertis中去修改一下

95a20aa2c11caeeb5cb7d4b7c284e133.png

fd502cefb74e7f539e0a4c0fff2fd650.png
  • 去页面获取国际化的值

35f3d3858cfdd89d899b19d54b32799f.png

效果:根据浏览器语言设置的信息切换了国际化;

2. 用按钮去实现切换国际化

  • 原理

国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象);

1d54c7f8521f16d5c05c70d5cc53fa59.png
  • 步骤

在页面上添加超链接

60b8b4325efc7017d1b38f2a18205460.png

编写自定义的LocaleResolver

public class MyLocalResolver implements LocaleResolver {@Overridepublic Locale resolveLocale(HttpServletRequest httpServletRequest) {String l = httpServletRequest.getParameter("l");//使用默认的Locale locale = Locale.getDefault();if(!StringUtils.isEmpty(l)){String[] s = l.split("_");locale = new Locale("s[0]","s[1]");}return locale;}@Overridepublic void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {}
}

在MyMvcConfig中将我们自己编写的LocaleResolver添加到容器中;

@Bean
public LocaleResolver localeResolver(){return new MyLocalResolver();
}

三、登录

1.不连接数据库,只要用户名不为空和密码等于123456就可以成功登录并且跳转到首页

@Controller
public class LoginController {//可以使用Restful风格的注解// @RequestMapping(value = "/user/login",method = RequestMethod.POST)@PostMapping(value="/user/login")public String login(@RequestParam("username") String username,@RequestParam("password") String password, Map<String,Object> map){if(!StringUtils.isEmpty(username) && "123456".equals(password)){//登录成功,为了防止表单重复提交,将重定向到dashboardreturn "redirect:/main.html";}else{//登录失败map.put("msg","用户名密码错误");}return "login";}
}

2. 开发期间模板引擎页面修改以后,为了保证他能实时生效,需要执行以下步骤:

  • 禁用模板引擎的缓存
#禁用模板引擎的缓存
spring.thymeleaf.cache=false
  • idea中用Ctrl+f9:重新编译

3. 登录错误信息的显示

<p th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

4. 为了防止表单重复提交,将重定向进首页,所以在自己的MvcConfig配置类中再添加一个视图渲染;但是我们在设置了这个之后,会发现直接在地址栏中输入跳到首页的网址是可以直接进去的,那么我们的登录功能就不是摆设了吗?所以需要使用拦截器

registry.addViewController("/main.html").setViewName("dashboard");return "redirect:/main.html";

四、拦截器

1.自定义拦截器

/*** 这个拦截器的作用就是:进行登录的检查,如果不通过的话是不能进行主页的访问和一些增删改查功能的*/
public class LoginHandlerInterceptor implements HandlerInterceptor {//目标方法执行之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object loginUser = request.getSession().getAttribute("loginUser");if (loginUser==null){//在页面显示错误信息request.setAttribute("msg","没有权限");//未登录,返回登录页面request.getRequestDispatcher("/login.html").forward(request,response);return false;}else{//已登录return true;}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

2. 将拦截器注入到容器中

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {@Bean//将这个组件注册到容器中public WebMvcConfigurer webMvcConfigurer(){WebMvcConfigurer webMvcConfigurer = new WebMvcConfigurer() {//注册拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {//由于SpringBoot已经做好了静态资源的映射,拦截器不会拦截静态资源//addPathPatterns()表示会对那种类型的映射进行拦截,"/**"表示/全部拦截//excludePathPatterns()表示排除一些不拦截的registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/login.html","/","/user/login");}@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("login");registry.addViewController("/login.html").setViewName("login");registry.addViewController("/main.html").setViewName("dashboard");}};return webMvcConfigurer;}

3. 在Controller中是利用了session来进行用户名的存储,然后在拦截器中判断用户名是否为空

@Controller
public class LoginController {//可以使用Restful风格的注解// @RequestMapping(value = "/user/login",method = RequestMethod.POST)@PostMapping(value="/user/login")public String login(@RequestParam("username") String username,@RequestParam("password") String password,Map<String,Object> map,HttpSession session){if(!StringUtils.isEmpty(username) && "123456".equals(password)){session.setAttribute("loginUser",username);//登录成功,为了防止表单重复提交,将重定向到dashboardreturn "redirect:/main.html";}else{//登录失败map.put("msg","用户名密码错误");}return "login";}
}

五、CRUD

1.员工列表

  • 实验要求

CRUD满足rest风格;

URI:/资源名称、资源标识;

HTTP请求方式区分对资源CRUD操作;

  • Controller代码实现
@Controller
public class EmployeeController {@AutowiredEmployeeDao employeeDao;//获取所有员工@GetMapping("/emps")public String list(Model model){//获取所有员工Collection<Employee> all = employeeDao.getAll();//将获取到的员工存进session域中model.addAttribute("emps",all); //thymeleaf默认就会进行拼串;前缀是classpath:/templates/xxxx.htmlreturn "emp/list";}
}
  • Thymeleaf公共页面元素抽取

93b17f65ce6688f4d35c2b03f00aa206.png

三种引入功能片段的th属性:

th:insert----将公共片段整个插入声明引入元素中;

th:replace---将声明引入的元素替换为公共片段;

th:include----将被引入的片段的内容包含进这个标签中;

7aa4f9aabb20d232a895e29a56823e43.png

56d863bd067c2d341a7a793304041dec.png
  • 链接高亮

thymeleaf实现只有在点击侧边栏某个按钮时,只有点击的按钮高亮;将之前的侧边栏和顶部栏代码抽取出来放在一个新的HTML文件里

侧边栏---dashboard
<a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#"th:class="${activeUri=='main.html'}?'nav-link active':'nav-link '">
侧边栏----员工管理<a class="nav-link active" href="#"th:href="@{/emps}" th:class="${activeUri=='emps'?'nav-link active':'nav-link '}">
dashboard.html(将activeUri的值传递到引用的侧边栏里,进行判断)
<div th:replace="commens/bar::#sidebar(activeUri='main.html')"></div>
list.html
<div th:replace="commens/bar::#sidebar(activeUri='emps')"></div>
  • 员工列表显示
<thead><tr><th>#</th><th>lastName</th><th>gender</th><th>department</th><th>birth</th><th>操作</th></tr>
</thead>
<tbody><tr th:each="emp:${emps}"><td th:text="${emp.lastName}"></td><td th:text="${emp.lastName}"></td><td th:text="${emp.gender}==0?'男':'女'"></td><td th:text="${emp.department.departmentName}"></td><td th:text="${#dates.format(emp.birth,'yyyy--MM-dd:HH:mm')}"></td><td><button class="btn btn-sm btn-primary">修改</button><button class="btn btn-sm btn-danger">删除</button></td></tr>

2.添加员工

  • Controller
@GetMapping("/addEmp")
public String toAddPage(Model model){Collection<Department> departments = departmentDao.getDepartments();model.addAttribute("depts",departments);//返回到添加页面return "emp/add";
}
@PostMapping("/addEmp")public String addEmp(Employee employee){System.out.println("保存的员工是:"+employee);employeeDao.save(employee);//来到员工列表页面//redirect:重定向到一个地址//forward:转发到一个地址return "redirect:/emps";}
  • 前台页面
跳转请求
<a href="addEmp" class="btn btn-sm btn-success">添加</a>
add.html
<form th:action="addEmp" method="post"><div class="form‐group"><label>LastName</label><input name="lastName" type="text" class="form‐control" placeholder="zhangsan"></div><div class="form‐group"><label>Email</label><input name="email" type="email" class="form‐control" placeholder="zhangsan@atguigu.com"></div><div class="form‐group"><label>Gender</label><br/><div class="form‐check form‐check‐inline"><input class="form‐check‐input" type="radio" name="gender" value="1"><label class="form‐check‐label">男</label></div><div class="form‐check form‐check‐inline"><input class="form‐check‐input" type="radio" name="gender" value="0"><label class="form‐check‐label">女</label></div></div><div class="form‐group"><label>department</label><select class="form‐control"name="department.id"><option th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}">1</option></select></div><div class="form‐group"><label>Birth</label><input name="birth" type="text" class="form‐control" placeholder="zhangsan"></div><button type="submit" class="btn btn‐primary">添加</button>
</form>
  • 使用添加功能主要会出现的错误是400错误,前台输入的格式不匹配导致

我们这个功能这边主要是日期的格式会导致错误

填写的日期格式主要有:2017/01/01 2017-01-01 2017.01.01

日期的格式话:SpringMVC需要将页面提取的值转化为指定的类型;

默认的日期格式是按照/的格式

可以在application.properties配置文件中修改

spring.mvc.date-format=yyyy-MM-dd

3.修改员工

  • 在做员工修改的时候发现修改页面和新增页面是差不多的,只需要通过判断去判定执行的是添加功能还是修改功能
add.html
<!--对功能的判定就是通过emp是否为空,不为空则是修改-->
<form th:action="@{/addEmp}" method="post"><input type="hidden" name="_method" value="put" th:if="${emp!=null}"/><!--在传递到Controller的时候也要把id传过去(修改功能的时候)--><input type="hidden" th:if="${emp!=null}" th:value="${emp.id}"/><div class="form‐group"><label>LastName</label><input th:value="${emp!=null}?${emp.lastName}" name="lastName" type="text" class="form‐control" placeholder="zhangsan"></div><div class="form‐group"><label>Email</label><input th:value="${emp!=null}?${emp.email}" name="email" type="email" class="form‐control" placeholder="zhangsan@atguigu.com"></div><div class="form‐group"><label>Gender</label><br/><div class="form‐check form‐check‐inline"><input class="form‐check‐input" type="radio" name="gender" value="1"th:checked="${emp!=null}?${emp.gender==1}"><label class="form‐check‐label">男</label></div><div class="form‐check form‐check‐inline"><input class="form‐check‐input" type="radio" name="gender" value="0"th:checked="${emp!=null}?${emp.gender==0}"><label class="form‐check‐label">女</label></div></div><div class="form‐group"><label>department</label><select class="form‐control"name="department.id"><option th:selected="${emp!=null}?${dept.id==emp.department.id}" th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}"></option></select></div><div class="form‐group"><label>Birth</label><input th:value="${emp!=null}?${emp.birth}" name="birth" type="text" class="form‐control" placeholder="zhangsan"></div><button type="submit" class="btn btn‐primary"th:text="${emp!=null}?'修改':'添加'"></button>
</form>
  • Controller
//来到修改页面,查出当前员工,并进行回显
@GetMapping("/editEmp/{id}")
public String toEditPage( @PathVariable("id") Integer id, Model model){Employee employee = employeeDao.get(id);model.addAttribute("emp",employee);//页面显示所有的部门信息Collection<Department> departments = departmentDao.getDepartments();model.addAttribute("departments",departments);return "emp/add";
}
//进行员工修改,需要传递该员工的id
@PutMapping("/addEmp")
public String updateEmp(Employee employee){System.out.println("收到的员工信息:"+employee);System.out.println(employeeDao);employeeDao.save(employee);return "redirect:/emps";
}
  • 这里重点提一下在写这段代码会出现的一个错误:如果使用的是较高版本的SpringBoot,在修改的时候使用的是put请求,SpringBoot是为我们配置好了hiddenFilter,但是他默认是不开启的,需要在application.properties中进行开启
#开启过滤器
spring.mvc.hiddenmethod.filter.enabled=true@Bean
@ConditionalOnMissingBean({FormContentFilter.class})
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter",name = {"enabled"},matchIfMissing = true
)
public OrderedFormContentFilter formContentFilter() {return new OrderedFormContentFilter();
}

4.删除员工

  • Controller
//员工删除方法
@DeleteMapping("/deleteEmp/{id}")
public String deleteEmp(@PathVariable("id") Integer id){employeeDao.delete(id);return "redirect:/emps";
}
  • 前台页面最简单的编写就是将删除按钮用form表单包起来,然后发送delete请求,再传递id;但是这样的页面就不太美观,所以可以使用js点击事件来进行编写
 <form th:action="@{/deleteEmp/}+${emp.id}" method="post"><input type="hidden" name="_method" value="delete"><button type="submit" class="btn btn-sm btn-danger">删除</button>
</form>
点击事件:
<button th:attr="del_uri=@{/emp/}+${emp.id}" class="btn btn‐sm btn‐danger deleteBtn">删除</button></td> </tr><script>$(".deleteBtn").click(function(){//删除当前员工的$("#deleteEmpForm").attr("action",$(this).attr("del_uri")).submit();return false; }); 
</script>

这个小实验到这里就写的差不多了,和Spring的框架差不多,只是在写的过程中可以知道一些技巧和thymeleaf的标签的使用,这里只贴了一部分代码,完整代码可以进入我的GitHub:https://github.com/rainbow-dan/SpringBoot-rest-crud;如果你喜欢我的文章,就关注我吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/534063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机英语六级,英语六级作文范文:计算机

英语六级考试时间越来越近了&#xff0c;所以在备考的时候就更要掌握技巧&#xff0c;勤加练习。在备考英语六级写作时&#xff0c;学习一篇好的范文&#xff0c;会给复习带来事半功倍的效果。Using a computer every day can have more negative than positive effects on you…

python软件_Python自制照片美颜软件~

下午被一个骗子恶心到了&#xff0c;本来听公开课听得好好的&#xff0c;搞得心情极差&#xff0c;于是就中断了网课&#xff0c;听听音乐&#xff0c;写一下文章吧&#xff01;前期准备①Python编译环境以及Python代码编辑器Pycharm的安装&#xff1a;请在【微信公众后台】找到…

数据集怎么导出_PCA算法 | 数据集特征数量太多怎么办?用这个算法对它降维打击...

今天是机器学习专题的第27文章&#xff0c;我们一起来聊聊数据处理领域的降维(dimensionality reduction)算法。我们都知道&#xff0c;图片格式当中有一种叫做svg&#xff0c;这种格式的图片无论我们将它放大多少倍&#xff0c;也不会失真更不会出现边缘模糊的情况。原因也很简…

常用命令_GIT常用命令大全

Git 是一个很强大的分布式版本控制系统。它不但适用于管理大型开源软件的源代码&#xff0c;管理私人的文档和源代码也有很多优势。克隆远程文件&#xff1a;git clone https://gitee.com/abcd/codefile.git projectgit checkout -b dev(本地分支名称) origin/dev(远程分支名称…

nvidia显示设置不可用_Nvidia显示设置不可用,您当前未使用连接到NVIDIA GPU的显示器的解决方法...

相信不少用户遇到这样一个问题&#xff0c;就是新购买的台式机电脑&#xff0c;配置达标的情况下&#xff0c;玩游戏出现卡顿不流畅的现象&#xff0c;准备在NVIDIA控制面板查看是否设置的问题&#xff0c;在打开NVIDIA控制面板的时候&#xff0c;提示了“Nvidia显示设置不可用…

oracle tns 代理配置_Toad for oracle安装配置与使用

一.toad安装与配置注意:toad的使用本机电脑必须安装完整版oracle客户端,不能是精简版的.1.1完整版oracle客户端的安装.1.解压文件&#xff0c;安装oracle客户端打开安装包&#xff0c;找到setup.ext&#xff0c;开始安装。提示下图弹窗,可根据此网址内容进行更改(https://blog.…

吴枫 python小课账号_无门槛速学编程——Python小短课,自上而下分而治之

【Python小短课 11】自上而下&#xff0c;分而治之 做任何事都需计划&#xff0c;编程也是。 譬如写文章要列大纲、作画要想布局&#xff0c;编程也需先谋全局&#xff0c;而后思虑细节。 就以上回说到的“找宝藏”这个程序举例&#xff0c;最顶层的需求自然就是“找宝藏”&…

计算机本地磁盘D无法扩展,计算机上的本地磁盘D突然无法打开,表明它需要格式化...

接受使用数据恢复软件将重要数据保存到其他磁盘FindDate特定操作: 运行软件----“打开”后&#xff0c;将显示要还原的驱动器. C \ D \ E \ F选择您要还原的一个&#xff0c;它将开始. 扫描后&#xff0c;再次保存扫描的文件. 哈哈&#xff0c;希望对您有所帮助.最后&#xff0…

caffe运行不停止_caffe(gpu)安装过程及问题解决

2019.12.05 caffe(gpu)安装参考网址&#xff1a;教程1&#xff1a;weiliu89/caffe​github.com教程2&#xff1a;https://blog.csdn.net/yggaoeecs/article/details/79163789​blog.csdn.net环境&#xff1a;Ubuntu16.04cuda10.0安装过程&#xff1a;git clone https://github.…

2021年考计算机考研三战,2021考研的小伙伴有3条忠告一定要记得,这些都是历年实战经验...

2021考研的小伙伴有3条忠告一定要记得&#xff0c;这些都是历年实战经验&#xff0c;考研一定要记得避开三个大坑。1&#xff0c;分数线低的学校就一定容易考。有一些学校分数线看着很低但实际上难度不低&#xff0c;比如首都师范大学 &#xff0c;很多专业就是国家线录取甚至招…

c++ 返回string_JVM系列之:String.intern和stringTable

简介StringTable是什么&#xff1f;它和String.intern有什么关系呢&#xff1f;在字符串对象的创建过程中&#xff0c;StringTable有起到了什么作用呢&#xff1f;一切的答案都在本文中&#xff0c;快来看看吧。intern简介intern是String类中的一个native方法&#xff0c;所以它…

华为 虚拟键盘_华为mate30 pro虚拟机械键盘特有体验,虽是虚拟,但却感受逼真...

华为Mate30 pro已于26日在国内正式发布了。此外&#xff0c;根据了解华为Mate30系列现在已经突破了5亿的销售额。看来&#xff0c;华为的这个下半年旗舰手机非常受欢迎啊。华为Mate30系列现在在国内已经发布了&#xff0c;其整体感官看上去与海外的没有多大的区别。其实&#x…

计算机有什么著名基金经理排名,百万年薪的基金经理,都是什么专业出身?!...

有人会说了“小哔君你四不四撒&#xff01;基金经理肯定是金融专业出身的咯&#xff1f;不然嘞&#xff1f;”但事实的真相是许多基金经理都并非科班出身这要从基金经理的晋升机制说起了&#xff01;如下图基金经理都是从研究员做起的&#xff01;那么问题来了&#xff0c;如何…

遍历children_589. N叉树的前序遍历

589. N叉树的前序遍历给定一个 N 叉树&#xff0c;返回其节点值的前序遍历。例如&#xff0c;给定一个 3叉树 :返回其前序遍历: [1,3,5,6,2,4]。说明: 递归法很简单&#xff0c;你可以使用迭代法完成此题吗?题解&#xff1a;既然是树的遍历&#xff0c;那么一共就是两种思路&a…

计算机未显示移动硬盘,电脑不显示移动硬盘怎么办_移动硬盘已连接不显示解决教程...

最近有很多小伙伴咨询小编&#xff0c;电脑不显示移动硬盘怎么办&#xff0c;怎么设置才能恢复呢&#xff1f;其实操作内容很简单&#xff0c;尝试删除你的USB3.0可扩展主机控制器,再扫描硬件改动&#xff0c;今天就由小编来告诉你&#xff0c;移动硬盘已连接不显示的解决方法。…

八个角最多可以把平面分成多少部分?_一个空间最多能被分成几块?

相信大家在小学奥数中都遇到这样一个问题&#xff1a;4条直线最多能将平面分成几部分&#xff1f;这个问题并不能难倒我们&#xff0c;但是如果将问题改为&#xff1a;4个平面最多能将空间分为几部分&#xff1f;这下子我们可能就要放弃了。为了解决这个问题&#xff0c;今天我…

破坏计算机信息系统功能罪,破坏计算机信息系统罪

破坏计算机信息系统罪2010年05月05日19:42法律咨询 我要评论一、概念&nbsp&nbsp&nbsp&nbsp破坏计算机信息系统罪(刑法第286条)&#xff0c;是指违反国家规定&#xff0c;对计算机信息系统功能或计算机信息系统中存储、处理或者传输的数据和应用程序进行破坏…

东京战纪服务器维护中,东京战纪7月21维护公告 当前测试进度介绍

东京战纪当前的测试进度已经有了很大的进步&#xff0c;接下来小编就跟大家一起看看测试期间对玩家给大家的报告吧。亲爱的喰种和CCG搜查官们7月19日中午12:00&#xff0c;我们怀着紧张又忐忑的心情开启了《东京战纪》官网限量删档技术测试。大家对《东京喰种》IP的热爱和对《东…

docker重启后容器消失_docker设置固定ip地址

代码来源:博客园 原文作者:雪之谷 原文链接:https://www.cnblogs.com/xuezhigu/p/8257129.html 本文版权归原作者所有,如有侵权请立即与我联系,我将及时处理。 背景: 我开发用的机器上边会启动几个容器,就因为保洁阿姨碰了一下我的插排,我的机器被断电关机了。 默认情况下…

模型稳定后放在服务器上,把工程放在服务器上

把工程放在服务器上 内容精选换一换获取方式&#xff1a;Ascend-mindx-msinstaller_{version}.zip&#xff1a;获取链接适用场景&#xff1a;在一台Linux服务器上使用msInstaller工具给本机安装开发或运行环境。在一台Linux服务器上使用msInstaller工具远程给昇腾AI设备安装开发…