I am using the java speech recognition API - Jarvis located at https://github.com/lkuza2/java-speech-api
However when I run my application, I get an error : Server returned HTTP response code: 400 for URL: https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&lang=en-US&maxresults=1 (This is the URL that this api uses to get response from Google)
I also created a API key as mentioned in the earlier posts and tried to use the url (this is version 2 API): www.google.com/speech-api/v2/recognize?output=json&lang=en-US&key=MYKey". But in this case I get a null response from Google.
Can anybody please tell me how to get around this?
I change some things from the Recognizer class:
I change the GOOGLE_RECOGNIZER_URL constant to:
private static final String GOOGLE_RECOGNIZER_URL = "https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=YOUR_KEY";
Then I changed this method because the response data have 2 lines
private String rawRequest(File inputFile, int maxResults, int sampleRate) throws IOException
The first line (the one that is read and sent) is null (i don¡t really know why) and the second line has the response of the speech recognized. For this you must read the second line (don't know if there is a nicer way):
String response = br.readLine();
response = br.readLine();
br.close();
return response;
Then I change this method, I think it was using the v1 URL response or something because this method looks for utterance in the json response and there is none utterance key.
private void parseResponse(String rawResponse, GoogleResponse googleResponse)
if (rawResponse == null)
return;
JSONObject jsonObject = new JSONObject(rawResponse);
JSONArray jsonArray= (JSONArray) jsonObject.get("result");
JSONArray jsonArrayResult = (JSONArray) jsonArray.getJSONObject(0).get("alternative");
googleResponse.setResponse(jsonArrayResult.getJSONObject(0).get("transcript").toString());
googleResponse.setConfidence(jsonArrayResult.getJSONObject(0).get("confidence").toString());
I'm new with the json library so it might be a better and shorter way but this worked for me!
Related
I am using the below code for sanitizing the JSON but still, I am getting the JSON injection while scanning from Fortify can you please help me out what is the problem or this is not an issue, maybe suppress. I have also looked out for the same question but those don't solve my problem . my problem is that I am sanitizing my JSON before converting it to java object but still I am getting JSON injection error in fortify
public String handleEventMessage(String jsonRequest) {
MonerisPaymentDetailsObject paymentObject = null;
if(null!=jsonRequest && jsonRequest.length()>0){
try{
paymentObject = mapper.readValue(JsonSanitizer.sanitize(jsonRequest), MonerisPaymentDetailsObject.class);
}catch(Exception ex){
logger.error("Error occured while converting MonerisPaymentDetailsObject json to Object :" , ex);
}
return "abc";
}
Fortify giving below description for this error
1. Data enters a program from an untrusted source.
In this case the data enters at readLine() in EPWFPaymentServicesServlet.java at line 49.
2. The data is written to a JSON stream.
In this case the JSON is written by readValue() in EPWFMonerisPaymentsServiceHandler.java at line 46.
EPWFPaymentServicesServlet.java code where data is entered
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
CodeTimer timer = new CodeTimer("EPWFPaymentServicesServlet.doPost()", true);
response.setContentType("text/xml");
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
StringBuffer requestBuffer = new StringBuffer(request.getContentLength());
String line = null;
while ((line = reader.readLine()) != null) {
requestBuffer.append(line).append('\n');
}
// read the POST request contents
String requestString = requestBuffer.toString();
if (logger.isDebugEnabled()) {
logger.debug("EPWF Payment Service POST Request: \n" + ((requestString == null) ? "Null" : requestString.substring(0, 9)));
}
PaymentServiceHandlerComposit paySvcHandler = new PaymentServiceHandlerComposit();
String responseString =paySvcHandler.handleEventMessage(requestString);//line no 49 where fortify is giving description for class where i am sanitizing the data
if (logger.isDebugEnabled()) {
logger.debug("EPWF Payment Service POST Response: \n" + ((responseString == null) ? "Null" : requestString));
}
response.getOutputStream().print(responseString);
timer.stopAndLogTiming("");
}
Given that you are using a new up-to-date version of jackson, there should be no need to pre-sanitise or alter your data at all before handing it off to jackson.
Jackson will only accept and parse valid JSON, as new exploits and vulnerabilities are discovered, the maintainers of Jackson fix and release new versions. and the best you can do is to keep up to date with these versions.
If the above conditions are met, you can safely suppress this error from fortify, the chance that there is a bug in your custom sanitizer is way higher than the chance of there being one in Jackson
I am using Rest Assured Framework for API testing(Using Java).
At line (1),I am expecting error as there is mismatch in expected JSON response and Actual JSON response
But instead my code is executing successfully.
Can someone please tell me if I am doing anything wrong in below code?
public void test123() {
try {
//Read the Curl Request Input file
String json = input.readFromTextFile(
System.getProperty("user.dir") + "\\src\\test\\resources\\inputFile\\CurlDataFile.txt");
json = json.replaceAll(" ", "");
RestAssured.baseURI = "My URL";
given().
contentType("application/json").
body(json).
when().
post("").
then().
assertThat().body(matchesJsonSchemaInClasspath("testCurlOuput1.json")); (1)
} catch (IOException e) {
e.printStackTrace();
}catch(JsonSchemaValidationException e){
e.printStackTrace();
}
}
This is not directly relevant to REST-assured, but I suggest you take a look at Karate, because IMO it may be exactly what you are looking for.
One of the core features of Karate is that you can perform a full equality match of a JSON payload in one step.
And you can easily use JSON from files, which encourages the re-use of payloads across multiple tests.
You are catching all Exceptions. When your assertThat(..) fails, it throws an Exception. Put a breakpoint on the e.printStackTrace(); run in DEBUG mode and check that your AssertionException/Error isn't being caught.
Instead of catching exceptions, just add all Checked Exceptions to your test signature. If an exception is uncaught, it will fail the test. Alternatively, but less prefered in my opinion, resolve by putting fail(); in the catch block.
Finally I choose different library i.e. jayway.restassured library and then JSON Assert library (org.skyscreamer.jsonassert.JSONAssert) which will comapre actual and expected response.
public void test123() {
String postData = input.readFromTextFile(System.getProperty("user.dir") + "\\src\\test\\resources\\inputFile\\CurlDataFile.txt");
RestAssured.baseURI = "MY URL";
Response r = (Response)given().contentType("application/json").body(postData).when().post("");
String responseBody = r.getBody().asString();
String curlResponse = //I am providing expected Curl response here
//JSON Assertion for matching Expected and Actual response
JSONAssert.assertEquals(curlResponse, responseBody, false);
}
Also sometime we may want to avoid comparing particular field from JSON like some ID field which generate dynamically which we can do using JSON comparator
I am a fan of JSONAssert as this provides easy comparing of complete JSONs.
Just use .extract().response().getBody().asString() to get the string representation of the answer.
Complete example:
#Test
public void getReturnsExpectedDataForMailExampleCom() throws JSONException {
String response = get("/users/mail#example.com")
.then()
.statusCode(200)
.extract().response().getBody().asString();
JSONAssert.assertEquals(
"{\"email\":\"mail#example.com\",\"locale\":\"de-DE\"}",
response,
false);
}
Update The drawback is that the complete JSON is not output to stdout if the assertion fails.
I am a front-end web developer trying to learn more about the back-end. Currently I just want to read in a local JSON file and expose it in a REST service to be parsed by AngularJS (does that make sense?). I believe I have the servlet set up correctly, but am not sure about how I am approaching this from a Java perspective. It's worth noting that I'm a JavaScript programmer. There are two methods that I am trying to decide between.
The following methods are contained in the class
#Path("/")
public class JsonRESTService {
.....
}
First method
#GET
#Path("/jsonService")
#Consumes("application/json")
#Produces("application/json")
public Response jsonREST(InputStream incomingData) {
StringBuilder jsonBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incomingData));
String line = null;
while((line = in.readLine()) != null) {
jsonBuilder.append(line);
}
} catch(Exception e) {
System.out.println("Error Parsing: - ");
}
System.out.println("Data Received: " + jsonBuilder.toString());
return Response.status(200).entity(jsonBuilder.toString()).build();
}
Second Method: not sure what to return.
#GET
#Path("/jsonService")
#Consumes("application/json")
#Produces("application/json")
public Response jsonREST(InputStream incomingData) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("C:/files/flat.json"));
JSONObject jsonObject = (JSONObject) obj;
} catch(Exception e) {
e.printStackTrace();
}
}
web.xml servlet mapping
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
So this should be exposed to http://localhost:8080/myapp/rest/jsonService. I got some of this code from a tutorial, but it seems like I want to have a method that returns a JSONObject instead of a Response. Is that correct? Am I on the right track, or is there a really good example of what I am trying to do that I haven't found yet?
There are multiple ways of doing it. You can try this way in the second method
Change the return type to String and return the value of JSONObject as a String using
return jsonObject.toString();
In the client side, Angular JS services - you can convert the String into JSON object through
var obj = JSON.parse(text);
So, now obj is a JSON object which you can use it for further processing.
if you are a JavaScript developer and getting started quickly is the goal, then I would recommend you checkout
http://www.dropwizard.io/getting-started.html
There are a few advantages here
a) much of the server infrastructure stuff is hidden away
b) you can focus on your implementation details
c) no need to figure out how to deploy this etc, it comes with a server built in.
To answer your question about the return type - the server will return javax.ws.rs.core.Response - or some other variation of a Response object. This encapsulates things like HTTP Status codes http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .
Therefore in order to send a simple response back you may use something like :
return Response.accepted().entity(String.format("{\"JSON\" : \"%s\"}",value)).build();
Replace the string with a JSON string read from file system or generate the JSON from object - what ever your pick of poison is.
Here is the message schema:>
message ServerResponse {
optional string ReferenceCode = 1;
optional NestedMessageProto.NestedMessage NestedMessage = 2;//Huge size data in response
optional bool Success = 3 [default = false];
repeated Errors Errors = 4;
}
Below is code for getting the response from serve and calling the proto response method.
String apiResponse = Server Response
protoResponseClass.parseFrom(apiResponse.getBytes())
its failing when reading the NestedMessage response on below bold line
public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
if (byteLimit < 0) {
throw InvalidProtocolBufferException.negativeSize();
}
byteLimit += totalBytesRetired + bufferPos;
if (byteLimit > currentLimit) {
currentLimit = byteLimit + currentLimit;
}
final int oldLimit = currentLimit;
**if (byteLimit > oldLimit) {
throw InvalidProtocolBufferException.truncatedMessage();
}**
currentLimit = byteLimit;
recomputeBufferSizeAfterLimit();
return oldLimit;
}
When its reading nested message the byte limit becoming greater than old limit.
What could be the solution?
Thanks
This is almost certainly the problem:
String apiResponse = Server Response
protoResponseClass.parseFrom(apiResponse.getBytes())
Protocol buffer messages are binary data. They're not text, and shouldn't be handled as text. You're taking the binary response from the server, interpreting it as text in some way (we can't tell how), then converting it back to a byte array using the platform default encoding (which is almost always a bad idea - never call getBytes() without specifying a charset, even when calling getBytes() is appropriate, which it's not here). The conversion to text and back is almost certainly losing information - quite possibly making the parsing code expect more data than is actually present in the message.
You should be handling the server response as binary data from the start - ideally just passing an InputStream from the server response into parseFrom, but at least reading it as a byte array instead of a String.
Instead of converting httpresponse to string and then to byte array for parsing, use EntityUtils.toByteArray directly.
private String readResponse(HttpResponse httpresponse) throws IOException {
int responseCode = httpresponse.getStatusLine().getStatusCode();
String mimeType = httpresponse.getFirstHeader(CONTENT_TYPE_KEY).getValue();
if (responseCode != HttpURLConnection.HTTP_OK) {
String cause = String.format("Bad HTTP response code: %d\nOr MIME type: %s", responseCode, mimeType);
throw new IOException(cause);
}
return EntityUtils.toString(httpresponse.getEntity());
}
I'm coming from this question.
The following code does not work well:
public static void main(String[] args) throws Exception {
for (int i = 0; i < 15; i++)
{
String google = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
String search = "test";
String charset = "UTF-8";
URL url = new URL(google + URLEncoder.encode(search, charset));
Reader reader = new InputStreamReader(url.openStream(), charset);
GoogleResults results = new Gson().fromJson(reader, GoogleResults.class);
// Show title and URL of 1st result.
System.out.println(results.getResponseData().getResults().get(0).getTitle());
System.out.println(results.getResponseData().getResults().get(0).getUrl());
}
}
The search query works fine if I run it one time, however in this loop I get a null pointer exception.
Unfortunately I need my program to make several queries :( What can I do?
It returns a NullPointerException at the first results.getResponseData.
This is happening because Google actively blocks suspected terms of service abuse. See section 5.3 here:
http://www.google.com/accounts/TOS
If Google detects that you are issuing search requests via a program without their consent, they don't send back results. Your JSON response will contain this:
{"responseData": null, "responseDetails": "Suspected Terms of Service Abuse. Please see http://code.google.com/apis/errors", "responseStatus": 403}
Check to make sure results and other contained objects are not null before you use them.
if ((results != null) && (results.getResponseData() != null) &&
(results.getResponseData().getResults() != null) &&
(results.getResponseData().getResults().get(0) != null)) {
// Show title and URL of 1st result.
System.out.println(results.getResponseData().getResults().get(0).getTitle());
System.out.println(results.getResponseData().getResults().get(0).getUrl());
}