Junit testing with Apache HttpClient - java

I am writing a Junit test with apache httpclient. The testCreate method successfully insert a record to the database but the status return is 500 which make the test case to fail.
Below is the test case,
public void testCreate() throws Exception {
String url = "http://localhost:8080/mediaactivity/videoAssignment";
HttpPost request = new HttpPost(url);
request.addHeader("Content-Type", "application/json");
request.addHeader("xAuthorization", "123");
request.addHeader("correlationId", "123");
String json = "{"+
"\"VideoType\": \"Sample\","+
"\"groupType\": \"INDIVIDUAL\","+
"\"submissionMethod\": \"test\","+
"\"title\": \"test me\""+
"}";
StringEntity entity = new StringEntity(json);
request.setEntity(entity);
// When
HttpResponse httpResponse = HttpClientBuilder.create().build().execute(request);
// Then
assertThat(httpResponse.getStatusLine().getStatusCode(), equalTo(HttpStatus.SC_CREATED));
}
The controller looks like,
#RequestMapping(value = "/videoAssignment", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE, method = RequestMethod.POST)
#ResponseBody
public HttpEntity<VideoAssignment> createVideoAssingnment(
//#ApiParam are there..){
//other methods
return new ResponseEntity<>(va, HttpStatus.CREATED);
}
what i am missing here?

Related

Quarkus multipart client without use form field

I want to write a rest client for old code, which as I understand it accepts multipart.
My client is written in quarkus and uses resteasy-multipart-provider
I have old code which I want to call with:
#POST
#Path("/upload")
#Produces(MediaType.APPLICATION_JSON)
public Response addFiles(#Context HttpServletRequest request, #Context ServletContext context)
{
try
{
File repository = (File) context.getAttribute("javax.servlet.context.tempdir");
DiskFileItemFactory factory = Utils.getDiskFileItemFactory(context, repository);
factory.setRepository(repository);
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("UTF-8");
List<FileItem> items = upload.parseRequest(request);
for (FileItem item: items)
{
if (!item.isFormField())
{
....
}
}
.....
}
And my client:
#Path("/upload")
#RegisterRestClient(configKey = "scannedimage")
#ClientHeaderParam(name = "Authorization", value = "{lookupAuth}")
public interface UploadClient extends BearerAuthorizedHeader {
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.MULTIPART_FORM_DATA)
Response upload(#MultipartForm UploadBody data);
}
public class UploadBody {
#FormParam("objectId")
#PartType(MediaType.TEXT_PLAIN)
public Long long1;
#FormParam("entityId")
#PartType(MediaType.TEXT_PLAIN)
public Long long2;
#FormParam("doctype")
#PartType(MediaType.TEXT_PLAIN)
public Long documentType;
#FormParam("file")
#PartFilename("{file.getName}")
#PartType(MediaType.APPLICATION_OCTET_STREAM)
public File file;
}
Response always return emty list
{
"lon1": 1,
"long2": 2,
"list": [],
"error": ""
}
what am I doing wrong
I have a valid request example creating using org.apache.httpcomponents:httpmime
HttpEntity entity = MultipartEntityBuilder.create().addTextBody("long1", "1").addTextBody("long2", "2499").addTextBody("doctype", "3306").addBinaryBody("file", file, ContentType.create("application/octet-stream"), "test.pdf").build();
HttpPost httpPost = new HttpPost("http://serviece/upload");
httpPost.setEntity(entity);
httpPost.setHeader("Authorization", "Bearer token");
HttpResponse response = httpClient.execute(httpPost);
HttpEntity result = response.getEntity();
System.out.println(EntityUtils.toString(result));
But I would like to implement it with rest-client, if it possible
As a result. I used org.apache.httpcomponents:httpmime:4.5.3 and writed method:
public UploadResponse upload(String long1, String long2, String documentType, String fileName, InputStream file) {
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
HttpEntity entity = MultipartEntityBuilder
.create()
.addTextBody("long1", long1)
.addTextBody("long2", long2)
.addTextBody("documentType", documentType)
.addBinaryBody("file", file, ContentType.create(MediaType.APPLICATION_OCTET_STREAM), fileName)
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.setCharset(StandardCharsets.UTF_8)
.build();
HttpPost httpPost = new HttpPost(url + "/upload");
httpPost.setEntity(entity);
httpPost.setHeader("Authorization", "Bearer " + token());
HttpResponse response = httpClient.execute(httpPost);
return objectMapper.readValue(response.getEntity().getContent(), UploadResponse.class);
} catch (IOException e) {
log.error("Error create httpClient", e);
}
return new UploadResponse();
}
Because i can't finded like through resteasy-multipart-provider add file name to file FormParam :(.
Maybe it's fix next version quarkus or restEasy

How can I make a Put rest call along with POJO using RestTemplate

How can I make a PUT request to a rest service using RestTemplate, so that I get a response also.
The rest service I have to call is:
#RequestMapping(value = /forgotpassword, method = RequestMethod.PUT, produces = "application/json")
public SuccessResponse resetUserPassword(#RequestBody ResetPasswordDTO resetPasswordDTO) throws GenericException {
logger.info("--->reset Password");
return new SuccessResponse(userservice.resetUserPassword(resetPasswordDTO));
}
I need to send one POJO also which has two String properties.
The method put of RestTempalte in (Spring)[https://spring.io/] has no return,so if your want get response from server,please try use POST method.I modify your code like this:
In server side:
#RequestMapping(value = "/forgotpassword", method = RequestMethod.POST, produces = "application/json")
public ResponseEntity<SuccessResponse> resetUserPassword(#RequestBody ResetPasswordDTO resetPasswordDTO) throws Exception {
log.info("--->reset Password");
SuccessResponse response = new SuccessResponse();
response.setName(resetPasswordDTO.getUsername());
response.setMessage("success");
return new ResponseEntity<SuccessResponse>(response, HttpStatus.OK);
}
In client side you can use RestTemplate do a request:
ResetPasswordDTO request = new ResetPasswordDTO();
request.setPasswork("Huawei#123");
request.setUsername("c00382802");
ResponseEntity<SuccessResponse> response =template.postForEntity("http://localhost:8080//forgotpassword",request,SuccessResponse.class);
System.out.println(response.getBody().toString());
More info you can get from (Spring)[https://spring.io/]
For PUT use RestTemplate.exchange() method
Example
MyJaxbRequestDataObjectrequest = createMyJaxbRequestDataObject();
Map<String, String> uriArguments= createUriArguments();
String url = restBaseUrl + "/myputservice/{usertId}?servicekey={servicekey}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<MyJaxbRequestDataObject> entity = new HttpEntity<MyJaxbRequestDataObject>(request, headers);
ResponseEntity<MyJaxbResponseDataObject> responseWrapper = shogunRestTemplate.exchange(url, HttpMethod.PUT, entity, MyJaxbResponseDataObject.class, uriArguments);
MyJaxbResponseDataObjectresponse = responseWrapper.getBody();

Consuming HTTP POST method which is secured with Basic Auth in spring

I want to consume a post method which is secured using basicAuth. I am using springBoot, Spring RestTemplate to consume it.
I've tried like this:
#CrossOrigin(origins = "*", maxAge = 3600)
#RequestMapping(value = "/ValidateAnswers", method = RequestMethod.POST)
public ResponseEntity<String> ValidateAnswers(#RequestBody Object requestIbject,
HttpServletRequest request, HttpServletResponse response) {
final String uri = "foo:8080//validateAnswers";
// hiding full path here,
RestTemplate restTemplate = new RestTemplate();
String plainClientCredentials = "user:pass";
String base64ClientCredentials = new String(
Base64.encodeBase64(plainClientCredentials.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64ClientCredentials);
HttpEntity<String> entity = new HttpEntity<String>("parameters",
headers);
ResponseEntity<String> respEntity = restTemplate.postForObject(uri, requestIbject, String.class);
// .exchange(uri,
// HttpMethod.POST, entity, String.class);
System.err.println("=------------Response--------------");
System.err.println("----" + respEntity);
return respEntity;
}
How do I pass the headers with basicAuth and post request body ?
if you using spring > 4.3.1
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));
From your code snippets I don't think you should use post method, try get first. And refer to my previous test:
public class Test {
private HttpHeaders getHeaders(){
String plainCredentials="admin:admin";
String base64Credentials = Base64.getEncoder().encodeToString(plainCredentials.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Credentials);
return headers;
}
#Test
public void testLogin() {
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<String>(getHeaders());
ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/login", HttpMethod.GET,
request, String.class);
System.out.println(response.getBody());
}
}

How to do GET API Request with URL params?

Client client = ClientBuilder.newClient();
urlApi="https://localhost:123/demo/api/v1/rows/search?";
WebTarget webTarget = client.target(urlApi);
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
webTarget.queryParam(entry.getKey(), entry.getValue());
}
webTarget.queryParam("searchConditions",webTarget.queryParam("mobileNo","+9999999999"));
Invocation.Builder builder = webTarget.request();
builder.header("id", "ABC");
String asB64 = Base64.getEncoder().encodeToString("ABC:PWD".getBytes("utf-8"));
logger.debug("Calling API "+urlApi);
builder.header("Authorization", "Basic "+asB64);
builder.header("Content-type", MediaType.APPLICATION_JSON);
response = builder.get();
responseData = response.readEntity(String.class);
System.out.println(responseData);
I am trying to do GET request with searchCondition as Key and value as {mobileNo="+919999999999"}, I am unable to get this to work.
Apart from that, how can I print the Request "Headers" along with "Query params"? Thank you in advance
I think you need to encode the value inputs, something like this:
webTarget.queryParam("searchCondition", URLEncoder.encode("{mobileNo=\"+919999999999\"}", StandardCharsets.UTF_8.toString()));
UDPATE:
Example of the rest client with Spring:
#Test
public void testStack() throws Exception {
RestTemplate rest = new RestTemplate();
String fooResourceUrl="http://localhost:8080/usersParam?";
RestTemplate restTemplate = new RestTemplate();
String parameter = "{mobileNo=\"+919999999999\"}";
ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "parameter=" + URLEncoder.encode(parameter, StandardCharsets.UTF_8.toString() ), String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
And this would be the rest service:
#RequestMapping(method = RequestMethod.GET, value="/usersParam")
public User getUsersInfo(#RequestParam String parameter) throws UnsupportedEncodingException {
System.out.println(URLDecoder.decode(parameter, StandardCharsets.UTF_8.toString() ));
return null;
}

Rest Api call gives error 400 using Spring Oauth2

I'm building a rest API using Spring security Oauth2 to secure it.
The following curl command runs succesfully and I get the token:
curl -X POST -vu clientapp:123456 http://localhost:8080/dms-application-0.0.1-SNAPSHOT/oauth/token -H "Accept: application/json" -d "password=spring&username=roy&grant_type=password&scope=read%20write&client_secret=123456&client_id=clientapp"
The following test to get the token also runs succesfully:
#Test
public void getAccessToken() throws Exception {
String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
String contentType = MediaType.APPLICATION_JSON + ";charset=UTF-8";
// #formatter:off
String content = mvc
.perform(
post("/oauth/token")
.header("Authorization", authorization)
.contentType(
MediaType.APPLICATION_FORM_URLENCODED)
.param("username", "roy")
.param("password", "spring")
.param("grant_type", "password")
.param("scope", "read write")
.param("client_id", "clientapp")
.param("client_secret", "123456"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.access_token", is(notNullValue())))
.andExpect(jsonPath("$.token_type", is(equalTo("bearer"))))
.andExpect(jsonPath("$.refresh_token", is(notNullValue())))
.andExpect(jsonPath("$.expires_in", is(greaterThan(4000))))
.andExpect(jsonPath("$.scope", is(equalTo("read write"))))
.andReturn().getResponse().getContentAsString();
// #formatter:on
String token= content.substring(17, 53);
}
However, when calling the rest end point externally from a webapp using Spring RestTemplate gives me a http error 400.
Below the code:
#RequestMapping(value = "/authentication", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity authenticate(#RequestBody CredentialsDto credentials) {
try {
String email = credentials.getEmail();
String password = credentials.getPassword();
String tokenUrl = "http://" + env.getProperty("server.host") + ":8080" + "/dms-application-0.0.1-SNAPSHOT" + "/oauth/token";
// create request body
JSONObject request = new JSONObject();
request.put("username", "roy");
request.put("password", "spring");
request.put("grant_type","password");
request.put("scope","read write");
request.put("client_secret","123456");
request.put("client_id","clientapp");
// set headers
HttpHeaders headers = new HttpHeaders();
String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));
String contentType = MediaType.APPLICATION_FORM_URLENCODED.toString();
headers.set("Authorization",authorization);
headers.set("Accept","application/json");
headers.set("Content-Type",contentType);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restClient.exchange(tokenUrl, HttpMethod.POST, entity, String.class);
// restClient.postForEntity(tokenUrl,entity,String.class,)
if (loginResponse.getStatusCode() == HttpStatus.OK) {
//JSONObject userJson = new JSONObject(loginResponse.getBody());
String response = loginResponse.getBody();
return ResponseEntity.ok(response);
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
// nono... bad credentials
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
return null;
}
And the error I get:
"Missing grant type"
Any ideas of what can be wrong or any other ways to do it? Because I'm completely stuck on this.
Thank you
Try to do it like this:
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("username", "roy");
map.add("password", "spring");
map.add("grant_type", "password");
map.add("scope", "read write");
map.add("client_secret","123456");
map.add("client_id","clientapp");
HttpEntity request = new HttpEntity(map, headers);
One more thing, when you ask for a token make sure not to send a json request, but with this header:
headers.add("Content-Type", "application/x-www-form-urlencoded");

Categories