使用springboot来编写web项目的一些实现

1. 默认访问首页

1.将首页添加到templates下,以启用thymeleaf模板

2.编写配置类实现WebMvcConfigurer接口,重写addViewControllers方法来添加自定义视图解析器,使“/”请求可以直接映射到首页(定义内部类时要添加@Bean注解)

@Configuration
//WebMvcConfigurer接口中有很多方法的对应的是以往Springmvc配置文件中的属性
//使用其来扩展SpringMVC的功能
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //浏览器发送/jiat请求来到 success
        registry.addViewController("/jiat").setViewName("success");
    }

    //所有的WebMvcConfigurer组件都会一起起作用
    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        WebMvcConfigurer webMvcConfigurer = new WebMvcConfigurer() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/login.html").setViewName("login");
            }
        };
        return webMvcConfigurer;
    }

2.国际化

  1. 编写国际化配置文件;
  2. 使用ResourceBundleMessageSource管理国际化资源文件
  3. 在页面使用fmt:message取出国际化内容

现在的步骤:

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

    三个文件:
    login.properties   默认
    login_en_US.properties	英文
    login_zh_CN.properties	中文
    
    
    login.btn=登录
    login.password=密码
    login.remrember=记住
    login.tip=登录
    login.username=用户名
    
  2. SpringBoot自动配置好了管理国际化资源文件的组件

    public class MessageSourceAutoConfiguration {
        private static final Resource[] NO_RESOURCES = new Resource[0];
    
        public MessageSourceAutoConfiguration() {
        }
    
        @Bean
        @ConfigurationProperties(
            prefix = "spring.messages"
        )
        public MessageSourceProperties messageSourceProperties() {
            return new MessageSourceProperties();
        }
    
    
        @Bean
        public MessageSource messageSource(MessageSourceProperties properties) {
            ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
            //setBasenames  设置国际化资源文件的基础名(去掉语言国家代码的)
            if (StringUtils.hasText(properties.getBasename())) {
                messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
            }
            
    public class MessageSourceProperties {
        private String basename = "messages";   //说明不做任何配置时,配置文件可以直接放在类路径下叫messages.properties,也可以识别
        private Charset encoding;
    

    配置时只需要去到spring.messages.basename=“” 直接赋值基本名则在root路径下,如果有包路径则通过路径查找

    spring.messages.basename=i18n.login
    
  3. 去页面获取国际化的值

     th:text="#{login.tip}
    

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

    原理

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

//springboot配置了一个解析区域信息的解析器
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
    prefix = "spring.mvc",
    name = {"locale"}
)
public LocaleResolver localeResolver() {
    if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
        return new FixedLocaleResolver(this.mvcProperties.getLocale());
    } else {
        //没有指定使用定义的解析器,则使用AcceptHeaderLocaleResolver
        AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
        localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
        return localeResolver;
    }
}


//默认使用AcceptHeaderLocaleResolver,从请求头中获取区域信息(request.getLocale())
public class AcceptHeaderLocaleResolver implements LocaleResolver {
    public Locale resolveLocale(HttpServletRequest request) {
            Locale defaultLocale = this.getDefaultLocale();
            if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
                return defaultLocale;
            } else {
                Locale requestLocale = request.getLocale();
                List<Locale> supportedLocales = this.getSupportedLocales();
                if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
                    Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
  1. 点击链接切换国际化

    链接携带上区域信息:zh_CN或者en_US

    /**
     * 能连接上携带区域信息的解析器
     **/
    
    public class MyLocaleResolver implements LocaleResolver {
        @Override
        public Locale resolveLocale(HttpServletRequest httpServletRequest) {
            String l = httpServletRequest.getParameter("l");
            Locale locale=Locale.getDefault();  //注意要为locale设置默认,否则会报空指针,设置为request.getLocale()可以实现跟随浏览器语言改动
            if (!StringUtils.isEmpty(l)){
                String[] split = l.split("_");
                locale = new Locale(split[0],split[1]);
            }
            return locale;
        }
    
     //WebMvcConfigurer配置类中
    	@Bean
        public LocaleResolver localeResolver(){
            return  new MyLocaleResolver();
        }
    

3.登陆

开发期间模板引擎页面修改以后, 要实时生效

1.禁用模板缓存

#禁用缓存
spring.thymeleaf.cache=false

页面修改完成后ctrl+f9;重新编译

错误消息的显示:

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

2.防止表单重复提交

登陆成功后重定向页面,因为页面需要通过模板引擎渲染,要添加到试图解析器的映射中

//	  springboot 有Rest风格的mapping注解代替原先的RequestMapping
//    @DeleteMapping
//    @PutMapping
//    @GetMapping
    @PostMapping(value = "/user/login")
//    @RequestMapping(value = "/user/login", method = RequestMethod.POST)
    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); //登陆状态记录到session中
            //防止表单重复提交
            return "redirect:/main.html";  //不能有空格
        }
            map.put("msg","用户名密码错误");
            return "login";
    }

将重定向的/main.html在视图解析器中映射到实际的页面

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

3. 拦截器进行登陆检查

防止直接通过/main.html请求越过登陆,所以要使用拦截器进行拦截检查

  1. 定义拦截器:实现HandlerInterceptor接口重写preHandle方法,检查登陆状态,成功则放行,不然request放入错误信息,并转发到登陆页面
public class LoginHandlerInterceptor implements HandlerInterceptor {
    //登陆检查
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //目标方法执行之前
        Object user = request.getSession().getAttribute("loginUser");
        if (user == null){
            //未登录,返回登陆页面
            request.setAttribute("msg","没有权限,请先登录");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else {
            return true;
        }
    }
}
  1. 在实现WebMvcConfigurer的配置类中注册拦截器加入到容器中

    //注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//注册登陆拦截器:排除掉去往登陆页面的请求,登陆请求也不能被拦截
    	//spring boot2.x 版本需要重新对静态资源放行,不然也会被拦截;
    	registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login","/assets/**");
    }
    };
    
posted @ 2020-06-20 18:38  J,IAT  阅读(310)  评论(0编辑  收藏  举报