I have implemented a RESTful web Service in java which inserts data into MySQL db, I have tested this using POSTER in mozila firefox and also in google chrome. My Web Service takes a String with the POST request, now I am unable to utilize WEB SERVICE using JS: the code making POST request on WEB SERVICE URL is as follows:
$.ajax({
url: 'http://localhost:8080/AgentWS/webresources/Items',
type: 'POST',
contentType: 'application/xml',
dataType: 'xml',
data: 'content='+content,
success: function (data) {
alert(content);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Error: " + errorThrown);
}
});
The alert in success function is also not displayed plus the dialog error is showing a dialog with : Error: on it'
Server Side code is:
#POST
#Consumes("application/xml")
#Produces("application/xml")
public String postXml(String content) {
//TODO
// return Response.created(context.getAbsolutePath()).build();
StringTokenizer sp = new StringTokenizer(content, "&");
String agentName = sp.nextToken();
String agentId = sp.nextToken();
String agentState = sp.nextToken();
String agentExtension = sp.nextToken();
String agentDeviceState = sp.nextToken();
String agentDeviceStateChangeTime = sp.nextToken();
DBConection conn = new DBConection();
conn.insertAgentActivityInfo(agentName, agentId, agentState, agentExtension, agentDeviceState, agentDeviceStateChangeTime);
return agentName + " " + agentId + " " + agentState + " " + agentExtension + " " + agentDeviceState + " " + agentDeviceStateChangeTime;
}
I think the problem is with the data you are sending,
data: 'content='+content should be replaced with a name for the parameter like
data: {content:'content='+content}
and check what you are doing on the server side
My guess is that data: 'content='+content, is posting invalid XML to the server and you are getting 500 Internal Server Error. Can you try setting the data to just the XML content? like
...
data: content,
....
EDIT
If all you want is a simple post
Java
#POST
public String postXml(String content) {
//TODO
// return Response.created(context.getAbsolutePath()).build();
StringTokenizer sp = new StringTokenizer(content, "&");
String agentName = sp.nextToken();
...
return agentName + " " + agentId + " " + agentState + " " + agentExtension + " " + agentDeviceState + " " + agentDeviceStateChangeTime;
}
Javascript
$.ajax({
url: '/AgentWS/webresources/Items',
type: 'POST',
data: 'content=1&2&3&4&5&5',
success: function (data) {
alert(data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Error: " + errorThrown);
}
});
Here's what i think, you should write a model class Agent in server side like this :
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Agent
{
private String agentName;
private String agentId;
private String agentState;
private String agentExtension;
private String agentDeviceState;
private String agentDeviceStateChangeTime;
public String getAgentName() {
return agentName;
}
public void setAgentName(String agentName) {
this.agentName = agentName;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public String getAgentState() {
return agentState;
}
public void setAgentState(String agentState) {
this.agentState = agentState;
}
public String getAgentExtension() {
return agentExtension;
}
public void setAgentExtension(String agentExtension) {
this.agentExtension = agentExtension;
}
public String getAgentDeviceState() {
return agentDeviceState;
}
public void setAgentDeviceState(String agentDeviceState) {
this.agentDeviceState = agentDeviceState;
}
public String getAgentDeviceStateChangeTime() {
return agentDeviceStateChangeTime;
}
public void setAgentDeviceStateChangeTime(String agentDeviceStateChangeTime) {
this.agentDeviceStateChangeTime = agentDeviceStateChangeTime;
}
}
And the server rest service that you have should be changed little bit :
#POST
#Consumes("application/xml")
#Produces("application/xml")
public String postXml(Agent agent) {}
Inside this method you can use "agent" object, that is passed, to retrieve all the values sent by the client like agent.getAgentName()
Now the payload(or request body) that should contain something like this:
<Agent>
<agentName></agentName>
<agentId></agentId>
<agentState></agentState>
<agentExtension></agentExtension>
<agentDeviceState></agentDeviceState>
<agentDeviceStateChangeTime></agentDeviceStateChangeTime>
</Agent>
I hope it is of some assistance.
Hard to guess without the error code and message but:
change
data: 'content='+content
to
data: { content : content } // format as json
And in your java resource:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String postXml(String content)
// read content as json
Related
I am working on restassured and here is my 2 methods. I want to use the albumId returned from the AlbumList method in the other method
public void AlbumList() {
Response response1 = given().spec(url).queryParam("page", 0).queryParam("size", 100)
.queryParam("sortBy", "createdDate").queryParam("contentType", "album/photo")
.queryParam("sortOrder", "ASC")
.header("Content-type", "application/json")
.header("Accept", "application/json")
.header("X-Auth-Token", payload.userAuth())
.when().get("/album")
.then().assertThat().statusCode(200).extract().response();
Assert.assertEquals(response1.jsonPath().get("[4].label"), "TLOTR");
JsonPath js = new JsonPath(response1.asString());
int count = js.getInt("size()");
// Response check part
for (int i = 0; i < count; i++) {
assertEqual(js, i, "createdDate", AlbumAttributes.actual_createdDate());
assertEqual(js, i, "lastModifiedDate", AlbumAttributes.actual_modifiedDate());
assertEqual(js, i, "uuid", AlbumAttributes.actual_uuid());
if (js.get("[" + i + "].coverPhoto") != null) {
String d = response1.jsonPath().get("[" + i + "].coverPhoto.tempDownloadURL").toString();
Assert.assertTrue(d.matches(AlbumAttributes.actual_temp_url()));
System.out.println(js.get("[" + i + "].coverPhoto.tempDownloadURL").toString() + " is equalent to : " + AlbumAttributes.actual_temp_url());
}
if (js.get("[" + i + "].coverPhoto.metadata['Thumbnail-Large']") != null) {
String e = response1.jsonPath().get("[" + i + "].coverPhoto.metadata['Thumbnail-Large']").toString();
Assert.assertTrue(e.matches(AlbumAttributes.actual_metaData_url()));
System.out.println(js.get("[" + i + "].coverPhoto.metadata['Thumbnail-Large']").toString() + " is equalent to : " + AlbumAttributes.actual_metaData_url());
}
}
String albumId = response1.jsonPath().get("[0].uuid").toString();
String albumId2 = response1.jsonPath().get("[1].uuid").toString();
}
I know these are void and doesnt return anything but idk how to use it. Bye the these methods are in the same class. Thanks in advance
public void AlbumDetails() {
Response response = given().queryParam("page", 0).queryParam("size", 100)
.queryParam("sortBy", "createdDate").queryParam("sortOrder", "DESC")
.header("Content-type", "application/json")
.header("Accept", "application/json")
.header("X-Auth-Token", payload.userAuth())
.when().get("/album/" + albumId)
.then().assertThat().statusCode(200).extract().response();
// Response check part
Assert.assertEquals("[]", response.jsonPath().get("fileList").toString());
Assert.assertEquals("album/photo", response.jsonPath().get("contentType").toString());
Assert.assertEquals("false", response.jsonPath().get("readOnly").toString());
Assert.assertTrue(response.jsonPath().get("createdDate").toString().matches(AlbumAttributes.actual_createdDate()));
Assert.assertTrue(response.jsonPath().get("lastModifiedDate").toString().matches(AlbumAttributes.actual_modifiedDate()));
Assert.assertTrue(response.jsonPath().get("uuid").toString().matches(AlbumAttributes.actual_uuid()));
System.out.println("Album Details Response Test PASS");
long albumDetails_time = response.getTime();
System.out.println("\tAlbum Detail's Api response time is : " + albumDetails_time);
}
The easiest way is to change the return type of the AlbumList() method from void to String:
public String AlbumList() {
And in AlbumDetails() method we should change:
.when().get("/album/" + AlbumList())
Another option is to create instance variable albumId, not locally in AlbumList() method, and use it:
public class SomeClass {
public String albumId;
public void AlbumList() {
...
albumId = response1.jsonPath().get("[0].uuid").toString();
}
public void AlbumDetails() {
...
.when().get("/album/" + albumId)
...
}
}
P.S. Here are some more tips:
due to clean code more correct name describes what these methods do, e.g. getAlbumList() or storeAlbumList() and smth similar for another method;
for extracting jsonPath from response we can use: JsonPath js = given()....extract().jsonPath();
I need to read JSON from file and replace few objects.
For example, I have class User.java
public class User {
String username;
String email;
String city;
String code;
}
and JSON:
{
"variables":
{
"user":
{
"value":
{
"username": "$USERNAME",
"email": "$EMAIL",
"city": "$CITY"
}
}
}
}
I have two questions:
How can I read JSON from file? Read JSON will be send by WebClient POST API.
How can I replace $USERNAME, $EMAIL and $CITY? I won't hardcode it.
I have register form. When someone complete form, it will be replaced for $...
Firsty, I got hardcode JSON to string but I need read it from file
class JSONClass {
static String toFormat(User user) {
String jsonUserRegister = "{\n" +
" \"variables\":\n" +
" {\n" +
" \"user\": \n" +
" {\n" +
" \"value\":\n" +
" {\n" +
" \"username\": \"" + user.getUsername() + "\",\n" +
" \"email\": \"" + user.getEmail() + "\",\n" +
" \"city\": \"" + user.getCity() + "\",\n" +
" \"code\": \"" + user.getCode() + "\"\n" +
" } }\n" +
" }\n" +
"}";
return jsonUserRegister;
This can be achieved using Spring Boot to set up the backend to receive client calls. So to get Task 1a working, we need below
#RestController
public class JsonReaderController {
#Autowired
private ResourceLoader resourceLoader;
#PostMapping(value = "/read-json")
public String fileContent() throws IOException {
return new String(Files.readAllBytes(
resourceLoader.getResource("classpath:data/json- sample.json").getFile().toPath()));
}
}
Above code simply reads file content and returns as String. Note default response is Json.
Now that we have the backend done, we need Task 1b - Sending the POST request.
private String readJsonFile() throws IOException {
final OkHttpClient client = new OkHttpClient();
final String requestUrl = "http://localhost:8080/read-json";
Request request = new Request.Builder()
.url(requestUrl)
.post(RequestBody.create(JSON, ""))
.build();
try (Response response = client.newCall(request).execute()) {
//we know its not empty given scenario
return response.body().string();
}
}
readJsonFile method makes a POST request - using OkHttp to our backend bit (done in Task 1a) and returns the content of the file as json.
And for Task 2 - replacing $USERNAME, $EMAIL and $CITY with appropriate values. For this, we will use the Apache commons-text library.
public static void main(String[] args) throws IOException {
String fileContent = new ReadJsonFromFile().readJsonFile();
User user = new User("alpha", "alpha#tesrt.com", "Bristol", "alpha");
Map<String, String> substitutes = new HashMap<>();
substitutes.put("$USERNAME", user.getUsername());
substitutes.put("$EMAIL", user.getEmail());
substitutes.put("$CITY", user.getCity());
substitutes.put("$CODE", user.getCode());
StringSubstitutor stringSubstitutor = new StringSubstitutor(substitutes);
//include double quote prefix and suffix as its json wrapped
stringSubstitutor.setVariablePrefix("\"");
stringSubstitutor.setVariableSuffix("\"");
String updatedContent = stringSubstitutor.replace(fileContent);
System.out.println(updatedContent);
}
Hope this helps.
I've a problem with call WS Rest Java. I call the WS but the parameters isn't passed.
My java code:
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response setUser(#FormParam("name") String name, #FormParam("surname") String surname, #FormParam("email") String email,
#FormParam("phone") String phone, #FormParam("skype") String skype, #FormParam("password") String password){
try {
FileOutputStream fis = new FileOutputStream("/home/File.txt");
PrintStream ps = new PrintStream(fis);
String s = "name: "+name+"\nSurname: "+surname+"\nEmail: "+email+"\nPhone: "+phone+"\nSkype: "+skype+"\nPassword: "+password;
ps.println(s);
ps.close();
fis.close();
UserDAO userdao = new UserDAO(0,name,surname,email,phone,skype);
userdao.save();
...
return Response.status(200).entity(new ObjectMapper().writeValueAsString("OK!")).header("Access-Control-Allow-Origin", "*").build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(500).entity("ERROR!").header("Access-Control-Allow-Origin", "*").build();
}
}
Angular call:
data = {
name: $scope.reg_name,
surname: $scope.reg_surname,
email: $scope.reg_email,
phone: $scope.reg_phone,
skype: $scope.reg_skype,
password: $scope.reg_password
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
});
If i log data on angular data are set, the call working but i've an error when i create AccountDAO object because the parameters are null. To test the parameters values i create a file and put here the value, the content are this:
name: null
Surname: null
Email: null
Phone: null
Skype: null
Password: null
Any one have idea why not pass the parameters?
Thanks!
Solved:
data = "name=" + $scope.reg_name +
"&surname=" + $scope.reg_surname +
"&email=" + $scope.reg_email +
"&phone=" + $scope.reg_phone +
"&skype=" + $scope.reg_skype +
"&password=" + $scope.reg_password;
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
Thanks grizzly!
You are sending data as JSON. Change it to form data string:
data = "name=" + $scope.reg_name +
"&surname=" + $scope.reg_surname +
"&email=" + $scope.reg_email +
"&phone=" + $scope.reg_phone +
"&skype=" + $scope.reg_skype +
"&password=" + $scope.reg_password;
}
$http.post(baseUrl+'user/',data,{
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
I keep receiving null values while sending these two parameters thru a POST with ajax (tried with Poster as well):
#POST
#Path("/update")
#Produces(MediaType.APPLICATION_JSON)
public void update(String Path, String Content) {
updateURI(Path,Content);
}
Path: http://essam.ldm.io/stor...amblog/ChannelList/ch1/post2
Content: <http://essam.ldm.io/storage/essamblog/ChannelList/ch1/post2> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://crosscloud/mblog/Post>. <http://essam.ldm.io/storage/essamblog/ChannelList/ch1/post2> <http://crosscloud/mblog/owner> <https://essam.ldm.io></https:>. <http://essam.ldm.io/storage/essamblog/ChannelList/ch1/post2> <http://purl.org/dc/terms/created> <2013-03-06T16:41:18+0300^^http://www.w3.org/2001/XMLSchema#dateTime>. <http://essam.ldm.io/storage/essamblog/ChannelList/ch1/post2> <http://rdfs.org/sioc/ns#content>.
Obviously I cannot send them as #QueryParam or #PathParam due to the format.
It is irrilevant putting the jQuery code since it deosnt wotk with Poster neither, but here it is:
function doUpdate(path, rdf)
{
var obj1 = {"path": path, "rdf": rdf};
var sUrl = "http://localhost:8080/browsing/services/RDF/update";
$.ajax({
type: "POST",
url: sUrl,
contentType: "application/json; charset=utf-8",
data: obj1,
//dataType: "json",
async: false,
success: function (resp, status, xhr) {
$("#message").html("STATUS: " + xhr.status + " " + xhr.statusText + "\n" + resp);
$("#message").hide();
$("#login_message").html("<font color='green'><b>Record succesfully updated</b></font>d");
},
error: function(resp, status, xhr){
$("#message").html("ERROR: " + resp.status + " " + resp.statusText + "\n" + xhr);
$("#message").show();
}
});
}
Anything I am doing wrong?
Thanks,
You can encode it (i.e. base64) before you send it and decode it on server or you can use JSON as request param.
Using JSON, for example;
#POST
#Path("/update")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void update(PathContext ctx) {
updateURI(ctx.getPath(),ctx.getContent());
}
#XmlRootElement
public class PathContext {
private String path;
private String content;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Your JSON will look like;
{"path": somePath, "content": someContent}
Hope it helps.
I am working on a project adding some Ajax to a Spring-MVC project. I removed the tags
<form:errors path="fieldName"/>
That would insert the error the JSP, now I am trying to make some Ajax code to display the errors on the page. can anyone should me how to updated the following code to display the error messages and NOT the errors?
success: function(response)
{
// we have the response
$('#error').hide('fast');
if(response.status == "SUCCESS")
{
$('#error').hide('fast');
alert("Thanks for submitting. We will get back to you as soon as possible.\n\n" + response.result);
$('#error').hide('slow');
}else
{
errorInfo = "";
for( i = 0 ; i < response.result.length ; i++){
errorInfo += "<br>" + (i + 1) +". " + response.result[i].code;
}
$('#error').html("Please correct following errors: " + errorInfo);
$('#info').hide('slow');
$('#error').show('slow');
$('#input').show('slow');
}
},
error: function(e){
alert('Error: ' + e);
}
});
The above code works to display the errors but not the error messages
below is my java code:
#RequestMapping(value = "/ajax.html", method = RequestMethod.POST)
public #ResponseBody
JsonResponse addMessage(#Valid
#ModelAttribute(value = "memberrequest") MemberRequest memberrequest,
BindingResult result) {
JsonResponse res = new JsonResponse();
if (!result.hasErrors()) {
res.setStatus("SUCCESS");
// Setting data over to RT
String Ticket = zzz.sentWebRequest(memberrequest);
/*
* Setting out the ticket number to be displayed to user
*/
Map<String, Object> model = new HashMap<String, Object>();
Ticket t = new Ticket();
t.setTicketDetails(Ticket);
model.put("ticket", t);
res.setResult(Ticket);
} else {
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
}
JSON Class:
public class JsonResponse { private String status = null; private
Object result = null;
public String getStatus() { return status; }
public void setStatus(String status) { this.status = status; }
public Object getResult() { return result; }
public void setResult(Object result) { this.result = result; }
}
Try response.result[i].defaultMessage instead of response.result[i].code.
response.result
There is no result attribute in response object according to XMLHttpRequest 2 by W3C
If you pass some text value in response form server end. you can get it response.responseText as a whole text.