স্প্রিং এমভিসি ধরণের রূপান্তর: প্রপার্টিএডিটর বা রূপান্তরকারী?


129

আমি স্প্রিং এমভিসিতে ডেটা বাঁধাই ও রূপান্তর করার সবচেয়ে সহজ এবং সহজ উপায়টি খুঁজছি। যদি সম্ভব হয় তবে কোনও এক্সএমএল কনফিগারেশন না করে।

এখনও অবধি আমি এর মতো প্রপার্টি এডিটর ব্যবহার করছি :

public class CategoryEditor extends PropertyEditorSupport {

    // Converts a String to a Category (when submitting form)
    @Override
    public void setAsText(String text) {
        Category c = new Category(text);
        this.setValue(c);
    }

    // Converts a Category to a String (when displaying form)
    @Override
    public String getAsText() {
        Category c = (Category) this.getValue();
        return c.getName();
    }

}

এবং

...
public class MyController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Category.class, new CategoryEditor());
    }

    ...

}

এটি সহজ: উভয় রূপান্তর একই শ্রেণিতে সংজ্ঞায়িত করা হয়, এবং বাঁধাই সোজা is আমি যদি আমার সমস্ত কন্ট্রোলারগুলিতে একটি সাধারণ বাঁধাই করতে চাইতাম তবে আমি আমার এক্সএমএল কনফিগারেশনে 3 টি লাইন যুক্ত করতে পারতাম ।


কিন্তু স্প্রিং 3.x রূপান্তরকারীদের ব্যবহার করে এটি করার একটি নতুন উপায় প্রবর্তন করেছে :

একটি স্প্রিং পাত্রে, এই সিস্টেমটি প্রপার্টি এডিটরের বিকল্প হিসাবে ব্যবহার করা যেতে পারে

সুতরাং আসুন আমি বলি যে আমি রূপান্তরকারীগুলি ব্যবহার করতে চাই কারণ এটি "সর্বশেষ বিকল্প"। আমাকে দুটি রূপান্তরকারী তৈরি করতে হবে :

public class StringToCategory implements Converter<String, Category> {

    @Override
    public Category convert(String source) {
        Category c = new Category(source);
        return c;
    }

}

public class CategoryToString implements Converter<Category, String> {

    @Override
    public String convert(Category source) {
        return source.getName();
    }

}

প্রথম অসুবিধা: আমাকে দুটি ক্লাস করতে হবে। উপকার: উদারতার জন্য ধন্যবাদ দেওয়ার দরকার নেই।

তারপরে, আমি কীভাবে রূপান্তরকারীগুলিকে ডেটা বাঁধতে পারি?

দ্বিতীয় ত্রুটি: এটি একটি নিয়ামক হিসাবে করার জন্য আমি কোনও সহজ উপায় (টিকা বা অন্যান্য প্রোগ্রামিক সুবিধা) খুঁজে পাই নি: মত কিছুই নয় someSpringObject.registerCustomConverter(...);

আমি খুঁজে পেয়েছি কেবলমাত্র উপায় ক্লান্তিকর হবে, সহজ নয় এবং কেবল সাধারণ ক্রস-নিয়ামক বাঁধাই সম্পর্কে:

  • এক্সএমএল কনফিগারেশন :

    <bean id="conversionService"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="somepackage.StringToCategory"/>
                <bean class="somepackage.CategoryToString"/>
            </set>
        </property>
    </bean>
    
  • জাভা কনফিগারেশন ( কেবলমাত্র বসন্ত 3.1+ এ ):

    @EnableWebMvc
    @Configuration
    public class WebConfig extends WebMvcConfigurerAdapter {
    
        @Override
        protected void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new StringToCategory());
            registry.addConverter(new CategoryToString());
        }
    
    }
    

এই সমস্ত ত্রুটিগুলি সহ কেন রূপান্তরকারী ব্যবহার করছেন? আমি কিছু অনুপস্থিত করছি ? এমন অন্য কৌশলগুলি কি আমি অবগত নই?

আমি প্রপার্টি এডিটরস ব্যবহার করতে প্রলুব্ধ হই ... বাঁধাই অনেক সহজ এবং দ্রুত is


দ্রষ্টব্য (স্প্রিং ৩.২.১7 ব্যবহার করে আমিও হোঁচট খেয়েছি): <এমভিসি: টিকাটি চালিত /> ব্যবহার করার সময় আসলে এই রূপান্তরকরণের পরিষেবাটি শিম: <এমভিসি: টিকা-চালিত রূপান্তর-পরিষেবা = "রূপান্তরকরণ পরিষেবা" /> উল্লেখ করা দরকার
mauhiz

অ্যাডফর্ম্যাটরস (...) অবশ্যই সর্বজনীন হতে হবে। এছাড়াও 5.0 থেকে WebMvcConfigurerAdapter হ্রাস করা হয়েছে।
পাকো অ্যাবাতো

উত্তর:


55

এই সমস্ত ত্রুটিগুলি সহ কেন রূপান্তরকারী ব্যবহার করছেন? আমি কিছু অনুপস্থিত করছি ? এমন অন্য কৌশলগুলি কি আমি অবগত নই?

না, আমি মনে করি আপনি প্রপার্টিএডিটর এবং রূপান্তরকারী উভয়কেই খুব বিস্তৃতভাবে বর্ণনা করেছেন, কীভাবে প্রত্যেকে ঘোষণা করা হয় এবং নিবন্ধিত হয়।

আমার মনে, প্রপার্টিএডিটরগুলি সুযোগের মধ্যে সীমাবদ্ধ - তারা স্ট্রিংকে কোনও প্রকারে রূপান্তরিত করতে সহায়তা করে এবং এই স্ট্রিংটি সাধারণত ইউআই থেকে আসে এবং সুতরাং @ ইনিটবাইন্ডার ব্যবহার করে একটি সম্পত্তি অ্যাডিটর নিবন্ধন করে এবং ওয়েবডাটাবাইন্ডার ব্যবহার করে বোঝা যায়।

অন্যদিকে রূপান্তরকারীটি আরও জেনেরিক, এটি কেবলমাত্র ইউআই সম্পর্কিত রূপান্তরগুলির জন্য নয় (স্ট্রিং থেকে টার্গেটের ধরণ) - সিস্টেমের মধ্যে যে কোনও রূপান্তর করার জন্য intended উদাহরণস্বরূপ, স্প্রিং ইন্টিগ্রেশনটি একটি বার্তা পেডলোডকে পছন্দসই ধরণের রূপান্তর করতে ব্যাপকভাবে একটি রূপান্তরকারী ব্যবহার করে।

আমি মনে করি ইউআই সম্পর্কিত প্রবাহের জন্য প্রপার্টি এডিটরগুলি বিশেষত সেই ক্ষেত্রে যেখানে আপনার নির্দিষ্ট কমান্ডের সম্পত্তিটির জন্য কিছু কাস্টম করা দরকার for অন্যান্য ক্ষেত্রে, আমি স্প্রিং রেফারেন্স থেকে সুপারিশ গ্রহণ করব এবং পরিবর্তে একটি রূপান্তরকারী লিখব (উদাহরণস্বরূপ, লম্বা আইডি থেকে কোনও সত্তায় নমুনা হিসাবে রূপান্তর করতে)।


5
আর একটি ভাল জিনিস যা রূপান্তরকারীরা রাষ্ট্রহীন, যখন সম্পত্তি সম্পাদকরা স্টেটফুল থাকে এবং বহুবার তৈরি হয় এবং অনেক এপিআই কল দিয়ে প্রয়োগ করা হয়, আমি মনে করি না যে এটির পারফরম্যান্সে কোনও বড় প্রভাব ফেলবে তবে রূপান্তরকর্তারা কেবল ক্লিনার এবং সরল।
বরিস ট্রুখভ

1
@ বরিস ক্লিনার হ্যাঁ, তবে সহজ নয়, বিশেষত একটি শিক্ষানবিশদের জন্য: আপনাকে ২ টি রূপান্তরকারী ক্লাস লিখতে হবে + এক্সএমএল কনফিগার বা জাভা কনফিগারেশনে কয়েকটি লাইন যুক্ত করতে হবে। আমি স্প্রিং এমভিসি ফর্ম জমা / প্রদর্শনের কথা বলছি, সাধারণ রূপান্তরগুলির সাথে (কেবল সত্তা নয়)।
জেরোম ডালবার্ট

16
  1. স্ট্রিং রূপান্তরগুলিতে / থেকে রূপান্তরকারীগুলির পরিবর্তে বিন্যাসগুলি ( org.springframework.format. Formatter প্রয়োগ করুন ) ব্যবহার করুন। এটা আছে মুদ্রণ (...) এবং পার্স (...) পদ্ধতি, যাতে আপনি দুই মাত্র এক বর্গ পরিবর্তে প্রয়োজন। তাদের নিবন্ধন করতে, ব্যবহার FormattingConversionServiceFactoryBean , উভয় converters এবং formatters রেজিস্টার করতে পারেন যার পরিবর্তে ConversionServiceFactoryBean
  2. নতুন ফর্ম্যাটর স্টাফের বেশ কয়েকটি অতিরিক্ত সুবিধা রয়েছে:
    • ফর্ম্যাটার ইন্টারফেস তার মুদ্রণ (...) এবং পার্স (...) পদ্ধতিতে লোকেল অবজেক্ট সরবরাহ করে , তাই আপনার স্ট্রিং রূপান্তরটি লোকাল-সংবেদনশীল হতে পারে
    • প্রাক-নিবন্ধন formatters ছাড়াও, FormattingConversionServiceFactoryBean কুশলী প্রাক-নিবন্ধন দুয়েক দিয়ে আসে AnnotationFormatterFactory বস্তু, যে আপনার টীকা মাধ্যমে অতিরিক্ত ফর্ম্যাটিং পরামিতি উল্লেখ করার অনুমতি দেয়। উদাহরণস্বরূপ: @ রিকোয়েস্টপ্রাম@DateTimeFormat (প্যাটার্ন = "MM-DD-বছর")LOCALDATE baseDate ... এটা আপনার নিজের তৈরি করা খুব কঠিন নয় AnnotationFormatterFactory ক্লাস, স্প্রিং দেখি NumberFormatAnnotationFormatterFactory একটি সহজ উদাহরণস্বরূপ। আমি মনে করি এটি নিয়ামক-নির্দিষ্ট বিন্যাস / সম্পাদকদের প্রয়োজনীয়তা দূর করে। সমস্ত নিয়ামকের জন্য একটি রূপান্তর পরিষেবা ব্যবহার করুন এবং টীকাগুলির মাধ্যমে ফর্ম্যাটটি কাস্টমাইজ করুন।
  3. আমি সম্মত হই যে আপনার যদি এখনও কিছু নিয়ামক-নির্দিষ্ট স্ট্রিং রূপান্তর প্রয়োজন, সহজ উপায় এখনও কাস্টম সম্পত্তি সম্পাদক ব্যবহার করা। (আমি আমার @ ইনিটবাইন্ডার পদ্ধতিতে ' বাইন্ডার.সেট কনভার্সন সার্ভিস (...) ' কল করার চেষ্টা করেছি , তবে এটি ব্যর্থ হয়েছে, যেহেতু বাইন্ডার অবজেক্টটি ইতিমধ্যে সেট করা 'গ্লোবাল' রূপান্তর পরিষেবা নিয়ে আসে। বসন্ত 3)।

7

সহজতম (ধরে নিচ্ছেন যে আপনি অধ্যবসায় কাঠামো ব্যবহার করছেন), তবে সঠিক উপায়টি হ'ল জেনেরিক সত্তা রূপান্তরকারীটিকে ConditionalGenericConverterইন্টারফেসের মাধ্যমে প্রয়োগ করা যা তাদের মেটাডেটা ব্যবহার করে সত্তাগুলি রূপান্তর করবে।

উদাহরণস্বরূপ, আপনি যদি জেপিএ ব্যবহার করছেন তবে এই রূপান্তরকারীটি নির্দিষ্ট শ্রেণীর @Entityটিকা আছে কিনা তা দেখতে পারে এবং @Idতথ্য বের করার জন্য টীকাযুক্ত ক্ষেত্রটি ব্যবহার করে এবং অনুসন্ধানের জন্য আইডি হিসাবে সরবরাহিত স্ট্রিং মানটি স্বয়ংক্রিয়ভাবে প্রদর্শন সম্পাদন করতে পারে।

public interface ConditionalGenericConverter extends GenericConverter {
    boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}

ConditionalGenericConverter স্প্রিং রূপান্তর এপিআই এর একটি "চূড়ান্ত অস্ত্র", তবে একবার প্রয়োগ করা গেলে এটি বিকাশকারীদের সময় সাশ্রয় করে সত্তা রূপান্তরগুলির বেশিরভাগ প্রক্রিয়া করতে সক্ষম হবে - আপনি যখন কেবলমাত্র আপনার নিয়ামকের পরামিতি হিসাবে সত্তা শ্রেণি নির্দিষ্ট করেন এবং কখনই বাস্তবায়নের বিষয়ে চিন্তা করেন না তখনই এটি এক বিরাট স্বস্তি একটি নতুন রূপান্তরকারী (অবশ্যই কাস্টম এবং অ-সত্তা প্রকারের জন্য বাদে)।


কেবল সত্তা রূপান্তরকে মোকাবেলা করার জন্য দুর্দান্ত সমাধান, কৌশলটির জন্য ধন্যবাদ for আপনাকে আরও একটি ক্লাস লিখতে হবে বলে শুরুর দিকে সহজ নয়, তবে দীর্ঘমেয়াদে সহজ এবং সময়ের সাধ্য।
জেরোম ডালবার্ট

BTW যেমন একটি কনভার্টার কোনো ধরনের জন্য প্রয়োগ করা যেতে পারে যে কিছু জেনেরিক চুক্তি Adher - অন্য একটি উদাহরণ: যদি আপনার enums কিছু সাধারণ বিপরীত লুকআপ ইন্টারফেস বাস্তবায়ন - তারপর আপনি একটি জেনেরিক রূপান্তরকারী বাস্তবায়ন করতে সক্ষম হবে (এটা অনুরূপ হতে হবে stackoverflow.com / প্রশ্নগুলি / 5178622 /… )
বরিস ট্রুখভ

@ জেরোম ডালবার্ট হ্যাঁ কোনও ভারী ওজনের স্টাফ করা কোনও নবজাতকের পক্ষে কিছুটা কঠিন, তবে আপনার যদি বিকাশকারীদের একটি দল থাকে তবে এটি সহজ হবে) পিএস এবং যে কোনও উপায়ে বাইন্ডিংয়ের সময় একই সম্পত্তি সম্পাদকদের নিবন্ধ করা বিরক্তিকর হয়ে উঠবে)
বরিস ট্রুখভ

1

স্থিতিশীল অভ্যন্তর শ্রেণি হিসাবে দুটি রূপান্তরকারী প্রয়োগ করে দুটি পৃথক রূপান্তরকারী ক্লাস করার প্রয়োজনের চারপাশে আপনি বিভিন্ন ধরণের কাজ করতে পারেন।

public class FooConverter {
    public static class BarToBaz implements Converter<Bar, Baz> {
        @Override public Baz convert(Bar bar) { ... }
    }
    public static class BazToBar implements Converter<Baz, Bar> {
        @Override public Bar convert(Baz baz) { ... }
    }
}

আপনার তখনও উভয়কে পৃথকভাবে নিবন্ধভুক্ত করা দরকার, তবে আপনি যদি কোনও পরিবর্তন করেন তবে কমপক্ষে আপনাকে যে ফাইলগুলির সংশোধন করতে হবে তার সংখ্যা হ্রাস পাবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.