Infinite Recursion with Jackson JSON ResponseBody and Spring-MVC (non-bidireccional) - java

I'm testing a new rest service that I've implemented. This service returns a Json through #ResponseBody. In each controller, I return the same structure:
-code
-message
-list of objects
The object that i return is a message with a list which extends to its parent class getting the code and message. These are my classes:
private class SimpleMessage{
ResponseCode code;
String message;
public ResponseCode getCode() {
return code;
}
public void setCode(ResponseCode code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setCodeAndMessage(ResponseCode code, String message){
this.code = code;
this.message = message;
}
}
private class MessageResponse<T> extends SimpleMessage{
List<T> list;
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
If I try to return the SimpleMessage, it works fine. But the problem is relative to the MessageResponse class. If I return this class with an instance of the class User for example in the list, it runs in an infinite loop until I stop the tomcat server.
This is my controller
public #ResponseBody SimpleMessage isUserSuscribed(#RequestBody String data){
MessageResponse<User> msg = new MessageResponse<User>();
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
JsonNode node;
try {
node = mapper.readTree(data);
BasicUser manager = mapper.convertValue(node.get("manager"), BasicUser.class);
User user = userService.getUserByOpenid(mapper.convertValue(node.get("openid"), String.class));
msg.setList(Lists.newArrayList(user));
} catch (JsonProcessingException e) {
log.debug(e.toString());
msg.setCodeAndMessage(ResponseCode.error, "Malformed JSON \n" + e.getMessage());
} catch (IOException e1) {
log.debug(e1.toString());
msg.setCodeAndMessage(ResponseCode.error, "Application error");
}
msg.setCodeAndMessage(ResponseCode.success, "success");
return msg;
}
The User class:
public class User extends AbstractPropertySearcher{
private String username;
private String password;
private String email;
private Boolean active;
private String metadata;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public String getMetadata() {
return getMeta().getMetadata();
}
public void setMetadata(String metadata) {
this.metadata = metadata;
}
public enum KnownUsers{
TEST, SYSTEM
}
public User() {
this.roles = new HashSet<String>();
this.profiles = new HashSet<String>();
this.geoareas = new HashSet<String>();
this.properties = new HashSet<Property>();
}
public User(String username) {
this.username = username;
this.roles = new HashSet<String>();
this.profiles = new HashSet<String>();
this.geoareas = new HashSet<String>();
this.properties = new HashSet<Property>();
}
public User(User o) {
try{
PropertyUtils.copyProperties(this, o);
}
catch (Exception e) {
e.printStackTrace();
}
}
private Set<String> roles;
private Set<String> profiles;
private Set<String> geoareas;
public Set<String> getRoles() {
return roles;
}
public void setRoles(Set<String> roles) {
this.roles = roles;
}
public Set<String> getProfiles() {
return profiles;
}
public void setProfiles(Set<String> profiles) {
this.profiles = profiles;
}
public Set<String> getGeoareas() {
return geoareas;
}
public void setGeoareas(Set<String> geoareas) {
this.geoareas = geoareas;
}
private Set<Property> properties;
private Map<String,Property> mappedProperties;
public Map<String,Property> getMappedProperties(){
if(mappedProperties==null){
mappedProperties = new HashMap<String,Property>();
for(Property prop : getProperties()){
mappedProperties.put(prop.getProperty(),prop);
}
}
return mappedProperties;
}
public Property getPropertyByName(KnownProperty knownProperty) throws PropertyNotFoundException{
return getPropertyByName(knownProperty.getPropertyName());
}
public void setProperty(Property property){
setProperty(properties, property);
}
public boolean hasRole(Role.KnownRoles role){
return roles.contains(role.name());
}
public Set<Property> getProperties() {
return properties;
}
public void setProperties(Set<Property> properties) {
this.properties = properties;
}
public String toString(){
return getUsername();
}
public int hashCode(){
return toString().hashCode();
}
public boolean equals(Object o){
if(o instanceof User){
return getUsername().equals(((User) o).getUsername());
}
return false;
}
public Property getBannerProperty() throws PropertyNotFoundException{
return AbstractPropertySearcher.getPropertyByName(getProperties(), KnownProperty.BANNER.getPropertyName());
}
private Metadata meta;
public Metadata getMeta(){
if(meta == null){
meta = new Metadata(metadata);
}
return meta;
}
public enum KnownMetaProperty{
REGISTRATION_DATE, LAST_ACCESS_DATE
}
public String getRegistrationDate(){
return getMeta().getVariable(KnownMetaProperty.REGISTRATION_DATE.name());
}
public String getLastAccessDate(){
return getMeta().getVariable(KnownMetaProperty.LAST_ACCESS_DATE.name());
}
}
This is the error in the log:
org.apache.jasper.JasperException: javax.servlet.ServletException: java.lang.StackOverflowError
Could anybody help me with this issue?
Thank you

Related

Mapping POJO with Snakeyaml with underscore in the name

I have the following configuration file where I am trying to map this yaml file into Java POJO Classes with Snakeyaml library.
consumers:
- acls:
- group: GRP-NAME-1
tags:
- CON-NAME
- group: GRP-NAME-2
tags:
- CON-NAME-TAG
oauth2_credentials:
- client_id: CRD-NAME
client_secret: xxxx
name: CRD-NAME
redirect_uris:
- http://xyz
tags:
- CON-NAME-TAG
username: CON-NAME
tags:
- CON-NAME-TAG
RootConfig.java
public class RootConfig {
private List<Consumer> consumers;
public List<Consumer> getConsumers() {
return consumers;
}
public void setConsumers(List<Consumer> consumers) {
this.consumers = consumers;
}
}
Consumer.java:
public class Consumer {
private List<Acl> acls;
private List<Oauth2Credential> oauth2Credentials;
private String username;
private List<String> tags;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<Acl> getAcls() {
return acls;
}
public void setAcls(List<Acl> acls) {
this.acls = acls;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public List<Oauth2Credential> getOauth2Credentials() {
return oauth2Credentials;
}
public void setOauth2Credentials(List<Oauth2Credential> oauth2Credentials) {
this.oauth2Credentials = oauth2Credentials;
}
}
Oauth2Credential.java:
public class Oauth2Credential {
private String clientId;
private String clientSecret;
private String name;
private List<String> redirectUris;
private List<String> tags;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getRedirectUris() {
return redirectUris;
}
public void setRedirectUris(List<String> redirectUris) {
this.redirectUris = redirectUris;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
}
Acl.java:
public class Acl {
private String group;
private List<String> tags;
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
}
ConfigLoader.java:
public class ConfigLoader {
public RootConfig load(String file) {
Yaml yaml = new Yaml(new Constructor(RootConfig.class));
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream(file);
RootConfig rootConfig = yaml.load(inputStream);
System.out.println(rootConfig);
return rootConfig;
}
}
Config loader is giving me following error:
Caused by: Cannot create property=oauth2_credentials for JavaBean=uk.gov.hmrc.deck.config.tool.modal.Consumer#1554909b
in 'reader', line 9, column 5:
- oauth2_credentials:
^
Unable to find property 'oauth2_credentials' on class: uk.gov.hmrc.deck.config.tool.modal.Consumer
in 'reader', line 10, column 7:
- client_id: CRD-MDTP-BREATHINGS ...
^
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:291)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:172)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:230)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:220)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructSequenceStep2(BaseConstructor.java:391)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructSequence(BaseConstructor.java:375)
at org.yaml.snakeyaml.constructor.Constructor$ConstructSequence.construct(Constructor.java:543)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:230)
at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:220)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.newInstance(Constructor.java:306)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:268)
... 10 more
Caused by: org.yaml.snakeyaml.error.YAMLException: Unable to find property 'oauth2_credentials' on class: uk.gov.hmrc.deck.config.tool.modal.Consumer
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:158)
at org.yaml.snakeyaml.introspector.PropertyUtils.getProperty(PropertyUtils.java:148)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.getProperty(Constructor.java:310)
at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:231)
... 20 more
If I remove oauth2_credentials element, it seems to be working fine. I believe the underscore in the name is causing this issue.
Any idea how to fix this?
You will need to use #YamlProperty(key = "oauth2_credentials") as follows:
public class Consumer {
private List<Acl> acls;
#YamlProperty(key = "oauth2_credentials")
private List<Oauth2Credential> oauth2Credentials;
private String username;
private List<String> tags;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<Acl> getAcls() {
return acls;
}
public void setAcls(List<Acl> acls) {
this.acls = acls;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public List<Oauth2Credential> getOauth2Credentials() {
return oauth2Credentials;
}
public void setOauth2Credentials(List<Oauth2Credential> oauth2Credentials) {
this.oauth2Credentials = oauth2Credentials;
}
}
Additionally, you must use AnnotationAwareConstructor when parsing:
public class ConfigLoader {
public RootConfig load(String file) {
Yaml yaml = new Yaml(new AnnotationAwareConstructor(RootConfig.class));
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream(file);
RootConfig rootConfig = yaml.load(inputStream);
System.out.println(rootConfig);
return rootConfig;
}
}

I want to add a bearer token to my retrofit post request

I have an app that is to register people into a platform but I get a response of Unauthenticated each time I submit the form data. The form is submitted using an API which requires a bearer token for each post request with the aid of retrofit. I have been out of touch with Java.
Note: its just a plain form. No authentication has been implemented in the app.
My ApiClient.java class
public class ApiClient {
private static Retrofit getRetrofit(){
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("xxxxxxxxxxxxx")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
return retrofit;
}
public static UserService getUserService(){
UserService userService = getRetrofit().create(UserService.class);
return userService;
}
}
My UserService.java class
public interface UserService {
#POST("algonapi/api/enroll_vehicle")
Call<UserResponse> saveUser(#Body UserRequest userRequest);
}
My saveUser Method
public void saveUser(UserRequest userRequest){
Call<UserResponse> userResponseCall = ApiClient.getUserService().saveUser(userRequest);
userResponseCall.enqueue(new Callback<UserResponse>() {
#Override
public void onResponse(Call<UserResponse> call, Response<UserResponse> response) {
if (response.isSuccessful()){
Toast.makeText(MainActivity.this, "Registration Successfull! Click on Reset Form to Start a New Enumeration...", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(MainActivity.this, "Registration Failed!", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call<UserResponse> call, Throwable t) {
Toast.makeText(MainActivity.this, "Registration Failed!" +t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
My UserRequest
package com.example.xxxxx;
public class UserRequest {
private String FullName;
private String StickerNumber;
private String Address;
private String Email;
private String Phone;
private String Nationality;
private String State;
private String LGA;
private String RC;
private String DriversLicenseNo;
private String LicenseIssued;
private String LicenseExpiry;
private String VehicleType;
private String VehicleLicense;
private String VehicleTyres;
private String LGAofOperation;
private String NOKFullName;
private String NOKAddress;
private String NOKPhone;
private String NOKEmail;
private String NOKNationality;
private String NOKState;
public String getFullName() {
return FullName;
}
public void setFullName(String fullName) {
FullName = fullName;
}
public String getStickerNumber() {
return StickerNumber;
}
public void setStickerNumber(String stickerNumber) {
StickerNumber = stickerNumber;
}
public String getAddress() {
return Address;
}
public void setAddress(String address) {
Address = address;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getPhone() {
return Phone;
}
public void setPhone(String phone) {
Phone = phone;
}
public String getNationality() {
return Nationality;
}
public void setNationality(String nationality) {
Nationality = nationality;
}
public String getState() {
return State;
}
public void setState(String state) {
State = state;
}
public String getLGA() {
return LGA;
}
public void setLGA(String LGA) {
this.LGA = LGA;
}
public String getRC() {
return RC;
}
public void setRC(String RC) {
this.RC = RC;
}
public String getDriversLicenseNo() {
return DriversLicenseNo;
}
public void setDriversLicenseNo(String driversLicenseNo) {
DriversLicenseNo = driversLicenseNo;
}
public String getLicenseIssued() {
return LicenseIssued;
}
public void setLicenseIssued(String licenseIssued) {
LicenseIssued = licenseIssued;
}
public String getLicenseExpiry() {
return LicenseExpiry;
}
public void setLicenseExpiry(String licenseExpiry) {
LicenseExpiry = licenseExpiry;
}
public String getVehicleType() {
return VehicleType;
}
public void setVehicleType(String vehicleType) {
VehicleType = vehicleType;
}
public String getVehicleLicense() {
return VehicleLicense;
}
public void setVehicleLicense(String vehicleLicense) {
VehicleLicense = vehicleLicense;
}
public String getVehicleTyres() {
return VehicleTyres;
}
public void setVehicleTyres(String vehicleTyres) {
VehicleTyres = vehicleTyres;
}
public String getLGAofOperation() {
return LGAofOperation;
}
public void setLGAofOperation(String LGAofOperation) {
this.LGAofOperation = LGAofOperation;
}
public String getNOKFullName() {
return NOKFullName;
}
public void setNOKFullName(String NOKFullName) {
this.NOKFullName = NOKFullName;
}
public String getNOKAddress() {
return NOKAddress;
}
public void setNOKAddress(String NOKAddress) {
this.NOKAddress = NOKAddress;
}
public String getNOKPhone() {
return NOKPhone;
}
public void setNOKPhone(String NOKPhone) {
this.NOKPhone = NOKPhone;
}
public String getNOKEmail() {
return NOKEmail;
}
public void setNOKEmail(String NOKEmail) {
this.NOKEmail = NOKEmail;
}
public String getNOKNationality() {
return NOKNationality;
}
public void setNOKNationality(String NOKNationality) {
this.NOKNationality = NOKNationality;
}
public String getNOKState() {
return NOKState;
}
public void setNOKState(String NOKState) {
this.NOKState = NOKState;
}
}
Create the OkHttpClient like this
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#NotNull
#Override
public Response intercept(#NotNull Chain chain) throws IOException {
Request request=chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + token)
.build();
return chain.proceed(request);
}
}).build();
If you most of your https requests need authentication then the first answer is perfect but if some of your requests need then you can pass the header to each methods.
public interface UserService {
#POST("algonapi/api/enroll_vehicle")
Call<UserResponse> saveUser(
#Header("Authorization") String token,
#Body UserRequest userRequest
);
}
While calling the method simply pass your token along with userRequest.

JsonMappingException: Cannot find a deserialzer for non-concrete Map type

I am new to java!
I am trying to read objects of type Admin, containing 3 strings, from a JSON file and store them in a List. I am getting "com.fasterxml.jackson.databind.JsonMappingException: Cannot find a deserializer for non-concrete Map type" but it seems I cannot find a solution.
What is a solution for my code so that I can load the list from the file?
Code snippet :
private static List<Admin> admins=new ArrayList<Admin>();
public static void loadAdminsFromFile() { /*LOAD THE LIST WITH JSON(ADMIN) OBJECTS*/
try {
ObjectMapper mapper = new ObjectMapper();
InputStream inputStream = new FileInputStream(new File("*path to file*"));
TypeReference<List<Admin>> typeReference = new TypeReference<List<Admin>>() {};
admins = mapper.readValue(inputStream, typeReference);
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JsonParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Admin class :
package model;
import javafx.scene.control.TextField;
public class Admin {
private String username;
private String ID;
private String password;
public Admin() {}
public Admin(String username, String ID, String password) {
this.username=username;
this.ID=ID;
this.password=password;
}
public String getUsername() {
return this.username;
}
public void setUsername(TextField username) {
this.username = username.getText();
}
public String getID() {
return this.ID;
}
public void setID(TextField ID) {
this.ID = ID.getText();
}
public String getPassword() {
return this.password;
}
public void setPassword(TextField password) {
this.password = password.getText();
}
#Override
public boolean equals(Object o) {
if(this==o) return true;
if(o==null || getClass()!=o.getClass()) return false;
Admin admin=(Admin) o;
if(!username.equals(admin.username)) return false;
if(!ID.equals(admin.ID)) return false;
if(!password.equals(admin.password)) return false;
return true;
}
#Override
public int hashCode (){
int result=username.hashCode();
result=31*result+ID.hashCode();
result=31*result+password.hashCode();
return result;
}
#Override
public String toString() {
return "Admin -> " + username + ID + password;
}
}
Try to override the setters method to accept String values:
....
public void setUsername(String username) {
this.username = username;
}
....

JsonMappingException: N/A when trying to deserialize JSON file

I have a User class and a Json file containing an array of Users. When trying to deserialize those users and get a List I'm getting a JsonMappingException, I don't understand what's wrong.
This is my User class:
public class User {
private StringProperty username;
private StringProperty password;
private StringProperty name;
private StringProperty surname;
private StringProperty email;
private StringProperty company;
private StringProperty phone;
private BooleanProperty canMonitorize;
private BooleanProperty canCreateProject;
private BooleanProperty canOpenProject;
private BooleanProperty admin;
public User() {}
public User(String user, String pass, String name, String surname, String email, String company, String phone,
boolean monitorize, boolean createP, boolean openP, boolean admin) {
this.username = new SimpleStringProperty(user);
this.password = new SimpleStringProperty(pass);
this.name = new SimpleStringProperty(name);
this.surname = new SimpleStringProperty(surname);
this.email = new SimpleStringProperty(email);
this.company = new SimpleStringProperty(company);
this.phone = new SimpleStringProperty(phone);
this.canMonitorize = new SimpleBooleanProperty(monitorize);
this.canCreateProject = new SimpleBooleanProperty(createP);
this.canOpenProject = new SimpleBooleanProperty(openP);
this.admin = new SimpleBooleanProperty(admin);
}
public String getUsername() {
return username.get();
}
public void setUsername(String username) {
this.username.set(username);
}
public String getPassword() {
return password.get();
}
public void setPassword(String password) {
this.password.set(password);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public String getSurname() {
return surname.get();
}
public void setSurname(String surname) {
this.surname.set(surname);
}
public String getEmail() {
return email.get();
}
public void setEmail(String email) {
this.email.set(email);
}
public String getCompany() {
return company.get();
}
public void setCompany(String company) {
this.company.set(company);
}
public String getPhone() {
return phone.get();
}
public void setPhone(String phone) {
this.phone.set(phone);
}
public boolean canMonitorize() {
return canMonitorize.get();
}
public void setCanMonitorize(boolean canMonitorize) {
this.canMonitorize.set(canMonitorize);
}
public boolean canCreateProject() {
return canCreateProject.get();
}
public void setCanCreateProject(boolean canCreateProject) {
this.canCreateProject.set(canCreateProject);
}
public boolean canOpenProject() {
return canOpenProject.get();
}
public void setCanOpenProject(boolean canOpenProject) {
this.canOpenProject.set(canOpenProject);
}
public boolean isAdmin() {
return admin.get();
}
public void setAdmin(boolean isAdmin) {
this.admin.set(isAdmin);
}
}
And this is an example of the Json file:
[{"username":"admin","password":"blablabla","name":"admin","surname":"admin","email":"admin#admin.com","company":"admin","phone":"admin","admin":true}]
This is the method that should obtain the list of users:
public static List<User> getUsers(String jsonArrayStr) {
ObjectMapper mapper = new ObjectMapper();
List<User> ret;
try {
User[] userArray = mapper.readValue(jsonArrayStr, User[].class);
ret = new ArrayList<>(Arrays.asList(userArray));
} catch (IOException e) {
return new ArrayList<User>();
}
return ret;
}
The error I get when executing the code:
com.fasterxml.jackson.databind.JsonMappingException: N/A (through reference chain: object.User["username"])
When you have a public 0-args constructor it is used by default to create new POJO instance. But in your case you should not allow to create instance with default constructor because all internal fields are null and when Jackson tries to set first property, username, NullPointerException is thrown. Try to declare your constructor as below and remove default one:
#JsonCreator
public User(#JsonProperty("username") String user,
#JsonProperty("password") String pass,
#JsonProperty("name") String name,
#JsonProperty("surname") String surname,
#JsonProperty("email") String email,
#JsonProperty("company") String company,
#JsonProperty("phone") String phone,
#JsonProperty("monitorize") boolean monitorize,
#JsonProperty("createP") boolean createP,
#JsonProperty("openP") boolean openP,
#JsonProperty("admin") boolean admin) {
//your code;
}
Also, your getUsers method could look like this:
public static List<User> getUsers(String json) {
final ObjectMapper mapper = new ObjectMapper();
try {
final JavaType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, User.class);
return mapper.readValue(json, collectionType);
} catch (IOException e) {
//You should not hide exceptions. Try to log it at least.
//But probably application should not start when app configuration is missing or wrong.
e.printStackTrace();
return Collections.emptyList();
}
}

Struts2 How to get selected value from dropdownlist to other jsp page

This is register.jsp page. Here setting the countryList in dropdownlist from Action class
<s:select name="country" list="countryList" listKey="countryId" listValue="countryName" headerKey="0" headerValue="Country" label="Select a country">
Here I am getting all the list from Action;
when I submit action , I am getting key instead of value on success.jsp.
<s:property value="country"/>
Here I am getting selected key like 0,1,2 instead of country value.
My Action class
public class RegisterAction extends ActionSupport {
private List<String> communityList;
private List<Country> countryList;
private String country;
private String userName;
private String password;
private String gender;
private String about;
private String[] community;
private boolean mailingList;
public String execute() {
return SUCCESS;}
public String populate(){
communityList = new ArrayList<String>();
countryList = new ArrayList<Country>();
countryList.add(new Country(1,"India"));
countryList.add(new Country(2,"US"));
countryList.add(new Country(3,"UK"));
communityList.add("JAVA");
communityList.add(".NET");
communityList.add("SOA");
community=new String[]{"JAVA",".NET"};
mailingList = true;
return "populate";
}
public List<String> getCommunityList() {
return communityList;
}
public void setCommunityList(List<String> communityList) {
this.communityList = communityList;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAbout() {
return about;
}
public void setAbout(String about) {
this.about = about;
}
public String[] getCommunity() {
return community;
}
public void setCommunity(String[] community) {
this.community = community;
}
public boolean isMailingList() {
return mailingList;
}
public void setMailingList(boolean mailingList) {
this.mailingList = mailingList;
}
public List<Country> getCountryList() {
return countryList;
}
public void setCountryList(List<Country> countryList) {
this.countryList = countryList;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Country.java
public class Country {
private String countryName;
private int countryId;
public Country(){}
public Country(int countryId,String countryName){
this.countryId=countryId;
this.countryName=countryName;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public int getCountryId() {
return countryId;
}
public void setCountryId(int countryId) {
this.countryId = countryId;
}
}
You can get the value from the request object.
HttpServletRequest request = (HttpServletRequest)(ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST));
Country value = (Country)request.getParameter("country");
use listKey="countryName" listValue="countryName" in this way you will receive value

Categories

Resources