Spring 4 Restfull Service with bean - rest

I am trying to create a simple Server / Client application that can send a bean as parameter instead of String but failing below is my code
Server
#Controller
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping(method=RequestMethod.POST,value="/returnGreet")
public #ResponseBody Greeting returnGreet(
#RequestBody(required=false) Greeting greet) {
if(greet == null)
return new Greeting(counter.incrementAndGet(),
String.format(template, greet));
else
return new Greeting(0,"Testing");
}
}
Client
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String,Greeting> greet = new LinkedMultiValueMap<String, Greeting>();
greet.add("greet", new Greeting(0,"XOXO"));
greeting = restTemplate.postForObject("http://localhost:8080/returnGreet",greet, Greeting.class,greet);
System.out.println("Content: " + greeting.getContent());
System.out.println("Id: " + greeting.getId() );
The result is always null for the object greet at the server side.
Any Idea ?

You're not using the RestTemplate correctly. Why are you passing a MultiValueMap as the Entity to be sent? This won't get serialized the way your Server expects.
Just use the Greeting object directly.
restTemplate.postForObject("http://localhost:8080/returnGreet", new Greeting(0, "XOXO"), Greeting.class);
Also, the last argument is not necessary, you don't have any URI variables.

Related

HTTP request doesn't work with a paricular rest

I'm making an application filled with various rest services, so I create a one-for-all HTTP class in order to allow a client application to keep asking information, via rest, to a server application
public HttpURLConnection HTTPSENDJSON(String urlAPI,String out,String requestmethod) throws IOException {
URL url = new URL(urlAPI);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestMethod(requestmethod);
conn.setDoOutput(true);
conn.setDoInput(true);
OutputStream os = conn.getOutputStream();
System.out.println(out);
os.write(out.getBytes());
os.flush();
os.close();
return conn;
urlAPI is the desired URL, a string is the JSON string (I'm using GSON) and the requestmethod is a string in order to switch from PUT\POST\GET\PATCH.
So, as I wrote, it's all ok if I need to retrieve information from DB\insert a new record
ATM my Client application makes a call to the server who calls an EJB in order to CRUD the information.
this is the Client method who call the upper method (the HTTPSENDJSON )
public String modifica() throws IOException {
Universal_HTTPREQUEST httprequest = new Universal_HTTPREQUEST();
String url= "http://localhost:8080/ModuloWebClientNuovo/rest/clientela/modifica/account/"+ac.getId()+"";
Gson g = new Gson();
String out=g.toJson(ac, Account.class);
httprequest.HTTPSENDJSON(url, out,"PUT");
and this is the working (at least with POSTMAN) services
#PUT
#Path("modifica/account/{id}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response modificaaccount(#PathParam("id") int id,Account a) {
System.out.println("i'm inside the api and i wrote: "+ a.toString());
ac.updateAccount(a);
return Response.status(200).entity(a).build() ;
}
The Client doesn't even make the call to the server, BUT the only with this specific rest, other works fine.
update account EJB is:
#Stateless
public class AccountEJB implements IAccountCrud {
#EJB
Iconnessioni x;
#Override
public void updateAccount(Account account) {
EntityManager entityManager=x.apriconnessione();
entityManager.merge(account);
x.chiudiconnessione(entityManager);
}
}
Fixed whit a new from scratch wildfly

Mocking an autowired field using mockito gives null response in rest call

I am using spring boot and mockito. I have autowired one class i.e, BDSRequest and in Junit Test class, i have used #Spy and #InjectMocks annotations. but while calling rest services in Junits, i am getting response (bdsCustomerHoldings) as null and assertion is failing. How to test this rest call with out mocking rest template like mockito.when(restTemplate.postForObject(Constants.BDS_REST_URL, bdsRequest,
BDSCustomerHoldings.class) ?
class BDSRestCall
{
#Autowired
BDSRequest bdsRequest;
public BDSCustomerHoldings getBDSCustomerInfo(String channelId, String customerId, String cinSuffix,
String countryCode) {
logger.info("prepareRequestForBDS");
Header header = new Header();
header.setMsgId(RandomStringUtils.randomAlphanumeric(20));
header.setChannelId(channelId);
header.setCountryCode(countryCode);
header.setRecordTimeStamp(DateTimeFormatter.ofPattern(Constants.DATE_FORMATTER).format(LocalDateTime.now()));
TxnRequest txnRequest = new TxnRequest();
txnRequest.setIdDoc(customerId);
txnRequest.setIdDocSuffix(cinSuffix);
txnRequest.setIdDoctype("");
txnRequest.setInsurerCode("");
bdsRequest.setHeader(header);
bdsRequest.setTxnRequest(txnRequest);
logger.info("BDS request " + bdsRequest);
BDSCustomerHoldings bdsResponse = restTemplate.postForObject(Constants.BDS_REST_URL, bdsRequest,
BDSCustomerHoldings.class);
logger.info("BDS Response : " + bdsResponse);
return bdsResponse;
}
}
Junit:
#RunWith(MockitoJUnitRunner.class)
class BDSRestCallTest
{
#InjectMocks
private BDSRestCall bdsRestCall;
#Mock
private RestTemplate restTemplate;
#Spy
private BDSRequest bdsRequest;
#Test
public void getBDSCustomerInfoExceptionTest() {
BDSCustomerHoldings bdsCustomerHoldings = bdsRestCall.getBDSCustomerInfo("SG", "S9718016D",
"00", "SG");
System.out.println("response is " + bdsCustomerHoldings);
assertNotNull("response is not null", bdsCustomerHoldings);
}
}
As we are using #RunWith(MockitoJUnitRunner.class), then we should use mocking the response of restTemplate like below
Mockito.when(restTemplate.postForObject(Mockito.anyString(), bdsRequest, BDSCustomerInsuranceHoldings.class)).thenReturn(sampleBDSCustomerInsuranceHoldings());
Then it will give mock response.

Invoking Camel Rest services gives me 401 using restlet

I am trying write a route to call a restful services. all of them donot have a body but query parameters. when i call(https) the rest service i get 401(unauthorised).
but if i use simple non-ssl (http) and invoke it works fine on other apis.
here is my Route and producer template.
Route
public static final String MONITOR_URI = "https://lsapi.thomson-pharma.com//ls-api-ws/ws/rs/opportunity-v1/match?drug=bevacizumab&company=Genentech Inc&fmt=json";
public static final String DIRECT_MONITOR = "direct:getDrugInfo";
from(DIRECT_MONITOR).to(MONITOR_URI).convertBodyTo(String.class);
=========================Main Class===============================
public static void main(String[] args) throws Exception {
CamelContext context = createCamelContext();
context.start();
final String text = "paracetamol";
final String fmt = "json";
final String authMethod = "Digest";
final String authUsername = "TR_Internal_024";
final String authPassword="ZTYA5S1KLF7WCDMN";
final String query = String.format("text=%s&fmt=%s&authMethod=%s&authUsername=%s&authPassword=%s",text,fmt,authMethod,authUsername,authPassword);
Map<String,Object> headers = new HashMap<String, Object>(){
{
put(Exchange.HTTP_METHOD,"POST");
put(Exchange.AUTHENTICATION,"Digest");
put("authUsername","TR_Internal_024");
put("authPassword","ZTYA5S1KLF7WCDMN");
put(Exchange.HTTP_QUERY,query);
}
};
ProducerTemplate template = context.createProducerTemplate();
String request = template.requestBodyAndHeaders(Constants.DIRECT_MONITOR,null,headers,String.class);
System.out.println("Body is : "+request);
}
Can someone help how to configure SSL using camel cxf or restlet ?
How do i add Credentials Provider to CamelContext or Spring Context ?
APologies for the delay. i got it worked by retriving the component from camelContext below is the code.
=========================================================================
HttpComponent http = (HttpComponent) camelContext.getComponent("https");
HttpClientConfigurer httpClientConfigurer = http.getHttpClientConfigurer();
if(httpClientConfigurer == null){
System.out.println("httpClientConfigurer is null");
if(http.getHttpClientConfigurer() == null ){
HttpConfiguration httpConfiguration = new HttpConfiguration();
httpConfiguration.setAuthMethod(AuthMethod.Digest);
httpConfiguration.setAuthUsername("xxxxx");
httpConfiguration.setAuthPassword("xxxxxx");
http.setHttpConfiguration(httpConfiguration);
}
}
Regards
Ram

Jersey client. MultivaluedMap goes empty

My RESTful client has this method:
public void testGetCateogrywiseData() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new LoggingFilter(System.out));
WebResource service = client
.resource("http://localhost:8080/MyApp/rest/publicdata");
#SuppressWarnings("rawtypes")
MultivaluedMap queryParams = new MultivaluedMapImpl();
queryParams.add("latitude", "18.522387");
queryParams.add("longitude", "73.878437");
queryParams.add("categoryID", "2");
service.queryParams(queryParams);
ClientResponse response = service.get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println("Form response " + response.getEntity(String.class));
}
On the server side the method looks like this:
#Path("publicdata")
#GET
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String getPublicData() throws JSONException {
MultivaluedMap<String, String> valueMap = uriInfo.getQueryParameters();
Long latString = Long.parseLong(valueMap.getFirst("latitude"));
Long lonString = Long.parseLong(valueMap.getFirst("longitude"));
Long categoryId = Long.parseLong(valueMap.getFirst("categoryID"));
// Do necessary stuff and return json string
return null;
}
My problem is the valueMap at the server end is always empty. It never gets the three parameters that I have sent from the client code. What am I missing?
The problem happens on this line:
service.queryParams(queryParams);
It successfully adds the query params, but it does not change the original service, it returns a new one to you. To make it work you need to change to this:
service = service.queryParams(queryParams);

begin array but was string GSON

I have a Web Service REST :
#Path("/Vehicles")
public class Vehicles{
#GET
#Path("/Cars")
#Produces(aplicattion/json)
public String Cars() {
Car[] cars = Consulting my database...
Gson gson = new Gson();
return gson.toJson(cars);
}
I consume the web service:
try {
HttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://localhost:8080/Concessionaire/rest/Vehicles/Cars");
HttpResponse resp = httpClient.execute(get);
String respGET = EntityUtils.toString(resp.getEntity());
Gson gson = new Gson();
Cars[] c = gson.fromJson(respGET,Cars[].class);
}catch(Exception e){
}
But appears this exception: Expected BEGIN_ARRAY but was String at line 1 colum 6
What is the problem ?
Your method returns a String
public String Cars()
The client code expects a Car array
Cars[] c = gson.fromJson(respGET,Cars[].class);
Gson expects the BEGIN_ARRAY event while parsing the json but instead finds a String. To fix it, send a Cars[] using the jersey Response class and change the return type to Response.
return Response.ok(myCarsArray).build();