I try to send an email from our java project but every time I have a code error 400. So I take the same request printed in the java console and send it from Postman with the same other elements then it works from Postman and i receive the email but from java I have always the code error 400 bad request and when i turn on the Mailjet debug mode the content is null.
Here the final JSON made by Java and inject from Postman
{
"Messages": [
{
"Variables": {
"objet": " objet",
"body": " body "
},
"From": {
"Email": "no-reply#gmail.com"
},
"To": [
{
"Email": "send#gmail.com",
"Name": ""
}
],
"TemplateID": 111111,
"TemplateLanguage": true,
"Subject": "[[data:objet:\" anything\"]]"
}
]
}
The java code :
/**
* Send a message
* #return MailjetResponse
* #throws MailjetException
* #throws MailjetSocketTimeoutException
*/
public MailjetRequest sendEmailCore() {
return new MailjetRequest(Emailv31.resource)
.property(Emailv31.MESSAGES, new JSONArray()
.put(new JSONObject()
.put(Emailv31.Message.FROM, new JSONObject()
.put("Email", senderMail)
.put("Name", senderName))
.put(Emailv31.Message.TO, getRecipientsJson())
.put(Emailv31.Message.TEMPLATEID, TEMPLATE_ID)
.put(Emailv31.Message.TEMPLATELANGUAGE, true)
.put(Emailv31.Message.SUBJECT, "[[data:objet:\" anything\"]]")
.put(Emailv31.Message.VARIABLES, new JSONObject()
.put("objet", " objet")
.put("mailTitle", mailTitle)
.put("body", body))));
}
private JSONArray getRecipientsJson(){
JSONArray json = new JSONArray();
for (String recipient : recipients) {
json.put(new JSONObject()
.put("Email", recipient)
.put("Name", ""));
}
return json;
}
public MailjetResponse sendLoggedMail() throws Exception {
MailjetClient client = new MailjetClient(API_KEY_PUBLIC, API_KEY_PRIVATE, new ClientOptions("v3.1"));
MailjetRequest request = sendEmailCore();
MailjetResponse response = null;
try {
client.setDebug(MailjetClient.VERBOSE_DEBUG);
log.info(request.getBody());
response = client.post(request);
} catch (final MailjetException | MailjetSocketTimeoutException e) {
log.error("sendLoggedMail", e);
}
return response;
}
The MailJet log :
=== HTTP Request ===
POST https://api.mailjet.com/v3.1/send
Accept-Charset:UTF-8
Accept:application/json
user-agent:mailjet-apiv3-java/v4.5.0
Content-Type:application/json
=== HTTP Response ===
Receive url: https://api.mailjet.com/v3.1/send
Status: 400
date:Tue, 01 Sep 2020 08:59:55 GMT
null:HTTP/1.1 400 Bad Request
content-length:177
x-mj-request-guid:0bb2a0ac-849d-4d80-82ed-a10a792e8d19
content-type:application/json; charset=UTF-8
Content:
null
Thank you for your help.
The default value for the connection timeout is too small in version 4.5.0
You can try to set value in client options like this:
new MailjetClient("public", "secret", new ClientOptions(8000));
or just use the newer version, where the default timeout value is set.
I have the same issue with Java Mailjet Client 4.5.0. Downgrading to v4.4.0 this error isn't there.
Related
I am new to using Swagger Codegen so I assume I am doing something completely wrong. I have a remote swagger.json that I am using to generate a java client. Everything works and looks good but the example usages in the readme are not referencing any API key.
I don't have access to the remote API that I am using just trying to create a nice Java SDK for interfacing with it.
This is what I am using to generate the code.
java -jar C:/Development/codegen/swagger-codegen-cli.jar generate
-a "client_id:XXXXXXXXXX,client_secret:YYYYYYYYYYYYY"
-i https://BLAH/swagger/v1/swagger.json -l java
-o C:/Development/workspace/JavaClient
-c C:/Development/workspace/JavaClient/java-genconfig.json
Then the example that get's generated in the read me looks something like this...
public static void main(String[] args) {
BusinessGroupApi apiInstance = new BusinessGroupApi();
Integer businessGroupId = 56; // Integer | The ID of the business group to fetch.
String apiVersion = "1.0"; // String | The requested API version
try {
BusinessGroup result = apiInstance.getBusinessGroupAsync(businessGroupId, apiVersion);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling BusinessGroupApi#getBusinessGroupAsync");
e.printStackTrace();
}
}
Side Note
When I try running the example, I get an error saying
Failed to connect to localhost/0:0:0:0:0:0:0:1:443
Is there some setting that I need to set so it looks for the service at a remote location instead of locally?
EDIT
I realized that I needed to modify their swagger as they might not have everything fleshed out.
Swagger Codegen Version = 2.4.5
swagger.json (Excluded the paths and definitions) I also downloaded thiers locally and added some more info to make it generate more info. I added host, basePath, schemes, consumes, produces, security and securityDefinitions.
{
"swagger": "2.0",
"info": {
"version": "1.0",
"title": "removed"
},
"host": "apitest.removed.com",
"basePath": "/removed/api",
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"security": [
{
"clientId": []
},
{
"clientSecret": []
}
],
"securityDefinitions": {
"clientId": {
"type": "apiKey",
"in": "header",
"name": "client_id"
},
"clientSecret": {
"type": "apiKey",
"in": "header",
"name": "client_secret"
}
}
}
This actually updated the readme to look how I would expect it to look
ApiClient defaultClient = Configuration.getDefaultApiClient();
// Configure API key authorization: client_id
ApiKeyAuth client_id = (ApiKeyAuth) defaultClient.getAuthentication("client_id");
client_id.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//client_id.setApiKeyPrefix("Token");
// Configure API key authorization: client_secret
ApiKeyAuth client_secret = (ApiKeyAuth) defaultClient.getAuthentication("client_secret");
client_secret.setApiKey("YOUR API KEY");
// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
//client_secret.setApiKeyPrefix("Token");
BusinessGroupApi apiInstance = new BusinessGroupApi();
Integer businessGroupId = 56; // Integer | The ID of the business group to fetch.
String apiVersion = "1.0"; // String | The requested API version
try {
BusinessGroup result = apiInstance.getBusinessGroupAsync(businessGroupId, apiVersion);
System.out.println(result);
} catch (ApiException e) {
System.err.println("Exception when calling BusinessGroupApi#getBusinessGroupAsync");
e.printStackTrace();
}
Yet when I plug in my client_id and client_secret and try to run it I get a Exception in thread "main" java.lang.NullPointerException
at removed.Tester.main(Tester.java:18). I think I might have the security definitions not set up correctly.
It's not OAuth but they require a client_id and client_secret to be passed in the header parameters.
EDIT 2
Exception when calling BusinessGroupApi#getBusinessGroupAsync
package.client.ApiException:
at package.client.ApiClient.handleResponse(ApiClient.java:927)
at package.client.ApiClient.execute(ApiClient.java:843)
at package.client.api.BusinessGroupApi.getBusinessGroupAsyncWithHttpInfo(BusinessGroupApi.java:148)
at package.client.api.BusinessGroupApi.getBusinessGroupAsync(BusinessGroupApi.java:133)
at Tester.main(Tester.java:30)
Line 30 -> BusinessGroup result = apiInstance.getBusinessGroupAsync(businessGroupId, apiVersion);
EDIT 3
I enabled debugging with
defaultClient.setDebugging(true);
It looks like it's working but for some reason doesn't like my client_id and client_secret despite them both being the ones I used in postman.
--> GET <removed>/api/api/businessGroups/56?api-version=1.0 HTTP/1.1
Accept: application/json
client_secret: <removed>
client_id: <removed>
User-Agent: Swagger-Codegen/1.0-SNAPSHOT/java
--> END GET
<-- HTTP/1.1 403 (393ms)
Content-Length: 80
Content-Type: application/json
Date: Mon, 10 Jun 2019 20:05:07 GMT
QL-LB-Appliance: <removed>
QL-LB-Pool: <removed>
QL-LB-Server: <removed>
OkHttp-Sent-Millis: <removed>
OkHttp-Received-Millis: <removed>
{ "error": "invalid_client", "description": "wrong client_id or client_secret" }
<-- END HTTP (80-byte body)
Exception when calling BusinessGroupApi#getBusinessGroupAsync
<removed>.client.ApiException:
at <removed>.client.ApiClient.handleResponse(ApiClient.java:927)
at <removed>.client.ApiClient.execute(ApiClient.java:843)
at <removed>.client.api.BusinessGroupApi.getBusinessGroupAsyncWithHttpInfo(BusinessGroupApi.java:148)
at <removed>.client.api.BusinessGroupApi.getBusinessGroupAsync(BusinessGroupApi.java:133)
at Tester.main(Tester.java:32)
I have done some queries to the database and they usually work but when I am trying to do it in the current class, I get the following error:
{"code":403,"success":false,"message":"Forbidden, No token provided"}
Both classes are too long to post here, and thus I think this is all I can provide:
SET_USER_STAR_COUNT = URL + "setUserProfileStars";
JSONObject request_data=new JSONObject();
try
{
request_data.put("newscore",newStars);
} catch (JSONException e)
{
e.printStackTrace();
}
OkHttp3Connection.doOkHttp3Connection("", Services_Url_class.SET_USER_STAR_COUNT, OkHttp3Connection.Request_type.POST, request_data, new OkHttp3Connection.OkHttp3RequestCallback() {
#Override
public void onSuccess(String result, String user_tag) {
System.out.println("oO" + result);
}
#Override
public void onError(String error, String user_tag)
{}
});
And here is the controller:
Router.post('/setUserProfileStars', function (req, res) {
var username = req.decoded.name;
var newStars = req.decoded.newscore;
var response = [];
var addStars = 'MATCH (n:User) WHERE n.username = "' + username + '" SET n.stars = "'+ newStars +'" RETURN n.stars AS totalStars';
dbneo4j.cypher({
query: addStars
}, function (err, data) {
if (err) {
return res.send({
code: 9325,
message: 'error encountered',
error: err
}).status(9325);
}
response.push(data);
res.send({
code: 200,
message: 'success',
data: response
}).status(200);
});
});
If there is anything else I can provide then I will do so.
The error comes when I try to print the result. My question is why is it doing so and how can I debug and check what is wrong with it?
403 Forbidden indicates that the server is refusing to process your request because you are not authorized. According to the message details, the server expects an authorization token to be passed as a header. You will have to work with the server to determine what "token" it expects.
I have designed login module in RESTFul API using jersey.
whenever any error occurred while login it will return error code and message like,
{
"errorFlag": 1,
"errorMessage": "Login Failed"
}
but whenever I get successful results it returns
{
"apiKey": "3942328b-fa65-496c-bf32-910aafbc1b0e",
"email": "caXXXX#gmail.inl",
"name": "Chandrakant"
}
I'm looking for results like below
{
"errorFlag": 0,
"errorMessage":{
"apiKey": "3942328b-fa65-496c-bf32-910aafbc1b0e",
"email": "caXXXX#gmail.inl",
"name": "Chandrakant"}
}
Use structure like below,
{
status/statusCode : 200/400, //eg. 200 for success, any other for failure.
statusMessage : "Success/<failureMessage>",
errorDetails : "Failed due to <reason>" //optional
data :{ //data will exists only in case of success call.
}
}
you can achieve this like below,
#GET
#Path("/images/{image}")
#Produces("image/*")
public Response getImage(#PathParam("image") String image) {
File f = new File(image);
if (!f.exists()) {
throw new WebApplicationException(404);
}
String mt = new MimetypesFileTypeMap().getContentType(f);
return Response.ok(f, mt).build();
}
You can return all the attributes in HashMap as key value .
Below piece of code worked for me
#POST
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public HashMap check(InputStream inputJsonObj) {
HashMap map = new HashMap();
map.put("key1", "value1");
return map;
}
The following thing occours during my use of the Youtube API v3. I request a search to get all my Playlists, but the result contains only 3 of 4, the newest playlist is missing.
But when I try the API in the developer page I get all four playlists.
Developer page:
https://developers.google.com/youtube/v3/docs/playlists/list?hl=fr#try-it
My Request:
https://www.googleapis.com/youtube/v3/playlists?part=id&channelId=UCtEV5D0j6LwV0MqCnZ7H1AA&key={YOUR_API_KEY}
In java application I use the API to do the same, here is my code that delievers only 3 of 4 Playlists:
public int execute(PipelineDictionary dict)
throws PipeletExecutionException
{
// Initialize the search
YouTube.Search.List search = null;
// Response item
SearchListResponse response = null;
// Create the youtube object
YouTube youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, new HttpRequestInitializer() {
public void initialize(HttpRequest request) throws IOException{}}).setApplicationName("GartenXXL").build();
try
{
search = youtube.search().list("id,snippet");
}
catch(IOException e1)
{
throw new PipeletExecutionException("Failure during sending youtube search request");
}
// Set API-Key
search.setKey(cfg_apiKey);
search.setChannelId(cfg_channelId);
// Set Request Query
// search.setQ(queryTerm);
// search.type("playlist"); oder search.type("channel");
search.setType("playlist");
// Set Fields, filters onle the filds that are defined
search.setFields("items(id/playlistId,snippet(title))");
search.setMaxResults(50L);
try
{
response = search.execute();
//System.out.println(response.toPrettyString());
}
catch(IOException e)
{
e.printStackTrace();
}
dict.put(DN_YOUTUBE_LISTS, response);
return PIPELET_NEXT;
}
The resulting Json looks like:
{
"items": [
{
"id": {
"playlistId": "PLWWeimUpYTkhXubzYoPSqetvhCYZocaVj"
},
"snippet": {
"title": "GartenXXL Ratgeber"
}
},
{
"id": {
"playlistId": "PLWWeimUpYTkjCabIwPo0NuvMV_BPkC981"
},
"snippet": {
"title": "Produktvideos - Top-Produkte von GartenXXL"
}
},
{
"id": {
"playlistId": "PLWWeimUpYTkgEBjIryCrqms640yy4D_1d"
},
"snippet": {
"title": "Rasenmäher-Videos"
}
}
]
}
I'm stuck trying to send JSON data to by Struts2 REST server using the struts2-rest-plugin.
It works with XML, but I can't seem to figure out the right JSON format to send it in.
Anybody has any experience with this?
Thanks,
Shaun
Update:
Sorry I wasn't clear. The problem is that Struts2 doesn't seem to be mapping the JSON data I send in to my model in the controller.
Here's the code:
Controller:
public class ClientfeatureController extends ControllerParent implements ModelDriven<Object> {
private ClientFeatureService clientFeatureService;
private ClientFeature clientFeature = new ClientFeature();
private List<ClientFeature> clientFeatureList;
//Client ID
private String id;
public ClientfeatureController() {
super(ClientfeatureController.class);
}
#Override
public Object getModel() {
return (clientFeatureList != null ? clientFeatureList : clientFeature);
}
/**
* #return clientFeatureList through Struts2 model-driven design
*/
public HttpHeaders show() {
//logic to return all client features here. this works fine..
//todo: add ETag and lastModified information for client caching purposes
return new DefaultHttpHeaders("show").disableCaching();
}
// PUT request
public String update() {
logger.info("client id: " + clientFeature.getClientId());
logger.info("clientFeature updated: " + clientFeature.getFeature().getDescription());
return "update";
}
public HttpHeaders create() {
logger.info("client id: " + clientFeature.getClientId());
logger.info("feature description: " + clientFeature.getFeature().getDescription());
return new DefaultHttpHeaders("create");
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public void setClientFeatureService(ClientFeatureService clientFeatureService) {
this.clientFeatureService = clientFeatureService;
}
public List<ClientFeature> getClientFeatureList() {
return clientFeatureList;
}
public void setClientFeatureList(List<ClientFeature> clientFeatureList) {
this.clientFeatureList = clientFeatureList;
}
public ClientFeature getClientFeature() {
return clientFeature;
}
public void setClientFeature(ClientFeature clientFeature) {
this.clientFeature = clientFeature;
}
}
This is the URL I'm making the request to:
..http://localhost:8080/coreserviceswrapper/clientfeature.json
-Method: POST or PUT (tried both, POST maps to create() and PUT maps to update())
-Header: Content-Type: application/json
Payload:
{"clientFeature":{
"feature": {
"id": 2,
"enabled": true,
"description": "description1",
"type": "type1"
},
"countries": ["SG"],
"clientId": 10}
}
And the output in the Struts2 logs when I make the request:
1356436 [http-bio-8080-exec-5] WARN net.sf.json.JSONObject - Tried to assign property clientFeature:java.lang.Object to bean of class com.foo.bar.entity.ClientFeature
1359043 [http-bio-8080-exec-5] INFO com.foo.bar.rest.ClientfeatureController - client id: null
Let me also add that XML requests work just fine:
URL: ..http://localhost:8080/coreserviceswrapper/clientfeature.xml
Method: POST/PUT
Content-Type: text/xml
Payload:
<com.foo.bar.entity.ClientFeature>
<clientId>100</clientId>
<feature>
<description>test</description>
</feature>
</com.foo.bar.entity.ClientFeature>
Output:
1738685 [http-bio-8080-exec-7] INFO com.foo.bar.rest.ClientfeatureController - client id: 100
1738685 [http-bio-8080-exec-7] INFO com.foo.bar.rest.ClientfeatureController - feature description: test
1738717 [http-bio-8080-exec-7] INFO org.apache.struts2.rest.RestActionInvocation - Executed action [/clientfeature!create!xml!200] took 1466 ms (execution: 1436 ms, result: 30 ms)
I also encounter same issue, my environment is:
Structs 2.3.16.3, Jquery 1.11, Struts-rest-plugin
symptom: post json data, rest controller not parse json data to model.
solution:
since the controller is modeldriven, browser client just post Json string is OK. but seems you have to force jquery to change conenttype of ajax call.
_self.update= function(model, callback) {
$.ajax({
beforeSend: function(xhrObj){
xhrObj.setRequestHeader("Content-Type","application/json");
xhrObj.setRequestHeader("Accept","application/json");
},
type: 'PUT',
url: this.svrUrl+"/"+ model.id + this.extension,
data: JSON.stringify(model), // '{"name":"' + model.name + '"}',
//contentType: this.contentType,
//dataType: this.dataType,
processData: false,
success: callback,
error: function(req, status, ex) {},
timeout:60000
});
};
the model data format is :
var model = {"id":"2",
"name":"name2",
"author":"author2",
"key":"key2"
}
when you put or post data whit "Content-Type"="application/json", the plugin will handle it with Jsonhandler automatically.
I got such a problem. Strange but got solved by changing the name 'clientFeature' to 'model'