I have a code which gets a body POST from Postman:
#RequestMapping(value="/dep", method=RequestMethod.POST)
public JsonResponse dep(#RequestBody String body) throws SQLException {
Connection connection = ConnectionSingleton.getInstance().getConnection(env);
Statement statement = connection.createStatement();
statement.close();
connection.close();
System.out.println("BODY #### "+body);
return new JsonResponse("depreciated");
}
Postman sent:
{
"idn":"MLCM00292",
"monto":"9149.92"
}
And the string is like:
%7B%0A%09%22idn%22%3A%22MLCM00292%22%2C%0A%09%22monto%22%3A%229149.92%22%0A%7D=
The words in bold are the parameters and their assigned values. I want to receive the parameters like variable. What its the correct way to get the params from a body in a POST request? What is missing in my code?
You can use a Map like this:
public JsonResponse dep(#RequestBody Map<String, String> body)
and then inside the method get the values like this:
String id = body.get("idn");
String monto = body.get("monto");
You can change the generics type for the Map class as it fits your needs. For example, if you are going to receive values of different types you can use it like Map<String, Object> body, then you could parse every value according to the data type (which you must know in advance). Something like:
String id = body.get("idn").toString();
double monto = Double.parseDouble(body.get("monto").toString());
For more complex data type I recommend you to create some custom POJOs or JavaBeans.
Further readings
Difference between DTO, VO, POJO, JavaBeans?
Related
I have set which contains string ["a" , "b" , "c"] , I want to POST json data like (comma seperated and one string)
Here is
JSON
{"view" : "a,b,c",
"fruits" : "apple"}
to the endpoing using Resttemplate postForObject method? I have used GSON but that is not working in my project. Are there any other alternatives?
Here is my code
private run(set<data> datas) {
Set<string> stack = new hashset<>();
iterator<data> itr = datas.iterator();
while (itr.hasnext()) {
data macro = itr.next();
if (//some condition) {
stack.add(macro);
}
}
}
}
Resttemplate.getmessageconverters().add(stringconvertor);
String result = resttemplate.postforobject(endpoint, request, String.class);
}
If the data is in a specific class like format, you could go with the POJO approach that is encouraged by Spring Boot. But looking at your example, it seems like you want to achieve a one time JSON Object response.
import org.json.simple.JSONObject;
public static void run(set<data> datas, string endpoint){
// build your 'stack' set
String joined = String.join(",", stack);
JSONObject obj=new JSONObject();
obj.put("view",joined);
obj.put("fruits","apple");
//return the jsonObject as the response to your entrypoint using your method
}
You could also try the following if you use #ResponseBody annotation in Spring Boot that will convert the Response Body to the appropriate (JSON) format.
HashMap<String, String> map = new HashMap<>();
map.put("view", joined);
map.put("fruits", "apple");
return map;
I'm going to receive requests with a JSON object passed as querystring which will no longer have a JSON structure, it will be something like this:
http:/mysite/api/doSomething?name=name&address=address...
I need to store it as a String following a JSON structure, the problem is that the original JSON object passed as querystring may have attributes that are collections and I can't figure out a way to parse it back correctly.
Is there a Java function or a library to achieve this easily?
I assume you are using spring mvc/jersey in controller. In that case you can do something like this
#RequestMapping(value = "/mysite/api/doSomething", method = RequestMethod.GET)
public String search(
#RequestParam Map<String,String> allRequestParams) {
JSONObject js = new JSONObject();
for (Map.Entry<String,String> entry : allRequestParams.entrySet()){
js.put(entry.getKey(), entry.getValue());
}
String jsonString = js.toString();
}
Basically get all the queryparam and construct JSONObjcet, JACKSON library will not be of much use here.
I am testing web services using java, RestAssured, groovy notation etc.
I have got separate modules that are depending on each other in terms of passing request methods. such as POST, PUT. when i want to do a POST request on a module, in json schema i have to pass existing id from two different modules into the file. i.e site_id and group_id respectively.
Below is my json schema that i have store in the file:
{
"site_id": 10,
"permission": "admin.client.add",
"group_id": 3
}
Below is my code: from my page class as am using Page object framework.
public String postpermission(String siteid, String grpid)
throws FileNotFoundException, IOException, ParseException {
Object obj = parser.parse(new FileReader(path
+ "/resources/permission/postpermission.json"));
String d = obj.toString();
Object objecc = parser.parse(d.replaceFirst("3", grpid));
Object objec = parser.parse(d.replaceFirst("10", siteid));
JSONObject jsonPostBody = (JSONObject) objec;
jsonPostBody = (JSONObject) objecc;
return postRequest(jsonPostBody, permissionURI, 201, "data.id",
"postpermission()", false);
}
Below is code from my test class:
#Test
public void postpermission() throws FileNotFoundException, IOException,
ParseException {
String siteid = sites.postsites();
String grpid = group.postGroup();
String permid = permission.postpermission(siteid, grpid);
permission.deletepermission(permid);
}
Note: with this code i can replace one id but it doesn't replace the second one. Please can anyone provide me with better way to make it work.
Thanks in anticipation.
You need to notice that the replaceFirst method will not change the original String, it will return the result as a new String.
So in your case, you need to reassign the first replaceFirst result back to variable d. The code as below:
d = d.replaceFirst("3", grpid);
Object objec = parser.parse(d.replaceFirst("10", siteid));
Or you can use simpler one:
Object objec = parser.parse(d.replaceFirst("3", grpid).replaceFirst("10", siteid));
One more suggestion about the JSON schema (I would like to call it json template) you have, it's better to have placeholders instead of using numbers.e.g.
{
"site_id": {site_id},
"permission": "admin.client.add",
"group_id": {group_id}
}
Also you may checkout this JSON template project if you need do more things on json template.
I'm trying to get param values passed to a Java Servlet but the string returned is not correct. I'm storing the values in a Map and checking if the key exists.
Map params;
params = request.getParameterMap();
String id = params.get("id").toString();
String data = params.get("data").toString();
System.out.println("streaming" + data + " with id of " + id);
Yet if I call this servlet via http://localhost:8080/Serv/stream/data?data=hereisdata&id=you my output looks like this:
streaming[Ljava.lang.String;#5e2091d3 with id of [Ljava.lang.String;#36314ab8
What am I missing?
EDIT: as the suggested answers are not working, I'm including the entire class as I'm likely messing something up within the class:
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import Engine.Streamer;
public class AnalyzerController {
private Map params;
private String pathInfo;
private HttpServletRequest request;
public AnalyzerController(HttpServletRequest request)
{
this.params = request.getParameterMap();
this.pathInfo = request.getPathInfo();
}
public void processRequest()
{
System.out.println("procing with " + pathInfo);
switch(pathInfo){
case "/stream/data":
if(params.containsKey("id") && params.containsKey("data")) processStream();
break;
}
}
private void processStream()
{
System.out.println("we are told to stream");
String data = request.getParameter("data");
String id = request.getParameter("id");
Streamer stream = new Streamer();
stream.streamInput(data, "Analyzer", id);
}
}
This line specifically is throwing the NPE: String data = request.getParameter("data");
If you look at the docs of the Request#getParameterMap(), it returns a Map of the type Map<String, String[]>. Therefore, you need to take out the first element from the value String[] array returned from the map.
String id = params.get("id")[0];
Ofcourse, you can avoid all this and directly get the parameters from the request objects using the Request#getParameter() method.
String id = request.getParameter("id");
Edit: Looking at your class code, it seems that the instance variable request is not initialized. Initialize that in the constructor like this:
public AnalyzerController(HttpServletRequest request)
{
this.request = request; // Initialize your instance variable request which is used in the other methods.
this.params = request.getParameterMap();
this.pathInfo = request.getPathInfo();
}
You can get the required parameters instead of the whole map
String id = request.getParameter("id");
String data = request.getParameter("data");
Try something like this.
String data = ((String)params.get("data"));
Or directly from the Request.
String data = request.getParameter("data");
You can use request object plus it's method for to get data usinggetParameter() of you can use getParameterValues() if multiple data are from page.
String id = request.getParameter("id")
String data = request.getParameter("data")
why are you using Map ?
Any special need of it or any reason ?
or you can use like this :
String id = params.get("id")[0];
I've got a MySQL table with Foos. Each Foo has a numeric non-unique code and a name. Now I need to find if any Foo with one of certain codes happens to have a name that starts with a given string. In normal SQL this would be trivial:
select * from FOO where CODE in (2,3,5) and NAME like 'bar%';
But how would I properly do this in Spring now? Without the need for the 'like' operator I'd do it like this:
public List<Foo> getByName(List<Integer> codes, String namePart) {
String sql = "select * from FOO where CODE in (:codes) and NAME=:name"
Map<String,Object> params = new HashMap<String,Object>();
params.put("codes", codes);
params.put("name", namePart);
return getSimpleJdbcTemplate().query(sql, new FooRowMapper(), params);
}
However, with 'like' nothing seems to work: NAME like :name%, NAME like ':name%', or NAME like ?% when using the placeholders instead of named parameters.
I could be brutal and enter it as
String sql = "select * from FOO where CODE in (:codes) and NAME like '"+namePart+"%'";`
but obviously it would be more than nice if Spring would sanitize the input parameters properly etc, you know...
You'd think Spring would support this somehow but I cannot figure it out.
Wait, of course I had to "try one more final thing" before calling it a day, and lo and behold, all my unit tests suddenly pass:
public List<Foo> getByName(List<Integer> codes, String namePart) {
String sql = "select * from FOO where CODE in (:codes) and NAME like :name"
Map<String,Object> params = new HashMap<String,Object>();
params.put("codes", codes);
params.put("name", namePart+"%");
return getSimpleJdbcTemplate().query(sql, new FooRowMapper(), params);
}
I didn't think of entering the "%" in the parameter, I was certain Spring would automatically escape it. I wonder if I'm doing it right?
For named parameters to work, you need to use NamedParameterJdbcTemplate
params.put("name", "Joe%");
jdbcTemplate.query("select * from FOO where CODE in (:codes) and NAME like :name"
In another form, I encountered the same problem, and I tried to solve it via this manner:
public List<MyEntity> getMyEntityValuesBySearchText(String searchText) {
String query = "SELECT * FROM MY_ENTITY_TABLE WHERE NAME LIKE ?";
return this.getJdbcTemplate().query(query, new String[] { "%" + searchText + "%" },
(rs, rowNum) -> new MyEntity(rs.getLong("PK"), rs.getString("NAME")));
}
There is a problem with the code above. The code structure is correct but there is a problem in mapping the variable. You will get the error message as "Index Out of Bound" SQL Exception error.
To avoid that error we map our variable properly using the class "MySqlParameterSource". We needed to create an object for that class and pass our variable inside to map out variables.
Follow this as an example.
public List<Products> getParticular2(#RequestParam String charc){
String sql ="select * from products where name like :name";
Map<String, Object> params = new HashMap<String, Object>();
params.put("name", charc+"%");
MapSqlParameterSource param = new MapSqlParameterSource(params);
List <Products> list = template.query(sql, param, new
BeanPropertyRowMapper<>(Products.class));
return list;
}