实现接口,PHP判断文章里是否有图片的简单方法10bet手机官网
分类:微服架构

本文的PHP程序用来判断文章里是否包含有图片,其主要实现思路就是用preg_match来检查内容里是否有匹配的“ 废话少说,下面是主要实现代码:

接口是面向对象编程里的重要特性,遗憾的是JavaScript并没有提供对接口的支持!怎么实现接口呢?

本文的PHP程序用来判断文章里是否包含有图片,其主要实现思路就是用preg_match来检查内容里是否有匹配的 <img ,抛开本文所述实例,我们还可以用preg_match来判断很多东西,比如邮箱地址里是否有 @ ,判断是否有手机号等等。
废话少说,下面是主要实现代码:

AuthenticationProvider

  • 默认实现:DaoAuthenticationProvider

授权方式提供者,判断授权有效性,用户有效性,在判断用户是否有效性,它依赖于UserDetailsService实例,开发人员可以自定义UserDetailsService的实现。

  1. additionalAuthenticationChecks方法校验密码有效性
  2. retrieveUser方法根据用户名获取用户
  3. createSuccessAuthentication完成授权持久化
@Component@Slf4jpublic class LindAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {  @Autowired  UserDetailsService userDetailsService;  @Autowired  private PasswordEncoder passwordEncoder;  /**   * 校验密码有效性.   *   * @param userDetails    .   * @param authentication .   * @throws AuthenticationException .   */  @Override  protected void additionalAuthenticationChecks(      UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)      throws AuthenticationException {    if (authentication.getCredentials() == null) {      logger.debug("Authentication failed: no credentials provided");      throw new BadCredentialsException(messages.getMessage(          "AbstractUserDetailsAuthenticationProvider.badCredentials",          "Bad credentials"));    }    String presentedPassword = authentication.getCredentials().toString();    if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword {      logger.debug("Authentication failed: password does not match stored value");      throw new BadCredentialsException(messages.getMessage(          "AbstractUserDetailsAuthenticationProvider.badCredentials",          "Bad credentials"));    }  }  /**   * 获取用户.   *   * @param username       .   * @param authentication .   * @return   * @throws AuthenticationException .   */  @Override  protected UserDetails retrieveUser(      String username, UsernamePasswordAuthenticationToken authentication)      throws AuthenticationException {    UserDetails loadedUser = userDetailsService.loadUserByUsername;    if (loadedUser == null) {      throw new InternalAuthenticationServiceException(          "UserDetailsService returned null, which is an interface contract violation");    }    return loadedUser;  }} /**   * 授权持久化.   */  @Override  protected Authentication createSuccessAuthentication(Object principal,                                                       Authentication authentication, UserDetails user) {    return super.createSuccessAuthentication(principal, authentication, user);  }
$url="http://XXXXX/article/012.html";
$content=file_get_contents($url); //读取文章页面源代码
if(preg_match("//",$content)){ //进行正则匹配判断是否有图片
  echo "检测到图片";
}else{
  echo "未发现图片";
}

在实际中,我们可以在注释中定义好接口,在实际的代码中予以实现

$url="http://XXXXX/article/012.html";
$content=file_get_contents($url); //读取文章页面源代码
if(preg_match("/<img.*>/",$content)){ //进行正则匹配判断是否有图片
  echo "检测到图片";
}else{
  echo "未发现图片";
}

AuthenticationFilter

  • 默认实现:UsernamePasswordAuthenticationFilter

授权过滤器,你可以自定义它,并把它添加到默认过滤器前或者后去执行,主要用来到授权的持久化,它可以从请求上下文中获取你的user,password等信息,然后去判断它是否符合规则,最后通过authenticate方法去授权。默认的UsernamePasswordAuthenticationFilter过滤器,主要判断请求方式是否为post,并且对username和password进行了默认值的处理,总之,在这个过滤器里不会涉及到具体业务。

public class LindUserNameAuthenticationFilter extends AbstractAuthenticationProcessingFilter {  public LindUserNameAuthenticationFilter() {    super(new AntPathRequestMatcher("/login", "GET"));  }  @Override  public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {    String username = request.getParameter("username");    String password = request.getParameter("password");    if (username == null) {      throw new InternalAuthenticationServiceException("Failed to get the username");    }    if (password == null) {      throw new InternalAuthenticationServiceException("Failed to get the password");    }    UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(        username, password);    authRequest.setDetails(authenticationDetailsSource.buildDetails;    return this.getAuthenticationManager().authenticate(authRequest);  }}

比如:

UserDetialsService

这是一个接口,有默认的实现方式,一般的,我们需要根据业务去重新实现它,比如从你的用户表获取当前授权的用户信息,你需要在UserDetialsService实现类里对用户表进行读取操作;它一般会在AuthenticationProvider里的retrieveUser方法中被使用,这就像面向对象里的模板方法模式一样,springSecurity把检验的步骤设计好了,咱们开发只要根据规则去实现具体细节就好。

@Componentpublic class MyUserDetailService implements UserDetailsService {  @Autowired  private PasswordEncoder passwordEncoder;  @Override  public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {    /*      设置用户和角色需要注意:      1. commaSeparatedStringToAuthorityList放入角色时需要加前缀ROLE_,而在controller使用时不需要加ROLE_前缀      2. 放入的是权限时,不能加ROLE_前缀,hasAuthority与放入的权限名称对应即可    */    List<UserDetails> userDetailsList = new ArrayList<>();    userDetailsList.add(User.builder()        .username("admin")        .password(passwordEncoder.encode("123"))        .authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("read,ROLE_ADMIN")).build;    userDetailsList.add(User.builder()        .username("user")        .password(passwordEncoder.encode("123"))        .authorities(AuthorityUtils.commaSeparatedStringToAuthorityList("read,ROLE_USER"))        .build;    //获取用户    return userDetailsList.stream()        .filter(o -> o.getUsername().equals        .findFirst()        .orElse;  }}
/*
interface Composite {
    function add(child);
    function remove(child);
    function getChild(index);
}
interface FormItem {
    function save();
}
*/
var CompositeForm = function(id, method, action) { // implements Composite, FormItem
...
};
// Implement the Composite interface.
CompositeForm.prototype.add = function(child) {
...
};
CompositeForm.prototype.remove = function(child) {
...
};
CompositeForm.prototype.getChild = function(index) {
...
};
// Implement the FormItem interface.
CompositeForm.prototype.save = function() {
...
};

在WebSecurityConfig里开启它

@Configuration@EnableWebSecurity@EnableGlobalMethodSecurity(prePostEnabled = true)public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  @Autowired  LindAuthenticationSuccessHandler lindAuthenticationSuccessHandler;  @Autowired  LindAuthenticationFailHandler lindAuthenticationFailHandler;  @Autowired  LindAuthenticationProvider lindAuthenticationProvider;  @Override  protected void configure(HttpSecurity http) throws Exception {    http        .authorizeRequests()        .antMatchers("/", "/index").permitAll()        .antMatchers("/admin/**").hasRole("ADMIN")//按路由授权        .anyRequest().authenticated()        .and()        .formLogin()        .loginPage("/login")        .defaultSuccessUrl("/hello")//默认登录成功后跳转的页面        .successHandler(lindAuthenticationSuccessHandler)        .failureHandler(lindAuthenticationFailHandler)        .permitAll()        .and()        .addFilterAt(lindAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class).authorizeRequests        .logout()        .permitAll();  }  /**   * 自定义的Filter.   */  @Bean  LindUserNameAuthenticationFilter lindAuthenticationFilter() {    LindUserNameAuthenticationFilter phoneAuthenticationFilter = new LindUserNameAuthenticationFilter();    ProviderManager providerManager =        new ProviderManager(Collections.singletonList(lindAuthenticationProvider));    phoneAuthenticationFilter.setAuthenticationManager(providerManager);    phoneAuthenticationFilter.setAuthenticationSuccessHandler(lindAuthenticationSuccessHandler);    phoneAuthenticationFilter.setAuthenticationFailureHandler(lindAuthenticationFailHandler);    return phoneAuthenticationFilter;  }  /**   * 密码生成策略.   *   * @return   */  @Bean  public PasswordEncoder passwordEncoder() {    return new BCryptPasswordEncoder();  }}

 

认证时执行的顺序

  1. LindUserNameAuthenticationFilter
  2. LindAuthenticationProvider.retrieveUser
  3. LindAuthenticationProvider.additionalAuthenticationChecks
  4. UserDetailsService
  5. Authentication

springSecurity源码:

实现接口的程序员是否将这些接口都实现了呢?我们没办法保证!因为这里没有任何办法去检查是否都实现了

我们需要一个检查是否实现了接口的机制,可以这样:

/*
interface Composite {
    function add(child);
    function remove(child);
    function getChild(index);
}
interface FormItem {
    function save();
}
*/
var CompositeForm = function(id, method, action) {
    this.implementsInterfaces = ['Composite', 'FormItem'];
...
};
...
function addForm(formInstance) {
    if(!implements(formInstance, 'Composite', 'FormItem')) {
        throw new Error("Object does not implement a required interface.");
    }
...
}
// The implements function, which checks to see if an object declares that it
// implements the required interfaces.
function implements(object) {
    for(var i = 1; i < arguments.length; i++) { // Looping through all arguments
    // after the first one.
    var interfaceName = arguments[i];
    var interfaceFound = false;
    for(var j = 0; j < object.implementsInterfaces.length; j++) {
        if(object.implementsInterfaces[j] == interfaceName) {
        interfaceFound = true;
        break;
        }
    }

    if(!interfaceFound) {
        return false; // An interface was not found.
        }
    }
    return true; // All interfaces were found.
}

这种方法让程序员在写的时候注明实现了哪些接口: this.implementsInterfaces = ['Composite', 'FormItem']; 在调用的时候使用implements方法来判断是否实现了,理论上可行,很有可能写上了实现了'Composite'接口,但是代码里却并没有add方法!因此,我们需要检验实现接口的类是否包含了接口里的方法!所以,接口必须从注释中解放出来:

// Interfaces.
var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
var FormItem = new Interface('FormItem', ['save']);
// CompositeForm class
var CompositeForm = function(id, method, action) { // implements      Composite, FormItem
...
};
...
function addForm(formInstance) {
    Interface.ensureImplements(formInstance, Composite, FormItem);
    // This function will throw an error if a required method is not implemented,
    // halting execution of the function.
    // All code beneath this line will be executed only if the checks pass.
...
}

    定义接口Composite,FormItem,并且CompositeForm实现这两个接口,在使用的时候,用Interface.ensureImplements来检验formInstance是否实现了这两个接口中的所有方法。

来看看Interface的定义:两个参数,第一个参数是接口名称,第二个参数是接口包含的方法数组

// Constructor.
var Interface = function(name, methods) {
    if(arguments.length != 2) {
        throw new Error("Interface constructor called with " + arguments.length +
"arguments, but expected exactly 2.");
}
    this.name = name;
    this.methods = [];
    for(var i = 0, len = methods.length; i < len; i++) {
        if(typeof methods[i] !== 'string') {
            throw new Error("Interface constructor expects method names to be "
+ "passed in as a string.");
        }
    this.methods.push(methods[i]);
    }
};

为Interface 添加建议接口是否实现的静态方法

// Constructor.
Interface.ensureImplements = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.ensureImplements called with " +
arguments.length + "arguments, but expected at least 2.");
    }
    for(var i = 1, len = arguments.length; i < len; i++) {
        var interface = arguments[i];
        if(interface.constructor !== Interface) {
            throw new Error("Function Interface.ensureImplements expects arguments"
+ "two and above to be instances of Interface.");
        }
    for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
        var method = interface.methods[j];
        if(!object[method] || typeof object[method] !== 'function') {
            throw new Error("Function Interface.ensureImplements: object "
+ "does not implement the " + interface.name
+ " interface. Method " + method + " was not found.");
        }
    }
    }
};

本文由10bet手机官网发布于微服架构,转载请注明出处:实现接口,PHP判断文章里是否有图片的简单方法10bet手机官网

上一篇:利用APR本地库提高Tomcat性能,安装教程 下一篇:没有了
猜你喜欢
热门排行
精彩图文