Rest or SOAP? Which one to use?

As a developer we might have worked on REST as well as SOAP based services. However when it comes to decide which one to use then many developers are not very clear with the answer. Let’s see in this article what are the differences in these two ways of creating web services. Before we dig-down into the differences here is a short history about REST and SOAP.

REST: REST(representational state transfer) was introduced and defined in 2000 by Roy Thomas Fielding in PhD dissertation “Architectural Styles and the Design of Network-based Software Architectures”. Rest facilitates philosophy of open web.

SOAP: SOAP(Simple Object Access Protocol) was introduced in 1998 by Dave Winer in collaboration with Microsoft. SOAP is mainly used to address the goals of the enterprise market.

Basic Concept

REST SOAP
Makes data available as a resources. E.g. AccountInformation, Invoice Makes application logic available as a servies. E.g. getAccountInformation, PayInvoice
It’s an architectural style. It’s a protocol.

Advantages

REST SOAP
It uses standard HTTP. Hence easy to implement. Works on top of any communication protocol
Returns data in many different formats (JSON,XML etc.) It can be fully described using WSDL
Better performance and scalability. Reads can be cached. Provides end-to-end reliability and successful/retry logic is built in
REST allows better support for browser clients due to its support for JSON. Security and authorization are part of protocol

Disadvantages

REST SOAP
Only works on top of HTTP protocol Hard to implement and not so popular among web and mobile developers
No built-in standards for security or reliability Permits XML data format only
No constraints on the payload SOAP defines standards to be strictly followed.
Requires more bandwidth and resource than REST.

When to use what

REST SOAP
When your bandwidth is very limited. When performing transactions that involves multiple calls.
When client and server operates on a web environment When you want to enforce a strict contract between client and server
Examples: Social Media Service, Web chat service Examples: Financial services, telecommunication services

 

In nutshell , identify your project need and goal you want to achieve before you pick any of the approaches.

Are you looking for fast android emulator?

After few years break back to mobile technologies again. Word of mobile development has changed a lot and at fast peace. I was feeling excited to work on Android again, however my excitement didn’t last long when I launched my application in emulator.

I was using default emulator provided by android SDK and to my goodness it was taking a long time.

5 min, 10 mins , 15 mins..Went for a coffee break …came back….but emulator was still loading.

Finally I decided to look on internet for a solution and I came across Genymotion emulator. Genymoyion is a commercial product from Genymobile which provides android emulator that is pretty fast and can be easily integrated with Eclipse and Android studio. Below are main feature

  •  Plugins for android studio and eclipse. Compatible with Android SDK tools
  •  High performance
  •  Easy integration with testing and continuous integration server.
  •  Powerful features: GPS, Battery, Screencast, Network quality and performance, Call interruption, SMS emulation etc.
  •  available for Windows, Mac and Linux
  •  Basic version for free with premium license which adds more features to the emulator

Let’s see how to use genymotion with android studio and emulator

Installing Genymotion on windows

  1. Got to genymotion site https://www.genymotion.com/#!/download and sign up
  2. There are two options to download one with virtual box and one without virtual box.For just emulator we will opt for option 2 i.e without virtual box. Go to link https://www.genymotion.com/#!/download/freemium/windows/withoutVirtualBox
  1. Now run the downloaded genymotion-x.x.x.exe and install the Genymotion on your PC.
  2. Then launch Genymotion and login with your Username and Password.

Instal1

5. Then select a device from the list and click next.

Instal2

6. It will create a new virtual device.

Integrating with android studio

  1. Go to File->Settings->Plugins
  2. Search for Genymotion

and1

4. If not displayed click on Browse link shown in above image.

5.It will display the plugin

and2

5. Click on Install plugin button.

6. Restart android studio once plugin is installed

7. When you click on device manager button

and3

For first time it will ask for path where Genymotion is installed

and4

8. Once this path is set you can launch Genymotion device manager displayed below.

and5

9. Using this device manager you can launch emulator

and6

Integrating with eclipse

  1. Select Help->Install New Software.
  2. Enter the URL http://plugins.genymotion.com/eclipse and press Enter.
  3. Genymotion Eclipse Tools will be shown, select it and click next.

ecl1

4.  Genymotion Eclipse Plug-in will be downloaded and installed.

5. Now restart Eclipse IDE the plug-in will be active.

ecl2

That’s it. You are ready to use genymotion now.

Spring Batch- Code example

In last article of Spring Batch we gone through concepts and interfaces provided by spring batch framework.

In this article let’s see how we can use those concepts to create a batch job.

For simplicity, below is a simple batch job we will be taking as an example.

  • Read from a csv file.
  • Process data – select only records where age > 30
  • Write to another csv file.
  1.  configuration file snippet for this job

<batch:job id=“reportJob”>

<batch:listeners>

<batch:listener ref=“customJobListener” />

</batch:listeners>

<batch:step id=“step1”>

<tasklet>

<chunk reader=“csvFileItemReader” writer=“cvsFileItemWriter” processor=“filterCSVProcessor”commit-interval=“1”>

<listeners>

<listener ref=“customStepListener” />

<listener ref=“customItemReaderListener” />

<listener ref=“customItemWriterListener” />

<listener ref=“customItemProcessListener” />

</listeners>

</chunk>

</tasklet>

</batch:step>

</batch:job>

In this configuration file you first define a job with job id. Then you define any listeners which pprovide call-backs at specific points in the lifecycle of a Job like before or after start of job.

Then you define a step which also has unique ID. Then you define the steps which are required for performing your job. These steps are defined in terms of item reader/processor/writers, and whole as a unit are defined with chunk element.

  • reader – The ItemReader that provides items for processing.
  • writer – The ItemWriter that processes the items provided by the ItemReader.
  • commit-interval – The number of items that will be processed before the transaction is committed.

Then you define listeners for step which are again call-backs at specific points in the lifecycle of a step like before or after start of step or before and after reading item etc.

The chunk element is defined within tasklet tag.

Below is a code snippet for item reader listener.

public class CustomItemReaderListener implements ItemReadListener<User> {

public void afterRead(User arg0) {

System.out.println(“CustomItemReaderListener : ” +”afterRead()”);

}

public void beforeRead() {

System.out.println(“CustomItemReaderListener : ” +”beforeRead()”);

}

public void onReadError(Exception arg0) {

System.out.println(“CustomItemReaderListener : ” +”onReadError()”);

}

}

Similarly you define other listeners for job, step, reader/writer/processor etc which are implementations of respective listeners interfaces provided by spring batch framework.

 

  1. Then we need to launch this job. Here is a code snippet.

String[] springConfig = {

“spring/batch/config/context.xml”,

“spring/batch/jobs/job-report.xml”

};

ApplicationContext context =

new ClassPathXmlApplicationContext(springConfig);

JobLauncher jobLauncher = (JobLauncher) context.getBean(“jobLauncher”);

Job job = (Job) context.getBean(“reportJob”);

try {

JobExecution execution = jobLauncher.run(job, new JobParameters());

System.out.println(“Job Exit Status : ” + execution.getStatus());

} catch (Exception e) {

e.printStackTrace();

}

System.out.println(“Done with batch”);

First you create a JobLauncher instance from “jobLauncher” bean defined in context.xml

Then you create a Job instance from “reportJob” which is defined in job configuration file.

When you run your Job instance with help of JobLauncher you will get a JobExecution instance which provides you the status whether your job executed successfully or not.

 

  1. Now let’s see how reader and writers are configured in our job-report.xml

<bean id=”csvFileItemReader” class=”org.springframework.batch.item.file.FlatFileItemReader”>

<!– Read a csv file –>

<property name=”resource” value=”file:csv/input/read.csv” />

<property name=”lineMapper”>

<bean class=”org.springframework.batch.item.file.mapping.DefaultLineMapper”>

<!– split it –>

<property name=”lineTokenizer”>

<bean                                                                                           class=”org.springframework.batch.item.file.transform.DelimitedLineTokenizer”>

<property name=”names” value=”name,age,phone” />

</bean>

</property>

<property name=”fieldSetMapper”>

<!– map to an object –>

<bean                                                                                              class=”org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper”>

<property name=”prototypeBeanName” value=”user” />

</bean>

</property>

</bean>

</property>

</bean>

<bean id=”cvsFileItemWriter” class=”org.springframework.batch.item.file.FlatFileItemWriter”>

<!– write to this csv file –>

<property name=”resource” value=”file:csv/output/write.csv” />

<property name=”shouldDeleteIfExists” value=”true” />

<property name=”lineAggregator”>

<bean                                                               class=”org.springframework.batch.item.file.transform.DelimitedLineAggregator”>

<property name=”delimiter” value=”,” />

<property name=”fieldExtractor”>

<bean                                     class=”org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor”>

<property name=”names” value=”name,age,phone” />

</bean>

</property>

</bean>

</property>

</bean>

</beans>

You first define beans which are responsible for reading and writing. In this example we are using readers and writers provided by spring batch framework i.e. FlatFileItemReader and FlatFileItemWriter as we are using comma separated records. You can have your custom classes as well.

Then you define a csv file to be read or written using property resource.

  1. Reading

We have defined a line maper . Line mappers are used for tokenizing lines into FieldSet in our case domain class User , followed by mapping to items.

  1. Writing:

We have defined a line aggregator that converts an object into a delimited list of strings. The default delimiter is a comma.

Then we need to extract our fields from our domain object user. For this we use field extractor to which given an array of property names, it will reflectively call getters on the item and return an array of all the values.

  1. Processing:

We have our custom file processor as we want to filter out records where age > 30.

For this we defined a bean

<bean id=“filterCSVProcessor” class=“com.springbatch.processor.FilterCSVProcessor” />

And here is implementation

public class FilterCSVProcessor implements ItemProcessor<User, User>{

public User process(User user) throws Exception {

if( user.getAge() > 30)

return user;

else

return null;

}

}

That’s all. Complete source code can be found here.

 

 

 

 

Spring Batch – Concepts and interfaces

Recently I came across a very interesting incident which was related to spring batch, where a write skip count was not getting updated properly. I never worked on spring batch and almost knew nothing about it before working on this incident.

So after understanding what the incident is about, I started reading how spring batch works.

Let’s see what spring batch is and how it works.

In general terms “BATCH” is the execution of a series of programs on a computer without manual intervention.

Where batch processing can be used:

  • Data Export
  • Invoice generation
  • Bulk database updates
  • Automated transaction processing
  • Processing digital images

What is Spring Batch: Spring Batch is an open source framework for batch processing. It is a lightweight framework based on top of spring framework.

Features:

  • Transaction management
  • Chunk based processing
  • Start/Stop/Restart
  • Retry/Skip

Let’s first understand the terms which are core to Spring Batch framework.

Batch: execution of a series of jobs

Job: A sequence of one or more steps and associated configuration that belong to the batch job. A job is indented to be executed without interruption.

JobInstance : A uniquely identifiable job run.

JobExecution : A single attempt to run a job. A JobInstance will be considered complete only when JobExecution completes successfully.

Step : A Step is a part of a Job and contains all the necessary information to execute the batch processing actions that are expected to be done at that phase of the job. A Step is a single state within the flow of a job.

StepExecution: An attempt to execute a step. Contains information about commit count and access to the Execution Context.

Job Repositories: Job repositories provides CRUD persistence operations for all job related metadata like the results obtained, their instances, the parameters used for the Jobs executed and the context where the processing runs.

JobLauncher: Responsible for launching jobs with their job parameters.

Batch application can be divided in three main parts:

  • Reading the data (from a database, file system, etc.)
  • Processing the data (filtering, grouping, calculating, validating…)
  • Writing the data (to a database, reporting, distributing…)

There are various reader and writer interfaces provided by spring batch framework.

Key Interfaces are:

  • ItemReader :
  • ItemWriter
  • ItemProcessor

ItermReader : Readers are abstractions responsible of the data retrieval. Here is a list of readers

  • AmqpItemReader
  • AggregateItemReader
  • FlatFileItemReader
  • HibernateCursorItemReader
  • HibernatePagingItemReader
  • IbatisPagingItemReader
  • ItemReaderAdapter
  • JdbcCursorItemReader
  • JdbcPagingItemReader
  • JmsItemReader
  • JpaPagingItemReader
  • ListItemReader
  • MongoItemReader
  • Neo4jItemReader
  • RepositoryItemReader
  • StoredProcedureItemReader
  • StaxEventItemReader

ItemWriter: Writers are abstractions responsible of writing the data to the desired output database or system. Here is a list of writers

  • AbstractItemStreamItemWriter
  • AmqpItemWriter
  • CompositeItemWriter
  • FlatFileItemWriter
  • GemfireItemWriter
  • HibernateItemWriter
  • IbatisBatchItemWriter
  • ItemWriterAdapter
  • JdbcBatchItemWriter
  • JmsItemWriter
  • JpaItemWriter
  • MimeMessageItemWriter
  • MongoItemWriter
  • Neo4jItemWriter
  • StaxEventItemWriter
  • RepositoryItemWriter

ItemProcessor: Processors are in responsible for modifying the data records converting it from the input format to the output desired one. These are optional. Here is a list

  • ValidatingItemProcessor
  • PassThroughItemProcessor
  • ScriptItemProcessor

And many other.

To put it all together this is how it looks

SpringBatch

 

Ok. So now how these batch jobs are processed. There are two ways.

1.Chunk oriented processing:

Chunk oriented processing refers to reading the data one at a time, and creating ‘chunks’ that will be written out, within a transaction boundary. One item is read in from an ItemReader, handed to an ItemProcessor, and aggregated. Once the number of items read equals the commit interval, the entire chunk is written out via the ItemWriter, and then the transaction is committed.

chunk-oriented-processing

Configuring step for chunk oriented processing:

<job id="sampleJob" job-repository="jobRepository">
    <step id="step1">
        <tasklet transaction-manager="transactionManager">
            <chunk reader="itemReader" writer="itemWriter" commit-interval="10"/>
        </tasklet>
    </step>
</job>

 

 

2.Tasklet oriented processing: Sometimes step consists of simple operations consisting of a single task like simple stored procedure call or deleting a file etc.

For such case Tasklet interface is provided.

The Tasklet is a simple interface that has one method, execute, which will be a called repeatedly by the TaskletStep until it either returns RepeatStatus.FINISHED or throws an exception to signal a failure.

Configuration of step as a tasklet:

<step id=”step1″>

<tasklet ref=”myTasklet”/>

</step>       

 

In next article we will see how these concepts are used /applied to create a batch job application.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ajax in Apache wicket

First a bit about JavaScript:JavaScript, aka Mocha, aka LiveScript and many other names, is a client-side (i.e. the browser) scripting language. That means it takes out burden of processing data from your server making it more responsive.

As there are advantages of using JavaScript as speed, simplicity etc. there are downsides as well like it is frequently turned off in browsers because of security concerns, it can be easily exploited etc.

Ajax(Asynchronous JavaScript+XML) is based on JavaScript with some other technologies like HTML and CSS and is used to dynamically update parts of the UI without having to reload the page.

While Ajax can be used with many java frameworks like Spring MVC,Struts , JFS etc, it is very easy to use Ajax with wicket. You don’t even need to write a single line of JavaScript as Wicket has bunch of Ajax enabled components.

Here are advantages of Ajax in wicket :

  1. As a java developer you can focus on pure java without need to learn JavaScript.
  2. Many built-in AJAX components, also Ajax behavior encapsulated in wickets reusable components.
  3. It is easy to replace components on the fly.
  4. Faster, more responsive user interfaces, as Ajax requests do not completely refresh whole page.
  5. It has excellent debugging utility for debugging Ajax calls

 

So let’s see how easy it is to use Ajax with wicket than traditional approach.

 

Let’s see how to submit a form without writing a single line of JavaScript.

 

You just need to add a button that can be used to submit the form via Ajax
form.add(new AjaxButton(“ajax-button”, form)
{
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form)
{
// repaint the feedback panel so that it is hidden
target.add(feedback);
}

@Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
// repaint the feedback panel so errors are shown
target.add(feedback);
}
});

And that’s all. No JavaScript in HTML i.e.markup file of your wicket application!!!

Note: above piece of code is from Wicket Library examples and complete example can be found here.

 

 

 

Are you disciplined coder? My checklist before code check-in

Now a days in agile development we follow many practices like continuous integration, test driven development and track progress using various other tools and metrics. But still we might not deliver quality software.

In my opinion , code quality and discipline goes hand-in-hand. Unless you are a disciplined coder , its hard to achieve code quality.

Here is my check-list before checking in code.

1. I have followed coding guidelines and standards while writing my code.

2. I have my unit tests(using JUnit, Mockito, TestNG etc) ready and code is properly tested.

3. I have done static code analysis. You can use various tools like Sonar, FindBugs, Checkstyle etc.

4. I have done peer review. Well one can ask if step 3 is already done then why peer review? There are certain defects or improvements in code that can be identified by only skilled developer. Also your peer can review other things like requirements , design documents , test cases and other deliverables are in place.

5. once step 3 and 4 are done then again go for step 2 and 3 to check if any new findings are introduced by code review implementation and I have covered unit tests for adapting those changes.

6. I have properly commented code. Have meaningful description for classes, methods, variables etc.

So all is well now and I am ready to check-in my code. Hey wait , before check in make sure you have tagged this with proper task-id and provided meaningful description. It is still not over, wait until your build is green :), so that others work is not affected because of you.

Happy coding!!!  🙂

 

 

Custom Console in Eclipse RCP Application

I was working on RCP application and there was a requirement to customize the console view by removing PIN Console, Open Console toolbar buttons.

Let’s learn today how we can do so.

First create a RCP application using Mail Template.

Then create an extension for “org.eclipse.ui.console.consolePageParticipants”.

extension

PageParticipant

This class implements IConsolePageParticipant and override method init()

Now get reference to toolbar manager in console view and remove unwanted buttons.

IPageSite pageSite = page.getSite();

IWorkbenchPage workbenchPage = pageSite.getPage();

IViewPart viewPart =

workbenchPage.findView( IConsoleConstants.ID_CONSOLE_VIEW );

IViewSite viewSite = viewPart.getViewSite();

IActionBars actionBars = viewSite.getActionBars();

IToolBarManager toolBarManager = actionBars.getToolBarManager();

IContributionItem[] contributionItems = toolBarManager.getItems();

contributionItems = toolBarManager.getItems();

toolBarManager.remove( contributionItems[5] );

toolBarManager.remove( contributionItems[6] );

toolBarManager.remove( contributionItems[7] );

 

This will remove Pin Console, Display Selected Console and Open Console buttons from the toolbar in console view.

There could be better way of removing tool bar buttons from console view but this is what I know so far.

Complete source code for this example can be found here.

Internationalization with Wicket

In last article we discussed  how to localize mark-up files in wicket. It would be very annoying having 14 different html files if we have 14 different languages that we should support for that particular page/component.

In this article we are going to learn how to use resource bundles instead of localizing mark-up files. Imagine your application contains so many texts that need i18n. In this situation it is very difficult to put a wicket:id on all of these, and then add a Label to each.

Wicket provides a simple way to provide i18n support for your applications.

You can use the wicket:message element in the HTML file directly

<wicket:message key=”staticMessage” >Message</wicket:message>

The property files are

DisplayPage.properties:

staticMessage= Message

For Germany

DisplayPage_de.properties:

staticMessage= Nachricht

For Netherland

DisplayPage_nl.properties:

staticMessage= Bericht

The key “staticMessage” is used to lookup the message in the property files. The default text Message is used when the message could not be found. Wicket framework provides getString(String key) method in Component class which search for a property by given key in resource bundles.

Localized pages and panel can have their own bundle files having as base name the class name of the related component and placed in the same package.

So in our example we have DisplayPage.java class. We have created our resource bundles based on name of this class for. E.g DisplayPage_de.properties. Note all these resource files are located in same place where out DisplayPage.java class resides.

Alternatively if you want to use text from properties file in wicket components like labels etc. simply use getString(“key”) method provided by Component class in wicket.

How lookup algorithm works:

Wicket will search all resource files with the names equal to the components in your component hierarchy, starting from application level at top to component defaults as a last place to look.

So when Wickets wants to look up a message used in MyPanel, where MyPanel is contained within MyPage, and the application is called MyApplication,

Wicket will look in:

  1. MyApplication_locale.properties, …, and then MyApplication.properties (..)
  2. MyPage_locale.properties, …, and then MyPage.properties
  3. MyPanel_locale.properties, …, and then MyPanel.properties

And what if it has same key in all these hierarchy properties files?

The lookup algorithm gives priority to the bundles of the containers (parents) of the component that is requesting a localized resource. The more a container is higher in the hierarchy, the bigger is its priority over the other components. In other words properties inside the resource bundle of a page will have the priority over the properties with the same key defined in the bundles of children components.

So for example in our sample code if we have HomePage which is container for DisplayPage, have a property with same key i.e. staticMessage with some other value in its resource bundle then it will be displayed instead of property in DisplayPage resource bundles. HomePage.properties staticMessage= Title Message.

So here text “Title Message” will be displayed instead of DisplayPage.

Also note that for DisplayPage component DisplayPage.properties is a default resource bundle.

So for e.g. your locale is set to “de” and there is no resource bundle for that locale (DisplayPage_de.properties is missing) then lookup algorithm will fall back to default resource bundle in this case DisplayPage.properties

To display languages like Chinese, Japanese etc, which need UTF-8 encoding you need to just append resource bundles with .utf8.properties extension.

Finally how to change locale?

To manually switch the locale in wicket:

Session.get().setLocale(new Locale(Locale.GERMAN));

Isn’t it pretty easy to i18n wicket applications. 🙂

A complete source code for sample example could be found here.

Localizing markup files in apache wicket

In this article we are going to see how we can localize markup files in wicket with an example.

We will be using DropDownChoice from previous article “Customizing display of choice in apache wicket”.

We need to create different markup files for different locale settings. All files have following format for naming.

YourFileName_<language code>[ <COUNTRY_CODE> ].html

Note <COUNTRY_CODE> could be optional.

So here is an example for markup file for displaying content in Chinese language.

LocaleSpecificPanel_zh_CN.html

<html xmlns:wicket=http://wicket.apache.org&#8221;S>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”/>

<title>TestForm</title>

<link rel=“stylesheet” type=“text/css” href=“style.css”/>

</head>

<body>

<wicket:panel>

歡迎來到中國

</wicket:panel>

</body>

</html>

In similar way we have to create markup files containing text in that particular language.

When the current locale is set to country China(language code zh_CN), markup file LocaleSpecificPanel_zh_CN.html will be used in place of the default one.

Complete source code for above example could be found here.

In next article we will see how to internationalization works in wicket. This time we will create separate resource bundles (.properties) files instead of markup files.

Customizing display of choice in apache wicket.

Many times we come across a requirement where we need to bind a key-value pair to a Drop Down component. i. e. we need to customize dropdown choice to show some display values and upon selection of that value we need to use key (some other value) for some business logic.

Let’s see how we can bind a key-value structure i.e. HashMap to a DropDownChoice component in wicket.

In this example we are going to bind a key value pair for Locale-ID and Country with DropDownChoice. i.e. we are going to display different countries in drop down and based on selection of country we will set Locale.

So first we will create a HashMap for holding key-value pairs of locale-id and country.

Map<String, String> localeMapTemp = new HashMap<String, String>();

localeMapTemp.put(“en_US”, “United States”);

localeMapTemp.put(“de_DE”, “Germany”);

localeMapTemp.put(“nl_NL”, “Netherlands”);

localeMapTemp.put(“zh_CN”, “China”);

Now we will create a helper class which will hold the above key-value pairs for the DropDownChoice.

public class SelectOption implements Serializable {

/**

*

*/

private static final long serialVersionUID = 1L;

private String key = null;

private String value = null;

public SelectOption(String key, String value) {

super();

this.key = key;

this.value = value;

}

public String getKey() {

return key;

}

public void setKey(String key) {

this.key = key;

}

public String getValue() {

return value;

}

public void setValue(String value) {

this.value = value;

}

}

We need to create a DropDownChoice object.

DropDownChoice<SelectOption> localeChoice = new DropDownChoice<SelectOption>(“dropDwonChoice”,

new PropertyModel<SelectOption>(localeModel, “selectedLocale”),

getLocaleList(),

new ChoiceRenderer<SelectOption>(“value”, “key”)){

/**

*

*/

private static final long serialVersionUID = 1L;

@Override

protected boolean wantOnSelectionChangedNotifications() {

return true;

}

@Override

protected void onSelectionChanged(Object newSelection) {

selectedLocale = ((SelectOption)newSelection).getKey();

super.onSelectionChanged(newSelection);

}

};

Now let’s understand all attributes of DropDownChoice constructor in above code snippet.

  1. First argument is id of choice element in html markup.

<select wicket:id=“dropDwonChoice”>

<option value=“en”>English</option>

<option value=“de”>German</option>

</select>

  1. Second argument i.e. new PropertyModel<Object>(localeModel, “selectedLocale”), in above code represents model object SelectOption helper class. Model class for your page in which drop down is added must use SelectOption.
  1. Third argument returned by getLocaleList() a list of SelectOption objects.

Note that the type of object returned by the model in second argument and the type of objects in the list in third argument must be the same, in this case SelectOption.

  1. And last argument is The ChoiceRenderer will use the value of the ‘key’ property of SelectOption object in the ‘value’ attribute in the rendered HTML (e. g. ‘key’ property value will be used as the option id). The ‘value’ property will be used as a display value for the given option.

If you want to customize further the values rendered in option then use your own customized choice renderer.

For e.g. if you want to use something like value-key (“German-de”) as display value in above example then you can write your own ChoiceRenderer.

class CustomChoiceRenderer implements IChoiceRenderer<SelectOption> {

/**

*

*/

private static final long serialVersionUID = 1L;

@Override

public Object getDisplayValue(SelectOption object) {

return object.getValue()+”-“+object.getKey();

}

@Override

public String getIdValue(SelectOption object, int index) {

return object.getKey();

}

}

Complete source code for above example can be found here.