This article is relevant if you wish to connect to NetSuite RESTLET technology using token-based authentication (TBA) using Java as a client.
Background
In general, my team and I perform NetSuite REST and Web Services development using the Postman http test utility. However, we have found that Postman may have challenges with OAuth 1.0 backing NetSuite’s token-based authentication. Even when using Postman, you may find that even after knowing you have your credentials right, it still may be challenging to craft the HTTP oAuth 1.0 headers in the client programming environment.
As discussed in my article, Download a NetSuite OAuth Token Based Authentication Sample Node.js Program, I offered a way to connect and test your Token-Based Authentication client using Node.js. This article offers effectively the same solution but instead uses Java.
Addendum July 21, 2019 and June 17, 2022
The program required some maintenance from the original work. In addition, NetSuite now requires SHA256 to connect. We have updated the latest code for these signatures.
The article has been updated to reflect the latest efforts.
NetSuite Java Class to Connect to REST
Here is the Java Class that will connect up to a NetSuite RESTLet service. It leverages the utilities of the scribejava open source framework. Below, I offer the source code.
package com.prolecto.sample.restlet.client; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.scribejava.core.builder.ServiceBuilder; import com.github.scribejava.core.builder.api.DefaultApi10a; import com.github.scribejava.core.model.OAuth1AccessToken; import com.github.scribejava.core.model.OAuth1RequestToken; import com.github.scribejava.core.model.OAuthRequest; import com.github.scribejava.core.model.Response; import com.github.scribejava.core.model.Verb; public class App { private static Logger log = LoggerFactory.getLogger(App.class); private final String CONSUMER_KEY; private final String CONSUMER_SECRET; private final String TOKEN_KEY; private final String TOKEN_SECRET; private final String ACCOUNT_ID; private final String RESTLET_URL; private final URI DOMAIN_URI; private ObjectMapper mapper = new ObjectMapper(); private HttpClient httpClient = HttpClient.newBuilder().build(); public App() throws IOException { Properties nsProp = new Properties(); nsProp.load(getClass().getClassLoader().getResourceAsStream("ns.properties")); CONSUMER_KEY = nsProp.getProperty("ns.consumerKey"); CONSUMER_SECRET = nsProp.getProperty("ns.consumerSecret"); TOKEN_KEY = nsProp.getProperty("ns.tokenKey"); TOKEN_SECRET = nsProp.getProperty("ns.tokenSecret"); ACCOUNT_ID = nsProp.getProperty("ns.accountId"); RESTLET_URL = nsProp.getProperty("ns.restletUrl"); DOMAIN_URI = URI.create("https://rest.netsuite.com/rest/datacenterurls?account=" + ACCOUNT_ID); } private Domains getDomains(String realm) throws Exception { HttpRequest request = HttpRequest.newBuilder().uri(DOMAIN_URI).build(); HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString()); return mapper.readValue(response.body(), Domains.class); } public static void main(String[] args) throws Exception { log.info("Test: NetSuite Token Based Authentication..."); new App().doEcho(); log.info("Test: Done!"); } public String doEcho() throws Exception { String dataCenterRest = getDomains(ACCOUNT_ID).getRestDomain(); log.debug("RestDataCenter: {}", dataCenterRest); try (var auth10aService = new ServiceBuilder(CONSUMER_KEY).apiSecret(CONSUMER_SECRET).build(new NSApi())) { OAuthRequest request = new OAuthRequest(Verb.POST, dataCenterRest + RESTLET_URL); request.setRealm(ACCOUNT_ID); request.addHeader("Content-Type", "application/json"); request.setPayload(mapper.writeValueAsString(Map.of("greetings", "Hello World"))); log.debug("Request : {}", request.getStringPayload()); auth10aService.signRequest(new OAuth1AccessToken(TOKEN_KEY, TOKEN_SECRET), request); Response response = auth10aService.execute(request); log.debug("Response : {}", response.getBody()); return response.getBody(); } } } class NSApi extends DefaultApi10a { private static Logger log = LoggerFactory.getLogger(App.class); @Override public String getRequestTokenEndpoint() { log.debug("getRequestTokenEndpoint"); return null; } @Override public String getAccessTokenEndpoint() { log.debug("getAccessTokenEndpoint"); return null; } @Override public String getAuthorizationUrl(OAuth1RequestToken requestToken) { log.debug("getAuthorizationUrl: " + requestToken.getRawResponse()); return null; } @Override protected String getAuthorizationBaseUrl() { log.debug("getAuthorizationBaseUrl"); return null; } } class Domains { private String webservicesDomain; private String restDomain; private String systemDomain; public String getWebservicesDomain() { return webservicesDomain; } public void setWebservicesDomain(String webservicesDomain) { this.webservicesDomain = webservicesDomain; } public String getRestDomain() { return restDomain; } public void setRestDomain(String restDomain) { this.restDomain = restDomain; } public String getSystemDomain() { return systemDomain; } public void setSystemDomain(String systemDomain) { this.systemDomain = systemDomain; } }
Download Java Client TBA Program to Connect to NetSuite REST Services
You can download this program here. To run the program, assuming you have Java 11 SDK installed, change to the base directory of the unzipped program and enter “gradlew run” (linux) or “gradlew.bat run” (windows) to have the program compile and execute. If you do not have the gradle framework on your machine, the software should first install and then you can run the program again. See the related image for what it looks like to succeed.
Work with Fellow NetSuite Experts
My goal in this article was to help fellow NetSuite software developers lower the learning curve to more quickly become productive. If you have perused a number of our articles, you have found that we love inventing with the NetSuite platform. If you have passion for NetSuite as we do, perhaps you can join our team so we can help each other bring innovation to the community.
Two thumbs up! Thank you for code sharing.
I wish NetSuite would be implementing OAuth 2.0, but according to enhancement requests, NetSuite is not considering this at present or in the near future.
Looks the URL has changed, am trying to test your code and am getting below error.
Test: NetSuite Token Based Authentication…
PAYLOAD:
{“message” : “Hello World”}
RESULT:
{“error” : {“code” : “INVALID_DATA_CENTER”, “message” : “Incorrect data center requested! The data center you are requesting is not the data center where your account is hosted. To obtain the correct URL for your request, please use the following endpoint: https://rest.netsuite.com/rest/datacenterurls?account=TSTDRV1030358. Then, send your original request to the correct data center.”}}
Test: Done!
Indeed, it looks like the code needs some maintenance. We will look into it.
Marty
When i am using TBA with webservice integration it is working but when I use TBA with above code i am getting below message:
error code: INVALID_LOGIN_ATTEMPT
error message: Invalid login attempt.
Can you please help me in solving this?
Thanks in Advance!!
Hello Rohan,
We see the issue. We will create a revised version and update the article. Standby. (Marty’s reference PTM3745)
Marty
Hello Rohan,
We finished the code maintenance and I have updated the article. Thanks for helping us out.
Marty
Robert,
The code should be working now. We have updated the article.
Marty
We were using scribe 1.3.7 in and Android eclipse project. This has version of scribe has stopped working for Android API 28. Do you know if there is a jar file for the newer version of scribe?
Hello Marty,
Does this work if I’m trying to connect using SHA256 signature
This Java applet will need to be updated to work with SHA256.
Marty
Hello Marty,
I am having the same issue connecting using the SHA256 signature. I know you mentioned the code being updated, just curious if it has been and if it has been if I could get a copy.
Best, Logan
Hello Logan,
We just updated the article and the latest build now connects with the SHA256 signature. Here is the reference to the code:
https://blog.prolecto.com/wp-content/uploads/2022/06/java-restlet-client-20220422.zip
Marty