订阅号可以做网站吗,南昌百度网站快速排名,西宁网站搭建企业,深圳多彩科技集团有限公司这篇文章准备来记录一下一个restful风格小项目的流程#xff0c;上篇文章为它做了一个基础#xff0c;如果有什么错误希望大家能够指出。目录首页国际化登录拦截器CRUD一、首页在访问localhost:8080/的时候#xff0c;默认访问首页在自己配置的SpringMVC的配置类中Configura…这篇文章准备来记录一下一个restful风格小项目的流程上篇文章为它做了一个基础如果有什么错误希望大家能够指出。目录首页国际化登录拦截器CRUD一、首页在访问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;}
}二、国际化步骤编写国际化配置文件抽取页面需要显示的国际化消息目录结构login.properties代表默认的下面的两个分别代表英文和中文的在编写页面需要的国际化消息时可以点击任意的一个properties文件然后切换到Resource Bundle视图然后使用进行每个消息的编写使用ResourceBundleMessageSource管理国际化资源文件 如果是在SpringMVC中使用的时候需要我们自己去编写但是在SpringBoot中是给自动配置好了的我们在编写的时候是在resourses目录下的i18n文件夹下写了配置文件但是在观察源码发现他表示配置文件是放在类路径下的message.properties中所以我们需要在application.propertis中去修改一下去页面获取国际化的值效果根据浏览器语言设置的信息切换了国际化2. 用按钮去实现切换国际化原理国际化Locale区域信息对象LocaleResolver获取区域信息对象步骤在页面上添加超链接编写自定义的LocaleResolverpublic 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, MapString,Object map){if(!StringUtils.isEmpty(username) 123456.equals(password)){//登录成功,为了防止表单重复提交将重定向到dashboardreturn redirect:/main.html;}else{//登录失败map.put(msg,用户名密码错误);}return login;}
}
2. 开发期间模板引擎页面修改以后为了保证他能实时生效需要执行以下步骤禁用模板引擎的缓存#禁用模板引擎的缓存
spring.thymeleaf.cachefalseidea中用Ctrlf9重新编译3. 登录错误信息的显示p th:text${msg} th:if${not #strings.isEmpty(msg)}/p4. 为了防止表单重复提交将重定向进首页所以在自己的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 (loginUsernull){//在页面显示错误信息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,MapString,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;}
}五、CRUD1.员工列表实验要求CRUD满足rest风格URI/资源名称、资源标识HTTP请求方式区分对资源CRUD操作Controller代码实现Controller
public class EmployeeController {AutowiredEmployeeDao employeeDao;//获取所有员工GetMapping(/emps)public String list(Model model){//获取所有员工CollectionEmployee all employeeDao.getAll();//将获取到的员工存进session域中model.addAttribute(emps,all); //thymeleaf默认就会进行拼串前缀是classpath:/templates/xxxx.htmlreturn emp/list;}
}
Thymeleaf公共页面元素抽取三种引入功能片段的th属性th:insert----将公共片段整个插入声明引入元素中th:replace---将声明引入的元素替换为公共片段th:include----将被引入的片段的内容包含进这个标签中链接高亮thymeleaf实现只有在点击侧边栏某个按钮时只有点击的按钮高亮将之前的侧边栏和顶部栏代码抽取出来放在一个新的HTML文件里侧边栏---dashboard
a classnav-link active hrefhttp://getbootstrap.com/docs/4.0/examples/dashboard/#th:class${activeUrimain.html}?nav-link active:nav-link
侧边栏----员工管理a classnav-link active href#th:href{/emps} th:class${activeUriemps?nav-link active:nav-link }
dashboard.html(将activeUri的值传递到引用的侧边栏里进行判断)
div th:replacecommens/bar::#sidebar(activeUrimain.html)/div
list.html
div th:replacecommens/bar::#sidebar(activeUriemps)/div员工列表显示theadtrth#/ththlastName/ththgender/ththdepartment/ththbirth/thth操作/th/tr
/thead
tbodytr th:eachemp:${emps}td th:text${emp.lastName}/tdtd th:text${emp.lastName}/tdtd th:text${emp.gender}0?男:女/tdtd th:text${emp.department.departmentName}/tdtd th:text${#dates.format(emp.birth,yyyy--MM-dd:HH:mm)}/tdtdbutton classbtn btn-sm btn-primary修改/buttonbutton classbtn btn-sm btn-danger删除/button/td/tr2.添加员工ControllerGetMapping(/addEmp)
public String toAddPage(Model model){CollectionDepartment 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 hrefaddEmp classbtn btn-sm btn-success添加/a
add.html
form th:actionaddEmp methodpostdiv classform‐grouplabelLastName/labelinput namelastName typetext classform‐control placeholderzhangsan/divdiv classform‐grouplabelEmail/labelinput nameemail typeemail classform‐control placeholderzhangsanatguigu.com/divdiv classform‐grouplabelGender/labelbr/div classform‐check form‐check‐inlineinput classform‐check‐input typeradio namegender value1label classform‐check‐label男/label/divdiv classform‐check form‐check‐inlineinput classform‐check‐input typeradio namegender value0label classform‐check‐label女/label/div/divdiv classform‐grouplabeldepartment/labelselect classform‐controlnamedepartment.idoption th:value${dept.id} th:eachdept:${depts} th:text${dept.departmentName}1/option/select/divdiv classform‐grouplabelBirth/labelinput namebirth typetext classform‐control placeholderzhangsan/divbutton typesubmit classbtn btn‐primary添加/button
/form使用添加功能主要会出现的错误是400错误前台输入的格式不匹配导致我们这个功能这边主要是日期的格式会导致错误填写的日期格式主要有2017/01/01 2017-01-01 2017.01.01日期的格式话SpringMVC需要将页面提取的值转化为指定的类型默认的日期格式是按照/的格式可以在application.properties配置文件中修改spring.mvc.date-formatyyyy-MM-dd3.修改员工在做员工修改的时候发现修改页面和新增页面是差不多的只需要通过判断去判定执行的是添加功能还是修改功能add.html
!--对功能的判定就是通过emp是否为空不为空则是修改--
form th:action{/addEmp} methodpostinput typehidden name_method valueput th:if${emp!null}/!--在传递到Controller的时候也要把id传过去(修改功能的时候)--input typehidden th:if${emp!null} th:value${emp.id}/div classform‐grouplabelLastName/labelinput th:value${emp!null}?${emp.lastName} namelastName typetext classform‐control placeholderzhangsan/divdiv classform‐grouplabelEmail/labelinput th:value${emp!null}?${emp.email} nameemail typeemail classform‐control placeholderzhangsanatguigu.com/divdiv classform‐grouplabelGender/labelbr/div classform‐check form‐check‐inlineinput classform‐check‐input typeradio namegender value1th:checked${emp!null}?${emp.gender1}label classform‐check‐label男/label/divdiv classform‐check form‐check‐inlineinput classform‐check‐input typeradio namegender value0th:checked${emp!null}?${emp.gender0}label classform‐check‐label女/label/div/divdiv classform‐grouplabeldepartment/labelselect classform‐controlnamedepartment.idoption th:selected${emp!null}?${dept.idemp.department.id} th:value${dept.id} th:eachdept:${depts} th:text${dept.departmentName}/option/select/divdiv classform‐grouplabelBirth/labelinput th:value${emp!null}?${emp.birth} namebirth typetext classform‐control placeholderzhangsan/divbutton typesubmit classbtn btn‐primaryth:text${emp!null}?修改:添加/button
/formController//来到修改页面查出当前员工并进行回显
GetMapping(/editEmp/{id})
public String toEditPage( PathVariable(id) Integer id, Model model){Employee employee employeeDao.get(id);model.addAttribute(emp,employee);//页面显示所有的部门信息CollectionDepartment 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.enabledtrueBean
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} methodpostinput typehidden name_method valuedeletebutton typesubmit classbtn btn-sm btn-danger删除/button
/form
点击事件
button th:attrdel_uri{/emp/}${emp.id} classbtn btn‐sm btn‐danger deleteBtn删除/button/td /trscript$(.deleteBtn).click(function(){//删除当前员工的$(#deleteEmpForm).attr(action,$(this).attr(del_uri)).submit();return false; });
/script这个小实验到这里就写的差不多了和Spring的框架差不多只是在写的过程中可以知道一些技巧和thymeleaf的标签的使用这里只贴了一部分代码完整代码可以进入我的GitHubhttps://github.com/rainbow-dan/SpringBoot-rest-crud如果你喜欢我的文章就关注我吧