Spring Boot 2 обрабатывает данные формы, где json - значения ключей

Не уверен, что это поможет вам или нет, но я предлагаю решение, учитывая следующие предположения -

  1. Вам нужно элегантное решение для проверки всех условий
  2. Условия могут меняться в будущем и в любое время.
  3. Одно условие не должно зависеть от других.

Однако я также рассмотрел следующее:

  1. Указанный файл имеет минимальные ошибки. Если это так, то моему коду могут потребоваться некоторые изменения, чтобы справиться с этим.
  2. Я использовал Stack для отслеживания блоков if(.

Хорошо, вот решение -

Я использовал C # и с ним MEF (Microsoft Extensibility Framework) для реализации настраиваемых парсеров. Идея состоит в том, чтобы использовать синтаксический анализатор для синтаксического анализа и список настраиваемых классов валидатора для проверки строки и возврата true или false на основе проверки. Затем вы можете добавить или удалить любой валидатор в любое время или добавить новые, если хотите. До сих пор я уже реализовал для S1, S2 и S3 вы упомянули, проверьте классы в точке 3. Вам нужно добавить классы для s4, s5, если вам нужно в будущем.

  1. Сначала создайте Интерфейсы -
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FileParserDemo.Contracts
    {
        public interface IParser
        {
            String[] GetMatchedLines(String filename);
        }
    
        public interface IPatternMatcher
        {
            Boolean IsMatched(String line, Stack<string> stack);
        }
    }
    
  2. Затем появляется программа чтения и проверки файлов -
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using FileParserDemo.Contracts;
    using System.ComponentModel.Composition.Hosting;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Collections;
    
    namespace FileParserDemo.Parsers
    {
        public class Parser : IParser
        {
            [ImportMany]
            IEnumerable<Lazy<IPatternMatcher>> parsers;
            private CompositionContainer _container;
    
            public void ComposeParts()
            {
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new AssemblyCatalog(typeof(IParser).Assembly));
                _container = new CompositionContainer(catalog);
                try
                {
                    this._container.ComposeParts(this);
                }
                catch
                {
    
                }
            }
    
            public String[] GetMatchedLines(String filename)
            {
                var matched = new List<String>();
                var stack = new Stack<string>();
                using (StreamReader sr = File.OpenText(filename))
                {
                    String line = "";
                    while (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                        var m = true;
                        foreach(var matcher in this.parsers){
                            m = m && matcher.Value.IsMatched(line, stack);
                        }
                        if (m)
                        {
                            matched.Add(line);
                        }
                     }
                }
                return matched.ToArray();
            }
        }
    }
    
  3. Затем идет реализация отдельных шашек, имена классов объясняются сами по себе, поэтому я не думайте, что им нужно больше описаний.
    using FileParserDemo.Contracts;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    namespace FileParserDemo.PatternMatchers
    {
        [Export(typeof(IPatternMatcher))]
        public class MatchAllNumbers : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("\\d+");
                return regex.IsMatch(line);
            }
        }
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveIfBlock : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("if\\(");
                if (regex.IsMatch(line))
                {
                    foreach (var m in regex.Matches(line))
                    {
                        //push the if
                        stack.Push(m.ToString());
                    }
                    //ignore current line, and will validate on next line with stack
                    return true;
                }
                regex = new Regex("//endif");
                if (regex.IsMatch(line))
                {
                    foreach (var m in regex.Matches(line))
                    {
                        stack.Pop();
                    }
                }
                return stack.Count == 0; //if stack has an item then ignoring this block
            }
        }
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveWithEndPeriod : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("(?m)(?!\\d+.*?\\.$)\\d+");
                return regex.IsMatch(line);
            }
        }
    
    
        [Export(typeof(IPatternMatcher))]
        public class RemoveWithInParenthesis : IPatternMatcher
        {
            public Boolean IsMatched(String line, Stack<string> stack)
            {
                var regex = new Regex("\\(.*\\d+.*\\)");
                return !regex.IsMatch(line);
            }
        }
    }
    
  4. Программа -
    using FileParserDemo.Contracts;
    using FileParserDemo.Parsers;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace FileParserDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var parser = new Parser();
                parser.ComposeParts();
                var matches = parser.GetMatchedLines(Path.GetFullPath("test.txt"));
                foreach (var s in matches)
                {
                    Console.WriteLine(s);
                }
                Console.ReadLine();
            }
        }
    }
    

Для тестирования я взял файл примера @ Tiago в качестве Test.txt, который имел следующие строки -

this is a text
it should match 12345
if(
it should not match 12345
//endif 
it should match 12345
it should not match 12345.
it should not match ( blabla 12345  blablabla )
it should not match ( 12345 )
it should match 12345

Дает выход -

it should match 12345
it should match 12345
it should match 12345

Не знаю, помогло бы вам это или нет, мне было весело провести время с ним ....:)

Лучшая часть этого заключается в том, что для добавления нового условия все, что вам нужно сделать, это обеспечить реализацию IPatternMatcher, оно будет автоматически вызвано и, следовательно, будет проверено.

0
задан jprism 16 January 2019 в 16:11
поделиться

1 ответ

Я не верю, что есть нестандартное картографирование.

Вы можете добавить GenericConvertor в WebConversionService, который использует WebDataBinder. Вам нужно будет перечислить все ваши типы объектов. Примерно так:

import java.util.HashSet;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class JsonFieldConverter implements GenericConverter {

    @Autowired
    private ObjectMapper objectMapper;

    // Add a new ConvertiblePair for each type you want to convert json 
    // in a field to using the objectMapper. This example has Patient and Doctor
    private static Set<ConvertiblePair> convertibleTypes = new HashSet<>();
    static {
        convertibleTypes.add(new ConvertiblePair(String.class, Patient.class));
        convertibleTypes.add(new ConvertiblePair(String.class, Doctor.class));
    }

    @Override
    public Set<ConvertiblePair> getConvertibleTypes() {
        return convertibleTypes;
    }

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
        try {
            return objectMapper.readValue(source.toString(), targetType.getType());
        } catch (Exception e) {
            // TODO deal with the error.
            return source;
        }

    }
}

И @ControllerAdvice, чтобы подключить его к подшивке данных:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.format.WebConversionService;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

@ControllerAdvice
public class JsonFieldConfig {

    @Autowired
    private JsonFieldConverter jsonFieldConverter;

    @InitBinder
    private void bindMyCustomValidator(WebDataBinder binder) {
        ((WebConversionService)binder.getConversionService()).addConverter(jsonFieldConverter);
    }

}  
0
ответ дан pcoates 16 January 2019 в 16:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: