手机网站的优缺点,凡科沙发官网,自己制作一个网页,有限公司在线网站使用Beetl开发网页时#xff0c;在网页中使用的CSS、JS、图片等静态资源需要进行适当的配置才可以展示。大致的过程如下#xff1a; #xff08;1#xff09;首先Spring Security框架需要允许js、css、图片资源免授权访问。 #xff08;2#xff09;网站开发时#xff0… 使用Beetl开发网页时在网页中使用的CSS、JS、图片等静态资源需要进行适当的配置才可以展示。大致的过程如下 1首先Spring Security框架需要允许js、css、图片资源免授权访问。 2网站开发时如果网页文件不放在SpringBoot工程内部打包单独指定了文件目录需要在Config文件中加载文件系统中的网页目录。 3网页文件中引用静态文件的路径不能使用相对路径需要使用绝对路径。 4如果使用了Nginx静态资源文件路径还要加上 Nginx反向代理的路径。
下面是实现过程 首先贴一下之前openjweb-sys工程的WebSecurityConfig文件增加了js目录、css目录、images目录的免授权访问
package opackage org.openjweb.sys.config;import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.openjweb.core.service.CommUserService;
import org.openjweb.sys.auth.security.AESPasswordEncoder;
import org.openjweb.sys.auth.security.MD5PasswordEncoder;
import org.openjweb.sys.auth.security.MyAccessDecisionManager;
import org.openjweb.sys.auth.security.MyFilterInvocationSecurityMetadataSource;
import org.openjweb.sys.entry.JwtAuthenticationEntryPoint;
import org.openjweb.sys.filter.JwtAuthenticationFilter;
import org.openjweb.sys.handler.JWTLogoutSuccessHandler;
import org.openjweb.sys.handler.JwtAccessDeniedHandler;
import org.openjweb.sys.handler.LoginFailureHandler;
import org.openjweb.sys.handler.LoginSuccessHandler;
import org.openjweb.sys.provider.MyAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;Slf4j
Configuration
EnableWebSecurity
RequiredArgsConstructor
EnableGlobalMethodSecurity(prePostEnabled true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {AutowiredCommUserService userDetailService;Beanpublic PasswordEncoder passwordEncoder(){return new AESPasswordEncoder();}AutowiredLoginSuccessHandler loginSuccessHandler;AutowiredLoginFailureHandler loginFailureHandler;AutowiredJwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;AutowiredJwtAccessDeniedHandler jwtAccessDeniedHandler;AutowiredJWTLogoutSuccessHandler jwtLogoutSuccessHandler;Value(${oauth2.server})private boolean isOAuth2Server false;private static final String[] ALLOW_URL_LIST {///login,/logout,/captcha,/favicon.ico,///api/jwt/**,/api/cms/**,/api/b2c/**,/api/b2b2c/**,/api/sns/**,/api/comm/**,/api/cms1/**,/api/store/**,/demo/**,/oauth/**, //允许oauth认证的路径/webjars/**, //webjars js允许的路径/testduoyu,/i18n/**,/**/*.html, //swagger/api/comm/user/login,/api/weixin/login,/api/weixin/getVueMenu,/api/comm/user/getUserInfo2,/front/**,/**/js/**,/**/images/**,/**/css/**};//作用暴露AuthenticationManager给其他Bean使用BeanOverrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();//return super.authenticationManagerBean();}//这个和上面的是什么区别能一起用吗/*BeanOverridepublic AuthenticationManager authenticationManagerBean() throws Exception{return super.authenticationManagerBean();}*/Overrideprotected void configure(HttpSecurity http) throws Exception {//下面注释掉的是第一阶段的示例/* http.cors().and().csrf().disable()//登录表单.formLogin().and().authorizeRequests().antMatchers(ALLOW_URL_LIST).permitAll().anyRequest().authenticated();*///下面是第二阶段整合了数据库权限控制的示例log.info(是否配置了oauth2 server:::::);log.info(String.valueOf(this.isOAuth2Server));if(this.isOAuth2Server){log.info(OAUTH2模式...........);http.formLogin()//.loginPage(/login.html).loginProcessingUrl(/login).and().authorizeRequests().antMatchers(/login.html, /img/**,/demo/**,/webjars/**, /testduoyu,/i18n/**,/api/b2c/b2carea/**,/api/store/**,/**/*.html, /api/comm/user/login,/api/weixin/login,/api/weixin/getVueMenu,/api/comm/user/getUserInfo2, /front/**,/**/js/**, /**/images/**, /**/css/**).permitAll().anyRequest().authenticated().and().csrf().disable();}else {log.info(非OAUTH2模式............);http.authorizeRequests().withObjectPostProcessor(new ObjectPostProcessorFilterSecurityInterceptor() {Overridepublic O extends FilterSecurityInterceptor O postProcess(O object) {object.setSecurityMetadataSource(cfisms());object.setAccessDecisionManager(cadm());return object;}}).and().formLogin()//先注掉这个检查oauth认证//.successHandler(loginSuccessHandler) //登录成功处理.failureHandler(loginFailureHandler) //登录失败处理.loginProcessingUrl(/login).permitAll()//.loginProcessingUrl(/demo/jwt/login).permitAll().and().logout().logoutSuccessHandler(jwtLogoutSuccessHandler)// 禁用session.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)// 配置拦截规则.and().authorizeRequests().antMatchers(ALLOW_URL_LIST).permitAll().anyRequest().authenticated()// 异常处理器.and().exceptionHandling()//接口登录模式打开这个//.authenticationEntryPoint(jwtAuthenticationEntryPoint) //这个影响登录会导致/login登录蔬菜.accessDeniedHandler(jwtAccessDeniedHandler)// 配置自定义的过滤器//这个jwtAuthenticationFilter 不加也执行了是否增加了会调整多个过滤器的执行顺序.and().addFilter(jwtAuthenticationFilter()).logout().permitAll().and().csrf().disable();}}/*BeanPasswordEncoder PasswordEncoder() {//return md5PasswordEncoder;//return aesPasswordEncoder;//这个不行return new AESPasswordEncoder();//return new BCryptPasswordEncoder();//return new Md5PasswordEncoder();}*//*AutowiredMD5PasswordEncoder md5PasswordEncoder;AutowiredAESPasswordEncoder aesPasswordEncoder;*/Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {if(true){//如果自定义AuthenticationProvider 则不使用这个//auth.userDetailsService(userDetailService).passwordEncoder(aesPasswordEncoder);//auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());DaoAuthenticationProvider provider new DaoAuthenticationProvider();provider.setUserDetailsService(userDetailService);provider.setPasswordEncoder(passwordEncoder());auth.authenticationProvider(provider);}else{//自定义AuthenticationProviderauth.authenticationProvider(new MyAuthenticationProvider(userDetailService));}}BeanMyAccessDecisionManager cadm() {//System.out.println(加载角色权限设置。。。。。。。。。。。。);return new MyAccessDecisionManager();}BeanMyFilterInvocationSecurityMetadataSource cfisms() {//System.out.println(加载权限设置。。。。。。。。。。。。);return new MyFilterInvocationSecurityMetadataSource();}BeanConditionalOnExpression(${oauth2.server}false)JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {JwtAuthenticationFilter jwtAuthenticationFilter new JwtAuthenticationFilter(authenticationManager());return jwtAuthenticationFilter;}
}然后在openjweb-core工程的WebMvcConfig中增加文件系统中静态资源目录 package org.openjweb.core.config;import lombok.extern.slf4j.Slf4j;
import org.beetl.core.GroupTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;import java.util.HashMap;
import java.util.Map;Configuration
Slf4j
public class WebMvcConfig implements WebMvcConfigurer {Value(${beetl.fileTemplatesPath:}) String fileTemplatesPath;Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController(/testduoyu).setViewName(testduoyu);//不能命名testlocale 可能locale有冲突}Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {log.info(fileTemplatePath::);log.info(fileTemplatesPath);if(!fileTemplatesPath.endsWith(/))fileTemplatesPath/;//D:/tmp/beetl/templatesregistry.addResourceHandler(/**).addResourceLocations(file:fileTemplatesPath).addResourceLocations(classpath:/static/);}Overridepublic void addInterceptors(InterceptorRegistry registry) {log.info(设置国际化参数lang...........);//默认拦截器 其中lang表示切换语言的参数名 LocaleChangeInterceptor 指定切换国际化语言的参数名。// 例如?langzh_CN 表示读取国际化文件messages_zh_CN.properties。//System.out.println(增加国际化拦截器...........);LocaleChangeInterceptor localeInterceptor new LocaleChangeInterceptor();localeInterceptor.setParamName(lang);// 指定设置国际化的参数registry.addInterceptor(localeInterceptor);}
}在上面的代码中增加了addResourceHandlers方法此方法加载了文件系统fileTemplatePath目录的静态资源在开发环境中,application-dev.yml中指定的fileTemplatePath是d:\tmp\beetl\templates。
项目的静态网页 假设项目的静态网页路径是D:\tmp\beetl\templates\cms\site\wenhua在此路径下有js、css、images目录以及html文件下面截取了局部的HTML文件
!DOCTYPE html
html xmlnshttp://www.w3.org/1999/xhtml
head
meta http-equivContent-Type contenttext/html; charsetutf-8 /
meta http-equivX-UA-Compatible contentIEEdge /
title中国文化网/title
meta namekeywords content中国文化网
meta namedescription content中国文化网
link href/clouds/cms/site/wenhua/css/common.css relstylesheet typetext/css /
link href/clouds/cms/site/wenhua/css/font-awesome/css/font-awesome.min.css relstylesheet/
link href/clouds/cms/site/wenhua/css/index.css relstylesheet typetext/css /
link href/clouds/cms/site/wenhua/css/focus1.css relstylesheet typetext/css /
script typetext/javascript src/clouds/cms/site/wenhua/js/jquery.1.7.2.min.js/script
script typetext/javascript src/clouds/cms/site/wenhua/js/koala.min.1.5.js/script
script typetext/javascript$(function(){ var pw $(#po-pic).width();var sw $(window).width();var lw (pw - sw)/2;$(#po-pic).attr(style,margin-left:-lwpx);})
/script
/head
body
div classtopdiv classlayoutdiv classfl logoa href#img src/clouds/cms/site/wenhua/images/logo.jpg width257 height70 border0 //a/divdiv classfr top-navdiv classfr searchinput typetext namesearch classfr /span高级搜索nbsp;nbsp;a href#i classfa fa-search fa-lg/i/a/span/diva href#邮箱登陆1/aspanemsp;|emsp;/span/divdiv classclear/div/div
/div
注意静态资源文件的引用/clouds/cms/site/wenhua/css/common.css、/clouds/cms/site/wenhua/images/logo.jpg其中clouds是使用Nginx反向代理将8001端口转发到了SpringBoot如果没使用nginx而是使用了localhost:8001,则不需要使用/clouds,后面/cms开头的路径则是针对模版文件跟路径下的相对路径根路径为D:\tmp\beetl\templates。 现在我们开发一个控制层类用于展示静态页面。在openjweb-cms内容管理模块增加一个控制层类
package org.openjweb.cms.controller;import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.openjweb.cms.service.CmsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.HashMap;
import java.util.Map;Api(tags 内容管理-前端查询)
Slf4j
Controller
RequestMapping(/front) //public class CmsInfoController {Autowiredprivate CmsInfoService cmsInfoService;RequestMapping(value/index)public String index( Model model) {return cms/site/wenhua/index.html;//返回页面名}}测试访问http://localhost:8001/front/index 不使用nginx则html中静态资源不要加/clouds
返回的静态页效果