Trying to see content of map - java

Hi I'm trying to see the content of a map with the following code:
#RequestMapping(value = "/demos", method = RequestMethod.GET,headers="Accept=application/json")
public #ResponseBody String getPartnerIdClusters(Model model) {
Map<Integer, List<Cluster>> partnerIdClusterMap = partnerService.getPartnerIdClusterMap(true, true);
return "partnerIdClusterMap: " + partnerIdClusterMap;
}
Which gave me the following output in the browser:
partnerIdClusterMap: {2=nl.irp.globetrotting.model.Cluster#7499394a}
After that I had tried this code:
String line = "test: /n";
for (Object entry : partnerIdClusterMap.values().toArray()) {
line += entry;
line += "/n";
}
return "partnerIdClusterMap " + line;
But that didn't work either because it has given me the following output:
partnerIdClusterMap test: /nnl.irp.globetrotting.model.Cluster#63769066/n
I already know that it is the Cluster with id 3. Here is a screenshot of it:
link: http://i.imgur.com/pKLu6gf.png
Here is how the getPartnerIdClusterMap() method looks like (in case you want to know):
#Override
public Map<Integer, List<Cluster>> getPartnerIdClusterMap(boolean minorOnly, boolean foreignCountriesOnly) {
BooleanBuilder predicate = new BooleanBuilder();
if (minorOnly) {
predicate.and(qCluster.type.eq(ClusterType.MINOR));
}
if (foreignCountriesOnly) {
predicate.and(qPartner.country.code2.ne("nl"));
}
return from(qCluster)
.innerJoin(qCluster.partner, qPartner)
.where(predicate)
.where(qPartner.country.code2.ne("nl"))
.map(qPartner.id, GroupBy.list(qCluster));
}
This is what I gladly want to know:
So I gladly want to see the Clusterwith all the values from the row.

Spring MVC should be able to convert maps to JSON, with the help of a message converter. Using Spring Boot, just returning maps works for me - a MappingJackson2HttpMessageConverter is automatically configured. As I recall, before using Spring Boot, I just had to configure an ObjectMapper, and then returning the map was working. So, in summary, I think that
Using Spring Boot, returning a map should work.
If not using Spring Boot, an ObjectMapper (and maybe also a MappingJackson2HttpMessageConverter) might be needed to be configured.
If the returned map holds things that the ObjectMapper can't convert by default, it might need you to supply some converting customization. Help material on Jackson (now called fasterxml) ObjectMapper will have more details.

partnerIdClusterMap: {2=nl.irp.globetrotting.model.Cluster#7499394a}
Basically you are printing the values that you specified. In this case you are printing the integer and then the list object populated with Cluster Objects.
Consider to iterate partnerIdClusterMap in your weblogic and extract the values with the methods provided by it or override the toString method of the object to get a full line with details.

Related

Getting error while extracting from list and putting an single attribute furhter into set

I have the below java code now what I am trying to do is that I am getting everything from the repository in the list named Abc list and from that list I am trying to extract an attribute named AbcCode now this tenant code further I want to put in a set of type string so that all tenant code I can have in set but I am getting not able to do that what I have tried is the below approach please advise is it correct
There are a couple of things wrong.
First, the Set is declared with the wrong generic type, second you're not creating an instance of Set, should be:
Set<String> tenantCodeSet = new HashSet<>();
for (Tenant tenant : tenantRepository.findAll()) {
tenantCodeSet.add(tenant.getTenantCode());
}
return tenantCodeSet;
It's also worth noting, if you're using Java 8 or greater you can write this in one line:
return tenantRepository.findAll().stream()
.map(Tenant::getTenantCode)
.collect(Collectors.toSet());
public Set<String> getTenants(String uuid) throws TenantException {
Set<String> tenantCodeSet;
List<Tenant> tenantList;
tenantList = tenantRepository.findAll();
for (Tenant tenant : tenantList) {
tenantCodeSet.add (tenant.getTenantCode());
}
return tenantCodeSet;
}

JSON value replacement by DataGen

Hi StackOverflow Users,
I'm having a following JSON either as JSONObject or String
{
"canconnect" : true,
"NetworkData": {
"mac": "{MAC}",
"ipaddress": "{IP}"
}
}
Here {MAC} and {IP} are kind of PlaceHolder. Once the data for {MAC} and {IP} available from datasource then I need to replace the place holder with proper values using Java.
This is pretty much equivalent to "PropertyPlaceholderConfigurer" in SpringFramework but for Json.
Thanks In Advance,
Arun.
This is as easy as using the replace method of the String class. You should read documentation before asking. Example of its usage:
String aux = "{\"canconnect\" : true, \"NetworkData\": {\"mac\": \"{MAC}\", \"ipaddress\": \"{IP}\"}}";
System.out.println(aux.replace("{MAC}", "YOUR_MAC").replace("{IP}", "YOUR_IP"));

Dynamically build response entity json

I have rest end point which has set of attributes. The user can select attributes need by them. As per the user selection i need to generate the reports.
I use the restTemplate to get the data from end point and populate my response object.
Is there a way I can generate the response object dynamically.
Like if user select
A
B
C
D
restTemplate.exchange(uri, HttpMethod.GET, null, response.class);
In this case my response object should look like
#JsonIgnoreProperties(ignoreUnknown = true)
public class Response {
#JsonProperty("A")
public String A;
#JsonProperty("B")
public String B;
#JsonProperty("C")
public Integer c;
#JsonProperty("D")
public String D;
}
Currently I am statically define the response class, can we dynamically define the response class as per the attributes required by user. please let me know how it can be done.
Map<String, Object> map = new HashMap<>();
map.put("A", "hello");
map.put("B", 2);
String s = objectMapper.writer().writeValueAsString(map);
System.out.println("s = " + s);
Output is
s = {"A":"hello","B":2}
One possible solution could be the creation of a dynamic filter.
Jackson has a built-in filter mechanism which works on simple property filtering.
The default implementation is pretty basic. It allows filtering on simple properties.
The idea would be to dynamically create the string array of properties to filter (include and exclude) with the input request and build the response accordingly.
If you want a more sofisticated filter you could try an addon library I just pushed on github.
Even if you dont need this kind of advanced filtering i think the Usage part of my readme can give you already some hints about the filtering approach.
https://github.com/Antibrumm/jackson-antpathfilter

Java Jersey REST Request Parameter Sanitation

I'm trying to make sure my Jersey request parameters are sanitized.
When processing a Jersey GET request, do I need to filter non String types?
For example, if the parameter submitted is an integer are both option 1 (getIntData) and option 2 (getStringData) hacker safe? What about a JSON PUT request, is my ESAPI implementation enough, or do I need to validate each data parameter after it is mapped? Could it be validated before it is mapped?
Jersey Rest Example Class:
public class RestExample {
//Option 1 Submit data as an Integer
//Jersey throws an internal server error if the type is not Integer
//Is that a valid way to validate the data?
//Integer Data, not filtered
#Path("/data/int/{data}/")
#GET
#Produces(MediaType.TEXT_HTML)
public Response getIntData(#PathParam("data") Integer data){
return Response.ok("You entered:" + data).build();
}
//Option 2 Submit data as a String, then validate it and cast it to an Integer
//String Data, filtered
#Path("/data/string/{data}/")
#GET
#Produces(MediaType.TEXT_HTML)
public Response getStringData(#PathParam("data") String data) {
data = ESAPI.encoder().canonicalize(data);
if (ESAPI.validator().isValidInteger("data", data, 0, 999999, false))
{
int intData = Integer.parseInt(data);
return Response.ok("You entered:" + intData).build();
}
return Response.status(404).entity("404 Not Found").build();
}
//JSON data, HTML encoded
#Path("/post/{requestid}")
#POST
#Consumes({MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON})
#Produces(MediaType.TEXT_HTML)
public Response postData(String json) {
json = ESAPI.encoder().canonicalize(json);
json = ESAPI.encoder().encodeForHTML(json);
//Is there a way to iterate through each JSON KeyValue and filter here?
ObjectMapper mapper = new ObjectMapper();
DataMap dm = new DataMap();
try {
dm = mapper.readValue(json, DataMap.class);
} catch (Exception e) {
e.printStackTrace();
}
//Do we need to validate each DataMap object value and is there a dynamic way to do it?
if (ESAPI.validator().isValidInput("strData", dm.strData, "HTTPParameterValue", 25, false, true))
{
//Is Integer validation needed or will the thrown exception be good enough?
return Response.ok("You entered:" + dm.strData + " and " + dm.intData).build();
}
return Response.status(404).entity("404 Not Found").build();
}
}
Data Map Class:
public class DataMap {
public DataMap(){}
String strData;
Integer intData;
}
The short answer is yes, though by "filter" I interpret it as "validate," because no amount of "filtering" will EVER provide you with SAFE data. You can still run into integer overflows in Java, and while those may not have immediate security concerns, they could still put parts of your application in an unplanned for state, and hacking is all about perturbing the system in ways you can control.
You packed waaaaay too many questions into one "question," but here we go:
First off, the lines
json = ESAPI.encoder().canonicalize(json);
json = ESAPI.encoder().encodeForHTML(json);
Aren't doing what you think they're doing. If your JSON is coming in as a raw String right here, these two calls are going to be applying mass rules across the entire string, when you really need to handle these with more surgical precision, which you seem to at least be subconsciously aware of in the next question.
//Is there a way to iterate through each JSON KeyValue and filter
here?
Partial duplicate of this question.
While you're in the loop discussed here, you can perform any data transformations you want, but what you should really be considering is using the JSONObject class referenced in that first link. Then you'll have JSON parsed into an object where you'll have better access to JSON key/value pairs.
//Do we need to validate each DataMap object value and is there a
dynamic way to do it?
Yes, we validate everything that comes from a user. All users are assumed to be trained hackers, and smarter than you. However if you handled filtering before you do your data mapping transformation, you don't need to do it a second time. Doing it dynamically?
Something like:
JSONObject json = new JSONObject(s);
Iterator iterator = json.keys();
while( iterator.hasNext() ){
String data = iterator.next();
//filter and or business logic
}
^^That syntax is skipping typechecks but it should get you where you need to go.
/Is Integer validation needed or will the thrown exception be good
enough?
I don't see where you're throwing an exception with these lines of code:
if (ESAPI.validator().isValidInput("strData", dm.strData, "HTTPParameterValue", 25, false, true))
{
//Is Integer validation needed or will the thrown exception be good enough?
return Response.ok("You entered:" + dm.strData + " and " + dm.intData).build();
}
Firstly, in java we have autoboxing which means this:
int foo = 555555;
String bar = "";
//the code
foo + bar;
Will be cast to a string in any instance. The compiler will promote the int to an Integer and then silently call the Integer.toString() method. Also, in your Response.ok( String ); call, THIS is where you're going to want to encodeForHTML or whatever the output context may be. Encoding methods are ALWAYS For outputting data to user, whereas canonicalize you want to call when receiving data. Finally, in this segment of code we also have an error where you're assuming that you're dealing with an HTTPParameter. NOT at this point in the code. You'll validate http Parameters in instances where you're calling request.getParameter("id"): where id isn't a large blob of data like an entire JSON response or an entire XML response. At this point you should be validating for things like "SafeString"
Usually there are parsing libraries in Java that can at least get you to the level of Java objects, but on the validation side you're always going to be running through every item and punting whatever might be malicious.
As a final note, while coding, keep these principles in mind your code will be cleaner and your thought process much more focused:
user input is NEVER safe. (Yes, even if you've run it through an XSS filter.)
Use validate and canonicalize methods whenever RECEIVING data, and encode methods whenever transferring data to a different context, where context is defined as "Html field. Http attribute. Javascript input, etc...)
Instead of using the method isValidInput() I'd suggest using getValidInput() because it will call canonicalize for you, making you have to provide one less call.
Encode ANY time your data is going to be passed to another dynamic language, like SQL, groovy, Perl, or javascript.

Auto data-binding Java object without Spring MVC

I am developing a Java web project and not applying Spring MVC, Spring web-flow to it (because it is quite simple). I have a small problem when attaching value from HTTP request to Java object. Is there any standalone library or utility support us to bind data from client request to a server object automatically (matched by property name) without using Spring? Assume that parameters in client request had already built to a map.
When I work with Grails (a web framework for Groovy), it has a very awesome way to fill data in request parameter to object by using: object.properties=parameters, but I do not know that in Java, do we have a similar mechanism to implement it?
Thank you so much.
Apache Commons might help with BeanUtilsBean. It has cool methods like getProperty() and setProperty(), which might help if you wanna try to code it by hand using reflection. There's also the populate(Object bean, Map properties) method, which, i believe, is the closest to what you want.
Dozer is a java library specialized in mapping stuff from one structure to other. It might help.
This guy posted a similar question on coderanch and, after some discussion, he came up with the following:
public static <T extends Object> T setFromMap(Class<T> beanClazz, HashMap<String, String> propValues) throws Exception
{
T bean = (T) beanClazz.newInstance();
Object obj = new Object();
PropertyDescriptor[] pdescriptors = null;
BeanInfo beanInfo = Introspector.getBeanInfo(beanClazz);
pdescriptors = beanInfo.getPropertyDescriptors();
for(int i=0; i<pdescriptors.length; i++)
{
String descriptorName = pdescriptors[i].getName();
if(!(descriptorName.equals("class")))
{
String propName = descriptorName;
String value = (String) propValues.get(propName);
if(value != null)
{
Object[] objArray = new Object[1];
objArray[0] = value;
Method writeMethod = pdescriptors[i].getWriteMethod();
writeMethod.invoke(bean, objArray);
}
}
}
return bean;
}

Categories