1. 首先要在Application的同级目录创建好需要的目录文件
先说明几个需要注意的点:
- 所有的静态页面放在templates包下;
- 所有的静态资源放在static包下;
- 想要创建自定义的SpringMVC配置类,可以实现接口WebMvcConfigurer,但是千万不要加@EnableWebMvc注解,不然就会导致SpringBoot自带的配置类失效;
- 创建需要的目录:controller(处理请求),bean(放置实体类),config(放置配置类),dao(连接数据库);
- 使用重定向可以防止用户不断的重复提交,但是缺点也很明显,因为有了新的映射,可以直接通过那个网址登录,就有可能跳出登录注册等操作,所以要设置拦截器;这个拦截器可以通过Session中的信息进行判断,比如登录的同时放一个值进入到session中,拦截器进行检查后才能进入;
- 拦截器在SpringBoot2.3.3中又需要排除静态资源的限制了,不然又没有静态资源了;
- 防止拦截的方法,使用
"/**/*.css"或者/**/*.js等方式,就可以躲避拦截此类文件;
2. 国际化配置
简单来说就是多种语言置换;不是单一语言显示;
-
编写国际化配置文件(放在资源路径下
名称i18n
);命名之后创建properties后缀的文件,IDEA就知道你想创建国际化文件了;zh_cn是指中文;语言和国家简写;比如还有en_US
-
通过ResourceMessageSource管理国际化资源;而且这个已经被SpringBoot做好了配置;就在这个类里面,至于源码,就只是指明位置,目前很多没学清楚,看的太费劲了;
-
下面的配置可以设置国际化配制文件的基础名,基础名就是将那个自己设置的文件去掉国家和语言留下的名字;比如
login_en_US.properties
,你去掉en_US
,再去掉后缀
,不就是一个login了,所以这个国际化配制文件的基础名就是i18n.login
;因为请你必须要加上它的包名不然就是这个结果;
#一定要加上包名,否则一定会无法显示切记加上i18n
spring.messages.basename=i18n.login
- 讲实话,实际运行的时候还是出现了一些问题,这篇博客介绍的很详细,跳转;
- 最后,想要转换成英语,要美式英语,虽然不知道为什么;
1. 如果想要自己切换网页的语言,那么可以这样做
#设置两个跳转链接,点一下就可以切换语言;
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
然后自己创建一个区域信息解析器(默认的区域信息获取请求头传过来的区域信息,然后进行国际化,当然自己创建就不一样了),也是一个处理类,这个处理类;
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获得请求参数中键l的值(由于在a标签中设置的是l='en');
String l = request.getParameter("l");
/*由于方法一定
要返回一个locale的值,
所以先创建一个loacle对象,
这里也需要给他一个默认的,
否则说不定会导致出现空指针;
而且它本身就有一个静态的方法;*/
Locale locale = Locale.getDefault();
//表示获得的l值并不是空,这时就需要判断值到底是多少;
if(!StringUtils.isEmpty(l)){
//在传送过来的值,是这种类型zh_CN,前面是语言,后面是国家;所以需要将它分开;
String[] values = l.split("_");
//恰巧locale有一个构造器含有这两个参数,传进去就可以了;
locale = new Locale(values[0],values[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
}
}
上面的类是自定义的区域信息处理类,主要思想就是通过一个a标签,重新传递原页面地址,然后再将原页面地址后面带上自己想要的参数,从而通过那些参数进行判断;
除了上面的方法,还需要在自己扩展的SpringMVC配置类中再次进行声明并将这个类放到容器里面;如下:
/*在另一个类中配制处理区域信息的方法
* 所以在这里需要对那个方法再次声明,
* 因为这里是SpringMVC的一个扩展配制类,
* 更重要的是我自定义的;
* */
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
注意点:
在自己扩展的SpringMVC配置文件里面,编写上面的方法的时候,一定要用方法名localeResolver,千万别改名字,否则就会无法将自定义的区域信息处理类放进去,到时候,一直取不到想要的结果;
3. 拦截器使用
在SpringBoot中,由于不希望用户总是重复提交,这时就可以用到重定向,但是重定向的时候又一定会会引起URL登录,这是不被允许的,所以需要设置拦截器;目的就是拦截非法的登入;
简单的登录请求处理
@Controller
public class LoginController {
/*规定请求的映射和请求的方式*/
//@RequestMapping(value = "/user/login",method = RequestMethod.POST)
//上面的注解方式是SpringMVC里面的,下面的注解方式是SpringBoot里面的
@PostMapping("/user/login")//两个注解都是一样的,这个注解底层有上面那个注解;
public String login(@RequestParam("username") String username, @RequestParam("password") String password, ModelMap map, HttpServletRequest request){
//这里没有连接数据库,照着视频来的,需要连接数据库的话可以去dao层;
if(!StringUtils.isEmpty(username)&&"123456".equals(password)){
//往session里面放用户名,证明该用户登录过了;
request.setAttribute("username",username);
//这是直接跳转,也就是转发,
//return "dashboard";
//使用重定向可以防止重复提交,但是登录就会失去意义,因为有了映射,可以直接通过网址进入;
return "redirect:/main.html";//定义一个跳转的路径,但是由于是虚拟映射需要到配置文件中进行配置;
}
map.addAttribute("msg","密码或账号登录错误");
return "login";
}
}
处理之后的话,写一个自定义的拦截器,进行判断用户是否登录;
//检查是否登录
public class LoginHandlerIntercepter implements HandlerInterceptor {
//在目标方法执行前执行的操作
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//从session里面获取用户的登录值,得到了,证明登录了,否则就是没有登录;
Object user = request.getSession().getAttribute("username");
//如果username是null
if(!(user==null)) {
return true;
}
//在登录界面显示消息,用了thymeleaf模板,所以${msg}可以获得这个信息;
request.setAttribute("msg","没有权限,请先登录");
//跳转回登录界面
request.getRequestDispatcher("/login.html").forward(request,response);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
上面之所以只有一个是因为第一个方法是请求生效之前,后面的方法有一个是生效之后才处理的,而拦截器,目前需要的只是生效前拦截住;
下面代码是为了让上面的拦截器生效,所以还要在自定义的SpringMVC配置类上进行定义;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//在“/**”表示任意请求都会被拦截,所以需要排除一些本身不登录就可以访问的请求页面;
//要排除哪些请求可以参考你自己定义了几个请求,否则默认“/”请求不要拦截;
//对了
registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**")
.excludePathPatterns("/login.html","/","/user/login","/**/*.css","/**/*.js");
}
excludePathPatterns方法是为了解除部分拦截;
在这里必须要注意,由于设置了拦截器,他一定会拦截请求,然后拦截器里面又写了一个跳转,必须要保证那个跳转可以正常访问,否则服务器肯定会崩溃,你想想,一个服务器就那么连接线程数,而且资源是有限的,你一直连接还不溢出来,一旦溢出来就没了,我就尝试了;