I made two RestController apis. On response of second api I wanted first api's response (which is a json response), so I tried to use HttpServletResponse.redirect. I also set required content type to it. But on second api response I got Unsupported Media Type Content type 'null' not supported.
first API
#GetMapping(value="checkStatus/{msisdn}",consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CoreResponseHandler> fetchOcsByDate2(#PathVariable(value="msisdn",required=true)String msisdn){
long l_time_start = System.currentTimeMillis();
List<Object[]> list = repository.getSingleCallDetail(msisdn);
if(list==null || list.size()==0) {
System.out.println("NO RECORD FOUND");
}
JSONObject objMain = new JSONObject();
for(Object[] objArr: list) {
JSONObject obj = new JSONObject();
String msisdn_ = objArr[0]==null?null:objArr[0].toString();
String songId = objArr[1]==null?null:objArr[1].toString();
String songName = objArr[2]==null?null:objArr[2].toString();
String status = objArr[3]==null?null:objArr[3].toString();
String lang = objArr[4]==null?null:objArr[4].toString();
String startDate = objArr[5]==null?null:objArr[5].toString();
objMain.put("status", status);
objMain.put("language", lang);
obj.put("id", songId);
obj.put("msisdn", msisdn);
obj.put("songName", songName);
objMain.put("subscription", obj);
}
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
if(list!=null && list.size()>0) {
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.OK, ResponseStatusEnum.SUCCESSFUL, ApplicationResponse.SUCCESSFUL, objMain,l_diff+" ms"),HttpStatus.OK);
}
if(list==null || list.size()==0) {
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.NOT_FOUND, ResponseStatusEnum.FAILED, ApplicationResponse.Failed, "not found",l_diff+" ms"),HttpStatus.NOT_FOUND);
}
return new ResponseEntity<CoreResponseHandler>(new SuccessResponseBeanRefined(HttpStatus.BAD_REQUEST, ResponseStatusEnum.FAILED, ApplicationResponse.Failed," > Bad request",l_diff+" ms"),HttpStatus.BAD_REQUEST);
}
no problem in output. ran smooth
second API
#GetMapping(value="verifyOtp/{msisdn}/{otp}",consumes=MediaType.APPLICATION_JSON_VALUE)
public void verifyOtp(#PathVariable(value="msisdn",required=true)String msisdn,
#PathVariable(value="otp",required=true)String otp,HttpServletResponse response) throws Exception{
long l_time_start = System.currentTimeMillis();
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
List<Object[]> list = repository.verifyOtp(msisdn,otp);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
if(list!=null && list.size()>0) {
for(Object[] obj:list) {
String strDate = obj[3]==null?null:obj[3].toString();
Date dtDb = sdf.parse(strDate);
Date dtNow = new Date();
String strDtNow = sdf.format(dtNow);
dtNow = sdf.parse(strDtNow);
long ldtDb = dtDb.getTime();
long ldtNow = dtNow.getTime();
if(ldtDb>ldtNow) {
System.out.println("success within time");
int ii = repository.updateIsActive(msisdn);
response.setContentType("application/json");
response.sendRedirect("http://localhost:9393/crbt/api/subscriber/ivr/checkStatus/"+msisdn);
}
else {
System.out.println("failure time over!");
}
}
}
else {
}
}
second Api Response in postman
What I expected was first API's response. But its giving me some 415 content type error
How can I get first API's success json response from second api's response.. I even tried org.springframework.http.HttpHeaders but couldn't get desired output. What changes I had to do in order to get first Api's response in my second api response.
I have a strange feeling answering your questions, because I dislike the solution I'll provided. But it might help, so I'll give a try.
Basically, your Controller are just Spring beans, which means you can do is having a dependency, and second controller will call first controller. This will also change your method verifyOtp to make it change the return type.
Something like that:
...
#Autowired
private FirstController firstController;
...
#GetMapping(value="verifyOtp/{msisdn}/{otp}",consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CoreResponseHandler> verifyOtp(#PathVariable(value="msisdn",required=true)String msisdn,
#PathVariable(value="otp",required=true)String otp,HttpServletResponse response) throws Exception{
long l_time_start = System.currentTimeMillis();
long l_time_end = System.currentTimeMillis();
long l_diff = l_time_end-l_time_start;
List<Object[]> list = repository.verifyOtp(msisdn,otp);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
if(list!=null && list.size()>0) {
for(Object[] obj:list) {
String strDate = obj[3]==null?null:obj[3].toString();
Date dtDb = sdf.parse(strDate);
Date dtNow = new Date();
String strDtNow = sdf.format(dtNow);
dtNow = sdf.parse(strDtNow);
long ldtDb = dtDb.getTime();
long ldtNow = dtNow.getTime();
if(ldtDb>ldtNow) {
System.out.println("success within time");
int ii = repository.updateIsActive(msisdn);
return firstController.fetchOcsByDate2(msidn);
}
else {
System.out.println("failure time over!");
return null;
}
}
}
else {
return null;
}
}
I think you are trying to achieve something uncommon, and to avoid having this dependency between controller, consider:
Change your use case. Make the second controller returning a HttpStatus.OK, and make the client do the next call to the first controller
Create a service in charge of loading the msidn, which will avoid duplicate code, and keep you in a more standard position to make our evolutions.
The issue occurred due to GetMapping .
#GetMapping(value="checkStatus/{msisdn}",consumes=MediaType.APPLICATION_JSON_VALUE)
replace with below in first Api:
#GetMapping(value="checkStatus/{msisdn}")
Related
I'm trying to realize a filter on one of my controllers.
This is the controller
#RequestMapping(value = "", method = RequestMethod.GET)
public String listSpots(ModelMap model, #RequestParam (value= "page", required = false) Integer page,
#RequestParam (value="numeroPosto", required = false) Integer numeroPosto,
#RequestParam(value="nomePosto", required = false) String nomePosto,
#RequestParam(value="occupied", required = false) Integer occupied,
#RequestParam(value="idPark", required = false) Integer idPark,
#RequestParam(value="idPiano", required = false) Integer idPiano,
#RequestParam(value="dateTime", required = false) Date dateTime) {
if (page == null) {
currentPage = 1;
} else {
currentPage = page;
}
int offset = (currentPage - 1) * elementsPerPage;
//creo la mappa dei criteri
Map<String, Object> criteri = new HashMap<String, Object>();
criteri.put("numeroPosto", numeroPosto);
criteri.put("nomePosto", nomePosto);
criteri.put("occupied", occupied);
Park park = null;
Piano piano = null;
if(idPark!=null){
park = parkService.findById(idPark);
}
if(idPiano!=null){
piano = pianoService.findById(idPiano);
}
criteri.put("park", park);
criteri.put("piano", piano);
criteri.put("dateTime", dateTime);
int numOfRows = postoService.showSpotsCount(criteri);
List<Posto> posti = postoService.showSpots(offset, criteri);
List<Posto> posto = new ArrayList<Posto>(posti.size());
for (Posto javaBean : posti){
Date date = new Date();
Date start = new Timestamp(date.getTime());
Date end = javaBean.getDateTime();
DateTime st = new DateTime(start);
DateTime en = new DateTime(end);
Long hours = postoService.getHours(st, en);
Long minutes = postoService.getMinutes(st, en);
javaBean.setHours(hours);
javaBean.setMinutes(minutes);
posto.add(javaBean);
}
int pages = 1+(numOfRows / elementsPerPage);
String pageTitle = messageSource.getMessage("spot.list", null, locale);
model.addAttribute("pageTitle", pageTitle);
model.addAttribute("cssActiveSpots", cssActiveSpots);
model.addAttribute("posto", posto);
model.addAttribute("currentPage", currentPage);
model.addAttribute("pages", pages);
model.addAttribute("numOfRows", numOfRows);
return path + "/posti";
}
I'm putting the params into a map, and then, at DAO level, this params will create the Restrictions to the query. I'm having a problem when leaving the dateTime field blank
I'm taking the query string from a simple form. Every other filed in the form works, and it also works if I put a correct date. When I leave it blank I get:
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [#org.springframework.web.bind.annotation.RequestParam java.util.Date] for value ''; nested exception is java.lang.IllegalArgumentException
I can I solve this?
Just add this to your controller and it should work.
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// change the format according to your need.
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
I have one JsonObjectBuilder that builds my response.
I have a for loop that loops 7 times, during each iteration it builds a new JsonObjectBuilder, adds key/value pairs, then this JsonObjectBuilder instance is added to the parent Builder for my response.
As I understand it, this method should build 7 nested JsonObjects in my response object.
private void addStoreHoursResponse(Map<String,Object> response, AppConfigHelper configHelper) throws IOException {
final String OPEN = "open";
final String CLOSE = "close";
final String NOTES = "notes";
JsonObject storeHours = configHelper.getStoreHours();
Calendar now = DateUtils.getEasternTimeZoneCalendar();
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
JsonObjectBuilder responseBuilder = Json.createObjectBuilder();
String open, close, notes;
for (int i = 0; i < 7; i++) {
JsonObjectBuilder hoursBuilder = Json.createObjectBuilder();
HoursKey hoursKey = HoursKey.getHoursKey(now);
JsonObject hours = storeHours.getJsonObject(hoursKey.toString());
open = hours.isNull(OPEN) ? null : hours.getString(OPEN);
close = hours.isNull(CLOSE) ? null : hours.getString(CLOSE);
notes = hours.isNull(NOTES) ? null : hours.getString(NOTES);
if (open == null || close == null) {
hoursBuilder.add(OPEN, JsonValue.NULL);
hoursBuilder.add(CLOSE, JsonValue.NULL);
hoursBuilder.add(NOTES, JsonValue.NULL);
} else {
hoursBuilder.add(OPEN, DateUtils.getIsoString(setCalendarTime(now, open)));
hoursBuilder.add(CLOSE, DateUtils.getIsoString(setCalendarTime(now, close)));
hoursBuilder.add(NOTES, notes);
}
responseBuilder.add(DateUtils.getIsoString(now), hoursBuilder);
now.add(Calendar.DAY_OF_MONTH, 1);
}
response.put(STORE_HOURS, responseBuilder.build());
}
private Calendar setCalendarTime(Calendar calendar, String time) {
String[] timeArray = time.split(":");
int hour = Integer.parseInt(timeArray[0]);
int minute = Integer.parseInt(timeArray[1]);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
return calendar;
}
My JsonResponse has the 7 JsonObjects, but they should look like the following...
"open" : ISO time string,
"close" : ISO time string,
"notes" : String value
I am getting this as a result, what am I doing wrong?
I'm writing a webapp where there are dates to be sent to a Servlet and I want to send some blank dates and based on these dates I want to build a query. But here My problem is when I pass the parameters i.e. the dates it's working fine, And when I send blank parameters it is throwing me the below error.
Start date got is and end date is //Here I'm checking the output
Unparseable date: "" servlet Errotr
When I give in the dates it shows in console as
Start date got is (TheStartDateValue) and end date is (TheEndDateValue)
and there is no exception (since the dates are parsed). And below is my code.
public class Controller extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
/* Date Start */
String startDateStr = request.getParameter("startDate");
String endDateStr = request.getParameter("endDate");
System.out.println("Start date got is " + startDateStr + " and end date is " + endDateStr);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat print = new SimpleDateFormat("yyyy-MM-dd");
Date startParsedDate = null, endParsedDate = null;
String startDate = null, endDate = null;
if (!startDateStr.equals(null) || !startDateStr.equals("")) {
startParsedDate = sdf.parse(startDateStr);
startDate = print.format(startParsedDate);
}
if (!endDateStr.equals(null) || !endDateStr.equals("")) {
endParsedDate = sdf.parse(endDateStr);
endDate = print.format(endParsedDate);
}
System.out.println(startDate + " value and " + endDate);
/* Date End */
DataDao dataDao = new DataDao();
ArrayList<UserBean> list = dataDao.getFrameWork(startDate, endDate);
String searchList = new Gson().toJson(list);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(searchList);
System.out.println("servlet Done");
} catch (Exception e) {
System.err.println(e.getMessage() + " servlet Errotr");
}
}
I'm trying to handle the startDateStr and startDateStrto chweck if the input values are null or having some value using the below block in my above code.
if (!startDateStr.equals(null) || !startDateStr.equals("")) {
startParsedDate = sdf.parse(startDateStr);
startDate = print.format(startParsedDate);
}
if (!endDateStr.equals(null) || !endDateStr.equals("")) {
endParsedDate = sdf.parse(endDateStr);
endDate = print.format(endParsedDate);
}
Please let me know where am I going wrong and how can I fix this.
Thanks
Problem is in condition !startDateStr.equals(null) || !startDateStr.equals(""), you should change it to startDateStr != null && !startDateStr.equals("") and the same problem is in second condition.
I'm trying to download photos posted with specific tag in real time. I found real time api pretty useless so I'm using long polling strategy. Below is pseudocode with comments of sublte bugs in it
newMediaCount = getMediaCount();
delta = newMediaCount - mediaCount;
if (delta > 0) {
// if mediaCount changed by now, realDelta > delta, so realDelta - delta photos won't be grabbed and on next poll if mediaCount didn't change again realDelta - delta would be duplicated else ...
// if photo posted from private account last photo will be duplicated as counter changes but nothing is added to recent
recentMedia = getRecentMedia(delta);
// persist recentMedia
mediaCount = newMediaCount;
}
Second issue can be addressed with Set of some sort I gueess. But first really bothers me. I've moved two calls to instagram api as close as possible but is this enough?
Edit
As Amir suggested I've rewritten the code with use of min/max_tag_ids. But it still skips photos. I couldn't find better way to test this than save images on disk for some time and compare result to instagram.com/explore/tags/.
public class LousyInstagramApiTest {
#Test
public void testFeedContinuity() throws Exception {
Instagram instagram = new Instagram(Settings.getClientId());
final String TAG_NAME = "portrait";
String id = instagram.getRecentMediaTags(TAG_NAME).getPagination().getMinTagId();
HashtagEndpoint endpoint = new HashtagEndpoint(instagram, TAG_NAME, id);
for (int i = 0; i < 10; i++) {
Thread.sleep(3000);
endpoint.recentFeed().forEach(d -> {
try {
URL url = new URL(d.getImages().getLowResolution().getImageUrl());
BufferedImage img = ImageIO.read(url);
ImageIO.write(img, "png", new File("D:\\tmp\\" + d.getId() + ".png"));
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
}
class HashtagEndpoint {
private final Instagram instagram;
private final String hashtag;
private String minTagId;
public HashtagEndpoint(Instagram instagram, String hashtag, String minTagId) {
this.instagram = instagram;
this.hashtag = hashtag;
this.minTagId = minTagId;
}
public List<MediaFeedData> recentFeed() throws InstagramException {
TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, minTagId, null);
List<MediaFeedData> dataList = feed.getData();
if (dataList.size() == 0) return Collections.emptyList();
String maxTagId = feed.getPagination().getNextMaxTagId();
if (maxTagId != null && maxTagId.compareTo(minTagId) > 0) dataList.addAll(paginateFeed(maxTagId));
Collections.reverse(dataList);
// dataList.removeIf(d -> d.getId().compareTo(minTagId) < 0);
minTagId = feed.getPagination().getMinTagId();
return dataList;
}
private Collection<? extends MediaFeedData> paginateFeed(String maxTagId) throws InstagramException {
System.out.println("pagination required");
List<MediaFeedData> dataList = new ArrayList<>();
do {
TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, null, maxTagId);
maxTagId = feed.getPagination().getNextMaxTagId();
dataList.addAll(feed.getData());
} while (maxTagId.compareTo(minTagId) > 0);
return dataList;
}
}
Using the Tag endpoints to get the recent media with a desired tag, it returns a min_tag_id in its pagination info, which is tied to the most recently tagged media at the time of your call. As the API also accepts a min_tag_id parameter, you can pass that number from your last query to only receive those media that are tagged after your last query.
So based on whatever polling mechanism you have, you just call the API to get the new recent media if any based on last received min_tag_id.
You will also need to pass a large count parameter and follow the pagination of the response to receive all data without losing anything when the speed of tagging is faster than your polling.
Update:
Based on your updated code:
public List<MediaFeedData> recentFeed() throws InstagramException {
TagMediaFeed feed = instagram.getRecentMediaTags(hashtag, minTagId, null, 100000);
List<MediaFeedData> dataList = feed.getData();
if (dataList.size() == 0) return Collections.emptyList();
// follow the pagination
MediaFeed recentMediaNextPage = instagram.getRecentMediaNextPage(feed.getPagination());
while (recentMediaNextPage.getPagination() != null) {
dataList.addAll(recentMediaNextPage.getData());
recentMediaNextPage = instagram.getRecentMediaNextPage(recentMediaNextPage.getPagination());
}
Collections.reverse(dataList);
minTagId = feed.getPagination().getMinTagId();
return dataList;
}
How to parse two different objects from the same json file knowing that parsing one of them block parsing the other, which means that i have to parse only one of them, this is my code:
try {
time = json1.getJSONObject(TAG_TIME);
String Time2 = time.toString();
deals = json1.getJSONObject(TAG_DEALS);
final String plusinfo = deals.getString(TAG_PLUS_INFO);
String title = deals.getString(TAG_TITLE);
Integer retail = deals.getInt(TAG_RETAIL);
String nretail = Integer.toString(retail);
Integer deal = deals.getInt(TAG_DEAL);
String ndeal = Integer.toString(deal);
String duration = deals.getString(TAG_DURATION);
String image = deals.getString(TAG_IMAGE_URL);
String participant = deals.getString(TAG_PARTICIPANT);
final String details = deals.getString(TAG_DETAILS);
final String name = deals.getString(TAG_ADVERTISER_NAME);
final String adress = deals.getString(TAG_ADVERTISER_ADDRESS);
final String phone = deals.getString(TAG_ADVERTISSER_PHONE);
/*String Time1 = deals.getString(TAG_DATE);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = new GregorianCalendar(0,0,0).getTime();
Date date2 = new GregorianCalendar(0,0,0).getTime();
try {
date1 = sdf.parse(Time1);
date2 = sdf.parse(Time2);
} catch (ParseException e) {
e.printStackTrace();
}
final String precision = deals.getString(TAG_PRECISION);
JSONArray c = deals.getJSONArray(TAG_PRECISION);
ArrayList<String> arrays = new ArrayList<String>();
for(int i = 0; i < c.length(); i++){
precision = c.getString(i);
arrays.add(precision);
}
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_RETAIL, nretail);
map.put(TAG_DEAL, ndeal);
map.put(TAG_DURATION, duration);
map.put(TAG_IMAGE_URL, image);
map.put(TAG_PARTICIPANT, participant);
map.put(TAG_SERVER_TIME, Time2);
otherdeals.add(map);
What do you mean it gets blocked? I dont see what the issue is with what you have posted. If you wish to parse two different JSON responses, either kick off two background threads (AsyncTask) or just parse them one after the other