I have a REST endpoint as
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getVariables(#QueryParam("_activeonly") #DefaultValue("no") #Nonnull final Active active) {
switch(active){
case yes:
return Response.ok(VariablePresentation.getPresentationVariables(variableManager.getActiveVariables())).build();
case no:
return Response.ok(VariablePresentation.getPresentationVariables(variableManager.getVariables())).build();
}
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
Which returns JSON of List of VariablePresentation. The VariablePresentaion looks like
#XmlRootElement
public class VariablePresentation {
private final UUID id;
private final String name;
private final VariableType type;
public VariablePresentation(#Nonnull final Variable variable) {
id = variable.getId();
name = variable.getName();
type = variable.getType();
}
public String getId() {
return id.toString();
}
#Nonnull
public String getName() {
return name;
}
#Nonnull
public VariableType getType() {
return type;
}
annotated with JAXB's XmlRoot to return JSON.
My integration test is as following
#Test
public void testGetAllVariablesWithoutQueryParamPass() throws Exception {
final ClientRequest clientCreateRequest = new ClientRequest("http://localhost:9090/variables");
final MultivaluedMap<String, String> formParameters = clientCreateRequest.getFormParameters();
final String name = "testGetAllVariablesWithoutQueryParamPass";
formParameters.putSingle("name", name);
formParameters.putSingle("type", "String");
formParameters.putSingle("units", "units");
formParameters.putSingle("description", "description");
formParameters.putSingle("core", "true");
final ClientResponse<String> clientCreateResponse = clientCreateRequest.post(String.class);
assertEquals(201, clientCreateResponse.getStatus());
}
I want to test the request body which returns the List<VariablePresentation> as String. How can I convert the response body (String) as VariablePresentation Object?
Update
After adding the following
final GenericType<List<VariablePresentation>> typeToken = new GenericType<List<VariablePresentation>>() {
};
final ClientResponse<List<VariablePresentation>> clientCreateResponse = clientCreateRequest.post(typeToken);
assertEquals(201, clientCreateResponse.getStatus());
final List<VariablePresentation> variables = clientCreateResponse.getEntity();
assertNotNull(variables);
assertEquals(1, variables.size());
Its fails with different Error
testGetAllVariablesWithoutQueryParamPass(com.myorg.project.market.integration.TestVariable): Unable to find a MessageBodyReader of content-type application/json and type java.util.List<com.myorg.project.service.presentation.VariablePresentation>
How do I resolve this?
The easiest way I found is to use ClientResponse with Gson
A simple example could be
#Test
public void testGetAllVariablesWithoutQueryParamNoPass() throws Exception {
final ClientRequest clientCreateRequest_var0 = new ClientRequest("http://localhost:9090/variables?_activeonly=no");
final MultivaluedMap<String, String> formParameters = clientCreateRequest_var0.getFormParameters();
final String name0 = "testGetAllVariablesWithoutQueryParamNoPass_0";
formParameters.putSingle("name", name0);
formParameters.putSingle("type", "String");
formParameters.putSingle("units", "units");
formParameters.putSingle("description", "description");
formParameters.putSingle("core", "true");
final ClientResponse<String> clientCreateResponse_var0 = clientCreateRequest_var0.post(String.class);
assertEquals(201, clientCreateResponse_var0.getStatus());
final ClientRequest clientCreateRequest_var1 = new ClientRequest("http://localhost:9090/variables");
final MultivaluedMap<String, String> formParameters1 = clientCreateRequest_var1.getFormParameters();
final String name1 = "testGetAllVariablesWithoutQueryParamNoPass_1";
formParameters1.putSingle("name", name1);
formParameters1.putSingle("type", "String");
formParameters1.putSingle("units", "units");
formParameters1.putSingle("description", "description");
formParameters1.putSingle("core", "true");
final ClientResponse<String> clientCreateResponse_var1 = clientCreateRequest_var1.post(String.class);
assertEquals(201, clientCreateResponse_var1.getStatus());
final ClientRequest clientCreateRequest2 = new ClientRequest("http://localhost:9090/variables");
final ClientResponse<String> clientCreateResponse2 = clientCreateRequest2.get(String.class);
final Gson gson = new Gson();
final Type variableType = new TypeToken<List<VariablePresentation>>() {
}.getType();
List<VariablePresentation> variables = gson.fromJson(clientCreateResponse2.getEntity(), variableType);
assertNotNull(variables);
assertEquals(2, variables.size());
// clean test data
removeTestDataVariableObject(name0);
removeTestDataVariableObject(name1);
}
Related
How can I keep the original case of the keys when writing the object to json?
POJO-Class:
public class LeadRequest
{
private String AccountName;
private String AccountAlias;
private String BPID;
private String CustomerType;
private String Email;
private String LocationType;
private String APRID;
private String APRDistributorName;
private String EngagedwithRAOrDistributor;
public String getBPID()
{
return BPID;
}
public void setBPID(final String bPID)
{
BPID = bPID;
}
public String getEngagedwithRAOrDistributor()
{
return EngagedwithRAOrDistributor;
}
public void setEngagedwithRAOrDistributor(final String engagedwithRAOrDistributor)
{
EngagedwithRAOrDistributor = engagedwithRAOrDistributor;
}
}
Service-class:
public void submitLeadRequest(final LeadRequest lead)
{
try
{
final String endPoint = Config.getParameter(ServicesConstants.API_URL);
final HttpPost request = new HttpPost(endPoint);
request.addHeader(ServicesConstants.CONTENT_TYPE, ServicesConstants.APPLICATION_JSON);
request.addHeader(ServicesConstants.CLIENT_ID, Config.getParameter(ServicesConstants.CLIENT_ID));
request.addHeader(ServicesConstants.CLIENT_SECRET, Config.getParameter(ServicesConstants.CLIENT_SECRET));
final ObjectMapper mapper = new ObjectMapper();
final String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(lead);
final StringEntity entity = new StringEntity(jsonString);
request.setEntity(entity);
final RequestConfig requestConfig = getRequestConfig(API_TIMEOUT_LONG);
final CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
CloseableHttpResponse response = client.execute(request);
}
}
Currently the Post Request json generated is:
{
"accountAlias" : "No Account Alias",
"accountName" : "REI AUTOMATION INC",
"customerType" : "OEM",
"aprid" : "002",
"bpid" : "0099105850",
"locationType" : "Research & Development",
"email" : "john.smith#jefftestaccount.com",
"engagedwithRAOrDistributor" : "",
"aprdistributorName" : "002-CED Royal Industrial Elec"
}
But the post request is failing giving HTTP/1.1 500 Server Error because of case sensitive keys in request json for the system being called
Therefore, the desired Request Json is:
If you are using com.fasterxml.jackson.databind.ObjectMapper, you can specify final name for each field using com.fasterxml.jackson.annotation.JsonProperty for example:
#JsonProperty("AccountName")
private String AccountName;
Or you can “tell” to your mapper to use fields instead of getters for creating a final JSON. In order to do so you can just configure your mapper class as follows:
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
HttpDataClient.java class is sending dataId to external service and should receive something in response. For my test I should test that RestTemplate and check if I am getting good response.
public class HttpDataClient implements DataClient{
private final static Logger LOGGER = LoggerFactory.getLogger(HttpDataClient.class);
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper = new ObjectMapper();
public HttpDataClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
#Override
public DataResponse getData(String dataId) {
try{
JsonNode node = restTemplate.exchange(
String.format("/data/{0}", dataId),
HttpMethod.POST,
new HttpEntity<>(buildRequest(dataId), headers()),
JsonNode.class
).getBody();
return dataResponse(node);
}catch (HttpStatusCodeException e) {
String msg = String.format(
"Error getting data for dataId: {0}",
dataId,
e.getStatusCode(),
e.getResponseBodyAsString());
LOGGER.error(msg);
return dataResponse.failed();
}
}
private MultiValueMap<String, String> headers() {
final LinkedMultiValueMap<String, String> mv = new LinkedMultiValueMap<>();
mv.set(HttpHeaders.CONTENT_TYPE, "application/json");
return mv;
}
private DataResponse dataResponse(JsonNode node) {
return DataResponse.dataResponse(
asString(node, "dataId"),
asString(node, "author"),
asString(node, "authorDataId"),
asString(node, "serverSideDataId")
);
}
private JsonNode buildRequest(String dataId) {
ObjectNode root = objectMapper.createObjectNode();
root.put("dataId", dataId);
return root;
}
}
DataResponse.java
public class DataResponse {
public final String dataId;
public final String author;
public final String authorDataId;
public final String serverSideDataId;
public DataResponse(
String dataId,
String author,
String authorDataId,
String serverSideDataId) {
notNull(dataId, "dataId must be set");
notNull(author, "author must be set");
notNull(authorDataId, "authorDataId must be set");
notNull(serverSideDataId, "serverSideDataId must be set");
this.dataId = dataId;
this.author = author;
this.authorDataId = authorDataId;
this.serverSideDataId = serverSideDataId;
}
public static GameDataResponse gameDataResponse(
String gameId,
String vendor,
String vendorGameId,
String serverSideGameId){
return new GameDataResponse(
gameId,
vendor,
vendorGameId,
serverSideGameId);
}
//TODO PD-849 - add faild method
public static GameDataResponse failed() {
return new GameDataResponse(
failed().gameId,
failed().vendor,
failed().vendorGameId,
failed().serverSideGameId
);
}
}
Interface:
public interface DataService {
DataResponse getData(String dataId);
}
Here is the test class:
#RunWith(MockitoJUnitRunner.class)
public class HttpDataServiceTest {
RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
private final HttpDataService httpDataService = new HttpDataService(restTemplate);
#Test
public void getData(){
ObjectNode responseNode = JsonNodeFactory.instance.objectNode();
responseNode.put("dataId", "");
responseNode.put("author", "");
responseNode.put("authorDataId", "");
responseNode.put("serverSideDataId", "");
Mockito
.when(restTemplate.exchange(
ArgumentMatchers.eq("/data/dataIdTest"),
ArgumentMatchers.eq(HttpMethod.POST),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<JsonNode>>any()))
.thenReturn(new ResponseEntity<>(responseNode, HttpStatus.OK));
httpDataService.getData("dataIdTest");
}
}
So, when I debug I go trough test class and everything works fine, then it goes to HttpDataClient.java class to getData() method and when I am in restTemplate.exchangeI can see thatdataIdis sent, then it goes down to.getBody();` and it breaks. And I don’t get anything in return.
What am I missing here?
Any advice appreciated.
based just on a quick look - try changing
String.format("/data/{0}", dataId)
to
String.format("/data/%s", dataId)
in your DataResponse getData(String dataId) method
I have a Service Class which has following method
NewCartService.java:
#Service
public class NewCartService {
#Autowired
private LoginRepository loginRepository;
#Autowired
private ProductRepository productRepository;
#Autowired
private CartRepository cartRepository;
#Autowired
private CartDao cartDao;
#Autowired
private Mailer mailService;
public MessageResponse order(List<Cart> cart) throws MessagingException {
for (Cart cart1 : cart) {
String userName = cart1.getUserName();
String password = cart1.getPassword();
String productName = cart1.getProductName();
String price = cart1.getPrice();
String discription = cart1.getDiscription();
if (!cartRepository.existsAllByUserNameAndPasswordAndProductNameAndPriceAndDiscription(userName, password, productName, price, discription)) {
throw new ResourceNotFoundException("not found");
}
MustacheFactory mf = new DefaultMustacheFactory();
Mustache m = mf.compile("cart.mustache");
StringWriter writer = new StringWriter();
String messageText = "";
List<Cart> carts = cartDao.getCart(cart);
Map<String, Object> params = new HashMap<>();
params.put("carts", carts);
Writer m1 = m.execute(writer, params);
System.out.println(m1);
messageText = m1.toString();
mailService.sendMail("/*email address*/", "/*email address*/", messageText, "demo", true);
cartRepository.deleteByUserNameAndPasswordAndProductNameAndPriceAndDiscription(userName, password, productName, price, discription);
return new MessageResponse("product Successfully ordered from cart");
}
throw new BadArgumentsException("bad arguments");
}
}
I have controller
CartController.java:
#RestController
public class CartController {
#Autowired
public CartService cartService;
#GetMapping("/orders")
public ResponseEntity<?> orders(#Valid #RequestBody List<Cart> carts) throws MessagingException {
return newCartService.order(carts);// it gives error because i need to convert MessageResponse into the ResponseEntity<?>
}
}
Now my Question is that how can i convert these MessageResponse into the ResponseEntity<?> ?
please suggest me code so that i can solve these issue and Thanks in Advance.
Have you tried:
return new ResponseEntity<>(newCartService.order(carts), HttpStatus.OK);
or as suggested in the comments:
return ResponseEntity.ok(newCartService.order(carts));
In addition if you want set header with response entity you can try:
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "<header>");
return new ResponseEntity<>(newCartService.order(carts), headers, HttpStatus.OK);
alternative you can use:
return ResponseEntity.ok()
.header("Custom-Header", "<header>")
.body(newCartService.order(carts));
I have two classes PlaylistResource which has a method createPlaylist which takes an object of type PlaylistRequest. I want to create a POST request on localhost:9999/playlists I am using Postman and I am not sure how to pass the object of PlaylistRequest which is request to the method createPlaylist.
#XmlType(propOrder= {"title", "artistSeeds", "numberOfSongs"})
#XmlAccessorType(XmlAccessType.FIELD)
public class PlaylistRequest {
private String title = "";
#XmlElement(name = "seeds")
private List<String> artistSeeds;
#XmlElement (name = "size")
private int numberOfSongs = 0;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public List<String> getArtistSeeds() {
return artistSeeds;
}
public void setArtistSeeds(List<String> artistSeeds) {
this.artistSeeds = artistSeeds;
}
public int getNumberOfSongs() {
return numberOfSongs;
}
public void setNumberOfSongs(int numberOfSongs) {
this.numberOfSongs = numberOfSongs;
}
}
The other class:
#Path("playlists")
public class PlaylistResource implements PlaylistApi {
#Override
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response createPlaylist(PlaylistRequest request) {
if(request == null) {
System.out.println("Was here");
throw new ClientRequestException(new ErrorMessage("no parameter passed."));
}
try {
List<Song> playList = new ArrayList<>();
List<Song> songs = new ArrayList<>();
List<String> artistsIds = new ArrayList<>();
ArtistResource artistsResources = new ArtistResource();
int playlistDefaultSize = 10;
int i = 0;
do {
playList.add(songs.get(i));
i++;
}while( i < playlistDefaultSize);
Playlist playlist = new Playlist();
playlist.setTitle(request.getTitle());
playlist.setSize(songs.size());
playlist.setTracks(playList);
return Response.status(Response.Status.CREATED.getStatusCode()).entity(playlist).build();
} catch (Exception e) {
throw new RemoteApiException(new ErrorMessage(e.getMessage()));
}
}
}
Change this parameter from data class to string,
public Response createPlaylist(PlaylistRequest request) {
to
public Response createPlaylist(String request) {
then convert it using GSON into your data class.
PlaylistRequest request = new Gson().fromJson(request, new TypeToken<PlaylistRequest >(){}.getType());
Simply add a JSON object in Body of request, select Raw Json in Postman and paste the following object:
NOTE: Add a key Content-Type and set its value to application/json in Header of Request
{
"title": "Some title",
"artistSeeds": [
"string1",
"string2"
],
"numberOfSongs": 0
}
HEADER
BODY
I have singleton implementation of enum as below :
public enum DeviceDetail{
INSTANCE;
private Context context = null;
private int handlercheck = 0;
private String network = "";
private String deviceInfo = "NoData";
private String androidVersion = "";
private String appVersion = "";
private String appName = "";
private String deviceID;
private String deviceinfo;
public void initilize(){
// deviceInfo = getDeviceInfo();
networktype = getNetworktype(context);
deviceID = getDeviceID(context);
//androidVersion = getAndroidVersion();
appVersion = getAppVersion(context);
appName = getAppName(context);
}
DeviceDetail(){
deviceInfo = getDeviceInfo();
androidVersion = getAndroidVersion();
initilize();
}
public static DeviceDetail getInstance() {
return DeviceDetail.INSTANCE;
}
}
I want to convert this DeviceDetail to JSON using GSON, for that I have written
public static String convertObjectToJsonString(DeviceDetail deviceData) {
Gson gson = new Gson();
return gson.toJson(deviceData);
}
I am calling this method as
convertObjectToJsonString(DeviceDetail.INSTANCE)
but it only returns me the string "INSTANCE" not key value pairs as it does for objects. Suggest the changes need to be made so that I get string with all fields in enum in key value JSON.
I have ended up in using a not so elegant workaround as below :
public static String convertObjectToJsonString(DeviceDetail deviceData) {
// Gson gson = new Gson();
// GsonBuilder gb = new GsonBuilder();
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("androidVersion", deviceData.getAndroidVersion());
jsonObject.addProperty("appName", deviceData.getAppName());
jsonObject.addProperty("appVersion", deviceData.getAppVersion());
jsonObject.addProperty("networkType", deviceData.getNetworktype());
jsonObject.addProperty("deviceInfo", deviceData.getDeviceInfo());
jsonObject.addProperty("deviceID", deviceData.getDeviceID());
jsonObject.addProperty("city", deviceData.getCity());
jsonObject.addProperty("country", deviceData.getCountry());
//jsonObject.addProperty("appName",deviceData.getAppName());
return jsonObject.toString();
}