I know that this is an easy one if I am not using Jersey and would use something like this:
Enumeration<String> params = request.getParameterNames();
while(params.hasMoreElements()){
String paramName = (String)params.nextElement();
System.out.println("Parameter Name - "+paramName+", Value - "+request.getParameter(paramName));
}
params = request.getHeaderNames();
while(params.hasMoreElements()){
String paramName = (String)params.nextElement();
System.out.println("Header Name - "+paramName+", Value - "+request.getHeader(paramName));
}
params = request.getAttributeNames();
while(params.hasMoreElements()){
String paramName = (String)params.nextElement();
System.out.println("Attribute Name - "+paramName+", Value - "+request.getAttribute(paramName));
}
I am also aware that I can do this and be done with it.
#FormParam("location") String location
But what if I do want to dump all the contents of the form submitted via POST?
The problem is that I am using Jersey as the implementation of JAX-RS and using the code above outputs this:
Attribute Name - org.glassfish.jersey.server.spring.scope.RequestContextFilter.REQUEST_ATTRIBUTES, Value - org.glassfish.jersey.server.spring.scope.JaxrsRequestAttributes#11e035a
Attribute Name - org.glassfish.jersey.message.internal.TracingLogger, Value - org.glassfish.jersey.message.internal.TracingLogger$1#16e45c8
I am guessing that my data is contained here: JaxrsRequestAttributes I am not sure though.
I know I am missing something here. This isn't supposed to be difficult isn't it?
UPDATE
As suggested Sotirios,
This is the code get the dump of the form.
try {
InputStream is = request.getInputStream();
int i;
char c;
while((i=is.read())!=-1)
{
// converts integer to character
c=(char)i;
// prints character
System.out.print(c);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
In order for this to work, I had to remove #FormParam in my parameter and leave out #Context HttpSerlvetRequest request.
Are there no other way to output this in a more elegant way with out the need to remove #FormParam? Maybe get the values from JaxrsRequestAttributes?
I tried to create a variable JaxrsRequestAttributes but it's a default class a can not access it directly.
Based on Sotirios comment's, here's the answer:
Here's the method signature
public Response authenticateUser(MultivaluedMap<String, String> form)
Iterator<String> it = form.keySet().iterator();
while(it.hasNext()){
String theKey = (String)it.next();
System.out.println("Parameter Name - "+theKey+", Value - "+form.getFirst(theKey));
}
System.out.println(form);
The HttpServletRequest can be accessed using :
#Context
private HttpServletRequest request;
Isn't that enough?
Related
ResponseEntity<String> respEntity = null;
try {
respEntity = getConfiguredRestTemplate().exchange(uri.toString()
, HttpMethod.GET
, entity
, new ParameterizedTypeReference<String>() {
});
log.debug("URL to retrieve a document : {}", respEntity.getBody());
}
The respEntity.getBody() returns {"url":"https://aps-fst"}
I want to send only the value - https://aps-fst as parameter to a function to download the content in the URL. How to extract only the URL value and pass it as parameter of type URL / String ?
You can use ObjectMapper from jackson and have the response body transformed into a map from which you can take the url value. You can find an example here.
String jsonString = respEntity.getBody();
JSONObject obj = new JSONObject(jsonString);
String s3urlvalue = obj.getString("url");
log.debug("S3 URL to retrieve a document : {} ", s3urlvalue);
I am able to get value with above code
I have a question on how would be the best way to get the information from a string but that has JSON format.
{
"internal_id":"1234",
"moreInformation":"Failed authentication for user."
}
In this case, I want to get the value of "internal_id" and I already did, with subtring, lastIndexOf and indexOf
public static String returnInternalCode(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length() - 1);
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
I also tried several JSONs with order changes that don't have the data and it also worked. I leave the full class of tests I did:
public class Test {
public static void main(String[] args) {
// Original JSON
String json = "{\"internal_id\":\"999999\",\"moreInformation\":\"Failed authentication for user, 1 authentication attempt remaining.\"}";
// Other JSON order
String json2 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\", \"moreInformation2\":\"Failed authentication for user. \", \"internal_id\":\"45678\"}";
// JSON without the internal_id
String json3 = "{\"moreInformation\":\"Failed authentication for user. Invalid response.\"}";
// JSON without moreInformation
String json4 = "{\"internal_id\":\"999999\"}";
System.out.println("JSON: ".concat(json4));
System.out.println("internalId: " + returnInternalId(json4));
System.out.println("moreInformation: " + returnMoreInformation(json4));
}
public static String returnInternalId(String json){
String internalCode = json.substring(json.lastIndexOf("\"internal_id\":\"") + "\"internal_id\":\"".length(), json.length());
if (json.lastIndexOf("\"internal_id\":\"") == -1) return null;
return internalCode.substring(0, internalCode.indexOf("\""));
}
public static String returnMoreInformation(String json){
String moreInformation = (json.substring(json.lastIndexOf("\"moreInformation\":\"") + "\"moreInformation\":\"".length(), json.length()));
if (json.lastIndexOf("\"moreInformation\":\"") == -1) return null;
return moreInformation.substring(0, moreInformation.indexOf("\""));
}
}
I would like to know if there are better ways to do what I did, such as with StringBuilder or StringBuffer and also to find out which way uses less memory or is faster to run, how do I know that? How long does it take to execute a method?
Thank you very much!
You can extract the values this way; Using Simple-json library
JSONObject jobj = (JSONObject) parser.parse(yourJsonString); // Pass the Json formatted String
String internal_id = (String) jobj.get("internal_id"); // Extract the value from your key
System.out.println(internal_id); // 1234
I want to pass a long series of request parameters (over 2000 characters in total) from one .jsp to another (via a URL), and make it seem to the receiving HTTPServletRequest as if it received the request parameters normally.
I cannot simply pass the URL normally as IE11 is truncating the URL at about 2000 characters (see What is the maximum length of a URL in different browsers?) so I need to have some kind of workaround.
It is trivial to save the url in the ClientSession with a key in one .jsp
public String addValue(String aString) {
String key=""+UUID.randomUUID();
mapValues.put(key, aString);
return key;
}
and then retrieve it in the other .jsp
public String getValue(String key) {
return mapValues.get(key);
}
However the other .jsp needs a HTTPServletRequest and not a string
I.e. I need to be able to do
public MyPosition(HttpServletRequest request) {
this.id= (String)request.getParameter("ID");
Is there anyway of doing this by converting the retrieved url to a HTTPServletRequest?
I know that I could rewrite MyPosition to take a string and extract the data from there directly, but I would much rather not touch the very lengthy, legacy code.
If I could do setParameter on the request, then this would be a solution. But such an option is not available (see HttpServletRequest - SetParameter)
The only way to modify an HttpServletRequest is to wrap it.
It sounds like you want to make a standard POST request instead of what sounds like a GET request.
I tried both #dimplex's and #Deadron's solutions, which I think should both work, but didn't manage to implement either in the short time frame I had available.
I ended up replacing the HTTPServletRequest request parameter in the MyPosition function with String urlKey and adding the following line inside the function
RequestStr request=new RequestStr(cSession,urlKey);
now my existing code did not need to be changed at all, and request.getParameter("paramName") would call my function below.
public class RequestStr {
String url = "";
public RequestStr(ClientSession cSession, String urlKey) {
super();
this.url = cSession.getValue(urlKey);
}
public String getParameter(String aParam) {
int i = url.indexOf("?" + aParam + "=");
if (i == -1) {
i = url.indexOf("&" + aParam + "=");
}
if (i == -1) {
return null;
} else {
int j = url.indexOf("&", i + 1);
if (j == -1) {
return url.substring(i + aParam.length() + 2);
} else {
return url.substring(i + aParam.length() + 2, j);
}
}
}
}
So all I needed to do was to save the very long URL in the session in a map with key urlKey and then in the request just passed this urlKey, and then I could retrieve the long URL via the urlKey and then decode it via my RequestStr class
I have aN HTML form where I have check boxes. In the Servlet, I am trying to print all the Parameter names with Values and In case it has no value i.e it's unchecked , print "BLANK", But surprisingly, the parameter itself is not printed if it has no value/is unchecked.Follows the code:
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("<tr><td>" + paramName + "</td>\n<td>");
String[] paramValues = request.getParameterValues(paramName);
if(paramValues.length == 0)
out.println("BLANK"); //Why does this not work?
// Read single valued data
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.println("<i>No Value</i>");
else
out.println(paramValue);
}
else {
// Read multiple valued data
out.println("<ul>");
for(int i=0; i < paramValues.length; i++) {
out.println("<li>" + paramValues[i]);
}
out.println("</ul>");
}
}
out.println("</tr>\n</table>\n</body></html>");
}
The checkboxes that are NOT checked in a form post are NOT sent as parameters. Only checked checkboxes are posted in the HTTP POST request.
If you want to post the "unchecked" check boxes, you will have to emply a small hack. Please refer this SO post.
Instead of manually looking for each property Use JSTL
tags , where you can just specify the java class and with same field name as in form and values directly maps to the bean
My function looks like this:
#PUT
#Path("property/{uuid}/{key}/{value}")
#Produces("application/xml")
public Map<String,ValueEntity> updateProperty(#Context HttpServletRequest request,
#PathParam("key") String key,
#PathParam("value") String value,
#PathParam("uuid") String uuid) throws Exception {
...
}
I have to modify it, so it accepts indefinite(or many) list of key-value pairs from REST call, something like
#Path("property/{uuid}/{key1}/{value1}/{key2}/{value2}/{key3}/{value3}/...")
Is it possible to store them in an array or list, so I do not list dozens of #PathParams and parameters, to avoid this:
#PathParam("key1") String key1,
#PathParam("key2") String key2,
#PathParam("key3") String key3,
Might be a good opportunity to rethink this design. By using /s, we are in a way signifying, with each / that we are trying to locate a different resource. Key/Value pairs (in the context of the URL) are mainly for query parameters or matrix parameters.
If /property/{uuid} is the path to a main resource, and we just want to offer some parameters to the client for accessing this resource, then we could allow matrix parameters or query parameters
Matrix Parameters (in a request url) will look something like
/12345;key1=value1;key2=value2;key3=value3
A resource method to obtain the values might look something like
#GET
#Path("/property/{uuid}")
public Response getMatrix(#PathParam("uuid") PathSegment pathSegment) {
StringBuilder builder = new StringBuilder();
// Get the {uuid} value
System.out.println("Path: " + pathSegment.getPath());
MultivaluedMap matrix = pathSegment.getMatrixParameters();
for (Object key : matrix.keySet()) {
builder.append(key).append(":")
.append(matrix.getFirst(key)).append("\n");
}
return Response.ok(builder.toString()).build();
}
See PathSegment
Query Parameters (in a request url) might look something like
/12345?key1=value1&key2=value2&key3=value3
A resource method to obtain the values might look something like
#GET
#Path("/property/{uuid}")
public Response getQuery(#PathParam("uuid") String uuid,
#Context UriInfo uriInfo) {
MultivaluedMap params = uriInfo.getQueryParameters();
StringBuilder builder = new StringBuilder();
for (Object key : params.keySet()) {
builder.append(key).append(":")
.append(params.getFirst(key)).append("\n");
}
return Response.ok(builder.toString()).build();
}
See UriInfo
The difference is that Matrix parameters can be embedded into path segments, while query parameters must be placed at the end of the URL. You can also notice a little difference in syntax.
Some Resources
Query String (Wikipedia)
When to use query parameters versus matrix parameters?
URL matrix parameters vs. request parameters
UPDATE
Also looking at the PUT in you method signature, it appears you are trying update a resource using the path as the values for which you are trying to update, as I don't see any parameters in your method for an entity body. When PUTting, you should be sending the representation in the the entity body, not as as path segments or parameters.
A workaround:
#Path("/foo/bar/{other: .*}
public Response foo(#PathParam("other") VariableStrings vstrings) {
String[] splitPath = vstrings.getSplitPath();
}
VariableStrings class:
public class VariableStrings {
private String[] splitPath;
public VariableStrings(String unparsedPath) {
splitPath = unparsedPath.split("/");
}
}
Path segment sequence to vararg array in JAX-RS / Jersey?
Another example where you map the optional parameter to a Map:
#GET
# Produces({"application/xml", "application/json", "plain/text"})
# Path("/location/{locationId}{path:.*}")
public Response getLocation(#PathParam("locationId") int locationId, #PathParam("path") String path) {
Map < String, String > params = parsePath(path);
String format = params.get("format");
if ("xml".equals(format)) {
String xml = "<location<</location<<id<</id<" + locationId + "";
return Response.status(200).type("application/xml").entity(xml).build();
} else if ("json".equals(format)) {
String json = "{ 'location' : { 'id' : '" + locationId + "' } }";
return Response.status(200).type("application/json").entity(json).build();
} else {
String text = "Location: id=" + locationId;
return Response.status(200).type("text/plain").entity(text).build();
}
}
private Map < String, String > parsePath(String path) {
if (path.startsWith("/")) {
path = path.substring(1);
}
String[] pathParts = path.split("/");
Map < String, String > pathMap = new HashMap < String, String > ();
for (int i = 0; i < pathParts.length / 2; i++) {
String key = pathParts[2 * i];
String value = pathParts[2 * i + 1];
pathMap.put(key, value);
}
return pathMap;
}