I think when I add #Async notation for this method, it returns an empty result. The method is to get data from a website and return the data. It works when I remove #Async. When I am not using #Async, it is using a thread called "http-nio-8080-exec-1", when I use #Async, it is using a thread with my naming prefix "My-thread1". I do not know if I need to config anywhere else like xml or something. Thank you!
#Async
public CompletableFuture<List<Post>> searchByTag(String[] tags, String sortBy, String direction ) throws ExecutionException, InterruptedException, IOException {
logger.info("I am here---------------------------------------------------------- ");
if(tags == null || tags.length == 0){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST , "Tags parameter is required");
}
if(sortBy == null){
sortBy = "id";
} else if(!sortBy.equals("id") && !sortBy.equals("reads") && !sortBy.equals("likes") && !sortBy.equals("popularity")){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "sortBy parameter is invalid");
}
if(direction == null){
direction = "asc";
} else if(!direction.equals("asc") && !direction.equals("desc")){
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "direction parameter is invalid");
}
long start = System.currentTimeMillis();
Set<Post> postSet = new HashSet<Post>();
String baseUrl = "https://api.hatchways.io/assessment/blog/posts?tag=";
HttpClient client = HttpClient.newHttpClient();
// send a get request to get all the posts with certain tag
for(int i = 0; i < tags.length; i++){
String url = baseUrl + tags[i];
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Accept", "application/json")
.uri(URI.create(url))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper mapper = new ObjectMapper();
// HttpResponse<String> result = response.get();
String responseBody = response.body().substring(9, response.body().length()-1);
logger.info("Using Thread: " + Thread.currentThread().getName());
List<Post> posts = mapper.readValue(responseBody, new TypeReference<List<Post>>() {});
// put all the posts into a set to filter out all the repeated posts
postSet.addAll(posts);
}
ArrayList<Post> postList = new ArrayList<>(postSet);
sortThePosts(sortBy, direction, postList);
long end = System.currentTimeMillis();
logger.info("Total time: " + Long.toString(end-start));
return CompletableFuture.completedFuture(postList);
}
Following is my config:
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
#Configuration
#EnableAsync
public class AsyncConfig {
#Bean(name = "threadPoolTaskExecutor")
public Executor taskExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);
threadPoolTaskExecutor.setMaxPoolSize(5);
threadPoolTaskExecutor.setQueueCapacity(20);
threadPoolTaskExecutor.setThreadNamePrefix("My_Thread");
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
The configuration looks fine. Have you created searchByTag() method in the same class you are calling the method from? If so try creating a separate service class that will contain your Async methods.
Related
I 'll explain first what I'm trying to do:
There's a service method that receives a thymeleaf template html file, process that and then transform into a pdf. The job that was assigned to me is to create an endpoint which returns the template html so the service will call that endpoint to get the html.
I don't know how to pass objects in a get request.
The code in the service method before:
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
Context context = new Context();
context.setVariable("expenseReportPdf", expenseReportPdf);
context.setVariable("expensePdf", expensePdfList);
context.setVariable("expenseImg", jpgFile);
context.setVariable("amountCompanyCurrency", amountCompanyCurrency);
context.setVariable("expenseIncurredList", expenseIncurredList);
context.setVariable("expenseRiepiloghiList",expenseRiepiloghiList);
context.setVariable("advancePayBigDecimal", advancePayBigDecimal);
context.setVariable("dailyAllowanceList", dailyAllowanceList);
context.setVariable("dailyAllowanceFlag", dailyAllowanceFlag.booleanValue());
context.setVariable("logo",logo);
context.setVariable("logoSmartex",logoSmartex);
logger.debug("Logo Smartex:" + logoSmartex);
logger.debug("Logo Company:" + logo);
String renderedHtmlContent = templateEngine.process("template", context);
Firstly I moved that part in a configuration class which creates the beans necessary to return the html.
#Configuration
public class TemplateConfiguration {
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver2());
return templateEngine;
}
// Esiste già un bean che si chiama htmlTemplateResolver
#Bean
public ClassLoaderTemplateResolver htmlTemplateResolver2() {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setOrder(Integer.valueOf(3));
resolver.setPrefix("templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode(TemplateMode.HTML);
return resolver;
}
}
Then i create the endpoint which should return the html processed.
#GetMapping(path = "/get-template-html")
public String getTemplateHTMLEndpoint(#RequestParam("expenseReportPdf") String expenseReportPdfJSON, #RequestParam("expensePdfList") String expensePdfListJSON,
#RequestParam("jpgFile") String jpgFileJSON, #RequestParam("amountCompanyCurrency") String amountCompanyCurrencyJSON,
#RequestParam("expenseIncurredList") String expenseIncurredListJSON, #RequestParam("expenseRiepiloghiList") String expenseRiepiloghiListJSON,
#RequestParam("advancePayBigDecimal") String advancePayBigDecimalJSON, #RequestParam("dailyAllowanceList") String dailyAllowanceListJSON,
#RequestParam("dailyAllowanceFlag") String dailyAllowanceFlag, #RequestParam("logo") String logo, #RequestParam("logoSmartex") String logoSmartex) {
// TODO convert JSON params to relative objects
Context context = new Context();
context.setVariable("expenseReportPdf", expenseReportPdf);
context.setVariable("expensePdf", expensePdfList);
context.setVariable("expenseImg", jpgFile);
context.setVariable("amountCompanyCurrency", amountCompanyCurrency);
context.setVariable("expenseIncurredList", expenseIncurredList);
context.setVariable("expenseRiepiloghiList",expenseRiepiloghiList);
context.setVariable("advancePayBigDecimal", advancePayBigDecimal);
context.setVariable("dailyAllowanceList", dailyAllowanceList);
context.setVariable("dailyAllowanceFlag", String dailyAllowanceFlag);
context.setVariable("logo",logo);
context.setVariable("logoSmartex",logoSmartex);
String renderedHtmlContent = templateEngine.process("template", context);
return renderedHtmlContent;
}
}
Finally I created a method in the service which calls the endpoint.
private String callGetTemplateHTMLEndPoint(ExpenseReportPdf expenseReportPdf, List<ExpensePdf> expensePdfList, List<ExpenseImg> jpgFile,
BigDecimal amountCompanyCurrency, List<ExpenseIncurred> expenseIncurredList,
List<ExpenseRiepiloghi> expenseRiepiloghiList, BigDecimal advancePayBigDecimal,
List<DailyAllowanceDetails> dailyAllowanceList, Boolean dailyAllowanceFlag, String logo,
String logoSmartex) {
ObjectMapper objectMapper = new ObjectMapper();
String JSONExpenseReportPdf = "";
String JSONExpensePdfList = "";
String JSONJpgFile = "";
String JSONAmountCompanyCurrency = "";
String JSONExpenseIncurredList = "";
String JSONExpenseRiepiloghiList = "";
String JSONAdvancePayBigDecimal = "";
String JSONDailyAllowanceList = "";
// Trasformo i parametri in JSON
try {
JSONExpenseReportPdf = objectMapper.writeValueAsString(expenseReportPdf);
JSONExpensePdfList = objectMapper.writeValueAsString(expensePdfList);
JSONJpgFile = objectMapper.writeValueAsString(jpgFile);
JSONAmountCompanyCurrency = objectMapper.writeValueAsString(amountCompanyCurrency);
JSONExpenseIncurredList = objectMapper.writeValueAsString(expenseIncurredList);
JSONExpenseRiepiloghiList = objectMapper.writeValueAsString(expenseRiepiloghiList);
JSONAdvancePayBigDecimal = objectMapper.writeValueAsString(advancePayBigDecimal);
JSONDailyAllowanceList = objectMapper.writeValueAsString(dailyAllowanceList);
} catch (JsonProcessingException e1) {
e1.printStackTrace();
}
// Creo i query params coi JSON
String params = "?";
params += "expenseReportPdf=" + JSONExpenseReportPdf + "&";
params += "expensePdfList=" + JSONExpensePdfList + "&";
params += "jpgFile=" + JSONJpgFile + "&";
params += "amountCompanyCurrency=" + JSONAmountCompanyCurrency + "&";
params += "expenseIncurredList=" + JSONExpenseIncurredList + "&";
params += "expenseRiepiloghiList=" + JSONExpenseRiepiloghiList + "&";
params += "advancePayBigDecimal=" + JSONAdvancePayBigDecimal + "&";
params += "dailyAllowanceList=" + JSONDailyAllowanceList + "&";
params += "dailyAllowanceFlag=" + dailyAllowanceFlag + "&";
params += "logo=" + logo + "&";
params += "logoSmartex=" + logoSmartex;
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:9898/Smartex/expense-report-pdf/get-template-html" + params))
.build();
String templateHTML = "Problems with the request";
try {
templateHTML = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString())
.body();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return templateHTML;
}
I don't know how to send/receive the params needed for the processing of the template, any idea?
TY
After a while I thought I could transform objects into JSON, add them as query params and then transform them back in the controller but there are 2 problems:
The URL is too much long (2568 characters)
URL contains {} and give error
If I do not use Spring Boot, my codes run well:
public void dealResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
long sartTime = System.currentTimeMillis();
while (true) {
Student student = getStudentResult();
if (student != null) {
response.setContentType("text/html;charset=UTF-8");
Writer writer = response.getWriter();
String ret = student.getName() + "is ok";
writer.write(ret);
writer.close();
if (student.isAllOver) {
break;
}
if (System.currentTimeMillis() - startTime > 60000) {
response.setContentType("text/html;charset=UTF-8");
Writer writer = response.getWriter();
String ret = “Deal over time ";
writer.write(ret);
writer.close();
break;
}
}
}
}
But now I want to change my code to Spring Boot, if return one result, I can change the code like this
#PostMapping
#RequestMapping(value = {"/"}, produces = {"application/json; charset=UTF-8"})
public ResponseEntity<Object> dealResult(HttpServletRequest request) {
return new ResponseEntity<>("Deal over time", HttpStatus.OK);
}
How to change my code to have multiple returns?
Your words are multi response, mutli-response was explained at here https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages#Body_2
Seemly, what you need shouldn't called "multi-response", Do you need response in few cases differently? Separate per case in control structure, then return the corresponding HttpStatus code. You may be need something like this
#PostMapping
#RequestMapping(value = {"/"}, produces = {"application/json; charset=UTF-8"})
public ResponseEntity<Object> dealResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
long sartTime = System.currentTimeMillis();
Student student = getStudentResult();
if (student != null) {
response.setContentType("text/html;charset=UTF-8");
Writer writer = response.getWriter();
String ret = student.getName() + "is ok";
writer.write(ret);
writer.close();
if (student.isAllOver) {
return new ResponseEntity<>("Deal over time", HttpStatus.OK);
} else {
if (System.currentTimeMillis() - startTime > 60000) {
response.setContentType("text/html;charset=UTF-8");
Writer writer = response.getWriter();
String ret = “Deal over time ";
writer.write(ret);
writer.close();
return new ResponseEntity<>("Deal over time", HttpStatus.REQUEST_TIMEOUT);
} else {
return new ResponseEntity<>("Error", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
}
I am trying to POST multipart file as a form data to a REST service which returns me a url after it saved at REST service end. In postman the request look like this.
I have a Spring Boot service which has a method to get Multipart file form frontend via jquery fileuploader. I need to post the file to the above URL which postman sends and saves in there end. I think i have to construct form data in my Spring boot service. Below are few snaps of the Spring boot service.
Controller end.
#RequestMapping(method = RequestMethod.POST, value = "/file-upload/{profileName:.+}")
public Attachment uploadFile(#RequestParam("file") MultipartFile input,
#PathVariable("profileName") String profileName) throws IOException {
Attachment attachment = new Attachment();
if (input != null) {
log.info("Upload a new attachment item" + input.getName());
byte[] fileByteArray = input.getBytes();
attachment.setEncodedFile(Utils.encodeBytes(fileByteArray));
attachment.setFileName(input.getOriginalFilename());
socialMediaService.uploadMedia(input, profileName);
}
return attachment;
}
SocialMediaService
public String uploadMedia(MultipartFile input, String profileName) {
String mediaUploadPath = "wall_attach/lenne-public";
Map < String, String > params = new HashMap < > ();
String mediaUploadFullPath =
UrlBuilder.build(System.getenv(Constants.HUBZILLA_URL), mediaUploadPath, params);
if (!isRestServiceProvided) {
restService = new RestService(RequestType.POST, mediaUploadFullPath);
}
MultipartEntityBuilder builder = restService.getEntityBuilder();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
try {
builder.addBinaryBody("userfile", input.getBytes(), ContentType.DEFAULT_BINARY, input.getOriginalFilename());
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
String strResp = restService.execute(profileName, Constants.HUBZILLA_PW);
return strResp;
}
return null;
}
RestService class
public class RestService {
private Logger log;
private HttpClient client = null;
private HttpRequest request = null;
private RequestType reqType = null;
private String body;
MultipartEntityBuilder builder = null;
public RestService() {
this.log = LoggerFactory.getLogger(RestService.class);
}
/**
* Create REST service with external parameters.
*
* #param reqType RequestType
* #param client HttpClient
* #param request External HttpRequest
*/
public RestService(RequestType reqType, HttpClient client, HttpRequest request, Logger log) {
this.reqType = reqType;
this.client = client;
this.request = request;
this.log = log;
}
/**
* Create REST service string parameters.
*
* #param reqType RequestType
* #param fullPath Full path of REST service
*/
public RestService(RequestType reqType, String fullPath) {
this.client = HttpClientBuilder.create().build();
this.reqType = reqType;
this.log = LoggerFactory.getLogger(RestService.class);
if (reqType == RequestType.GET) {
this.request = new HttpGet(fullPath);
} else if (reqType == RequestType.POST) {
this.request = new HttpPost(fullPath);
} else if (reqType == RequestType.DELETE) {
this.request = new HttpDelete(fullPath);
}
}
/**
* Execute REST service without authentication.
*
* #return - Result of the service.
*/
public String execute() {
return execute(null, null);
}
/**
* Execute REST web service with basic authentication.
*
* #return - Result of the service.
*/
public String execute(String user, String password) {
try {
if (user != null && password != null) {
StringBuilder authString = new StringBuilder();
authString.append(user).append(":").append(password);
String authBase = new String(
Base64.getEncoder().encode(authString.toString().getBytes(Charset.forName("UTF-8"))));
String authType = "Basic ";
String authHeader = authType + authBase;
request.setHeader(HttpHeaders.AUTHORIZATION, authHeader);
}
HttpResponse response = null;
if (this.reqType == RequestType.GET) {
HttpGet get = (HttpGet) request;
response = client.execute(get);
} else if (this.reqType == RequestType.POST) {
HttpPost post = (HttpPost) request;
if (body != null) {
StringEntity stringEntity = new StringEntity(body);
post.setEntity(stringEntity);
}
if (builder != null) {
HttpEntity entity = builder.build();
post.setEntity(entity);
}
response = client.execute(post);
} else {
throw new NotImplementedException();
}
if (response != null && (response.getStatusLine().getStatusCode() == Status.OK.getStatusCode()
|| response.getStatusLine().getStatusCode() == Status.CREATED.getStatusCode())) {
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity);
}
} catch (Exception e) {
log.error("External service call failed ", e);
}
return null;
}
public void setBody(String body) {
this.body = body;
}
public MultipartEntityBuilder getEntityBuilder() {
this.builder = MultipartEntityBuilder.create();
return this.builder;
}
}
My problem is not getting any result after I executed the rest service upload media method. But it worked perfectly via postman.
Can anybody let me know what am I missing? Is the way I constructed the form data in java correct?
Thank you in advance.
Try adding consumes parameter in #RequestMapping like this (consumes = "multipart/form-data")
#RequestMapping(method = RequestMethod.POST, consumes = "multipart/form-data" ,value = "/file-upload/{profileName:.+}")
public Attachment uploadFile(#RequestParam("file") MultipartFile input,
#PathVariable("profileName") String profileName) throws IOException {
----
----
}
There is another relevant issue here:
Trying to upload MultipartFile with postman
Please read the comments under answer in this link.
Hope it helps!
I am trying to apply Around advice to my "Login.jsp" with angular js. And the problem is my controller method is check and I am applying around advice to check method but when I run my application I will get undefined as response at Login.jsp. And but the result which I had printed in my advice contains expected result.But I am not getting it on client side.
AroundAdvice.java
#Aspect #Component
public class AroundAdvice {
static Logger log = Logger.getLogger(AfterLoginAspect.class.getName());
#Around("execution(* com.admin.controller.LoginController.check(..))")
public void logWrittter(ProceedingJoinPoint jp) throws Throwable {
SimpleDateFormat date=new SimpleDateFormat();
log.info("Date Time :: " + date.format(new Date().getTime()));
Object result = jp.proceed();
System.out.println("result around");
log.info("result :: " + result);
// returns {"get Status":"home"}
}
}
LoginController.jsp
// authentication check
#RequestMapping(value = "/PostFormData", method = RequestMethod.POST)
public #ResponseBody JSONObject check(#RequestBody LoginBo login) {
System.out.println("checkCredentials::" + login.getUserName());
String username = login.getUserName();
// log.info("uswername ::"+username);
JSONObject result = new JSONObject();
String encrptedpassword = encryptdPwd.encrypt(login.getPassWord());
boolean login_status = loginService.checkCredentials(username, encrptedpassword);
// log.info("login_status ::"+login_status);
// System.out.println("staus ::"+login_status);
if (login_status == true && login.isIs_system_generated_pwd() == true) {
System.out.println("sys gen chnge pwd:: " + login.isIs_system_generated_pwd());
result.put("getStatus", "change");
// System.out.println(resultPage);
// login.setIs_system_generated_pwd(false);
} else if (login_status == true && login.isIs_system_generated_pwd() == false) {
result.put("getStatus", "home");
// System.out.println("Home paege ");
} else {
result.put("getStatus", "error");
}
System.out.println("result ::" + result);
// log.info("result ::"+resultPage);
return result;
}
Your pointcut does not match because the advice has a void return type, but your method returns a JSONObject. So maybe you want to change your advice declaration to:
#Aspect #Component
public class AroundAdvice {
static Logger log = Logger.getLogger(AfterLoginAspect.class.getName());
#Around("execution(* com.admin.controller.LoginController.check(..))")
public JSONObject logWriter(ProceedingJoinPoint jp) throws Throwable {
SimpleDateFormat date=new SimpleDateFormat();
log.info("Date Time :: " + date.format(new Date().getTime()));
JSONObject result = (JSONObject) jp.proceed();
System.out.println("result around");
log.info("result :: " + result);
return result;
}
}
Please note
public JSONObject logWriter instead of public void logWrittter,
JSONObject result = (JSONObject) jp.proceed(); instead of Object result = jp.proceed(); and
return result; instead of no return value.
I have a REST API that accepts 3 query params. When the query is called without any one of the query parameters, the API executes and returns the result. How do we make the queryparams mandatory? How can I add validation to check if all the parameters are present? Also, please let me know the best approach.
On a very simple level you could just inject the HttpServletRequest and check yourself:
#GET
public Response example(#Context HttpServletRequest request,
#QueryParam("name") String name) {
if (null == request.getParameter("name")) {
ResponseBuilder builder = Response.status(404);
return builder.build();
}
// Do something with name
}
Or you can implement something more elaborate using AOP. Here's a blog post about further options.
jersey doesn't give a mandatory parameter checking functionality out of the box. however you can do something like implementing your own annotation to achieve it.
Below is the annotation code:
#Target(value = ElementType.METHOD)
#Retention(value = RetentionPolicy.RUNTIME)
public #interface Required {
String[] value();
}
You also need a filter, below is the code:
public class RequiredParamResourceFilterFactory implements ResourceFilterFactory {
#Context
private transient HttpServletRequest servletRequest;
private class RequiredParamFilter implements ResourceFilter, ContainerRequestFilter {
private final String[] requiredParams;
protected List<String> parametersValueMissing;
private RequiredParamFilter(String[] requiredParams) {
this.requiredParams = requiredParams;
}
#Override
public ContainerRequest filter(ContainerRequest containerRequest) {
boolean missingMandatoryParameter = false;
List<String> missingParameters = new ArrayList<String>();
List<String> requiredParametersValueMissing = new ArrayList<String>();
List<String> URLParameters = getURLParameters(containerRequest.getQueryParameters());
List<String> methodRequiredParameters = Arrays.asList(requiredParams);
if (methodRequiredParameters != null) {
for (String methodRequiredParam : methodRequiredParameters) {
if (URLParameters == null) {
missingMandatoryParameter = true; //we will check this flag before returning result set to caller
missingParameters.add(methodRequiredParam);
} else if (!URLParameters.contains(methodRequiredParam)) {
missingMandatoryParameter = true; //we will check this flag before returning result set to caller
missingParameters.add(methodRequiredParam);
//Add to required parameters value missing List, only if the parameter is mandatory and value is not provided
// in the URL
} else if (parametersValueMissing.contains(methodRequiredParam)) {
requiredParametersValueMissing.add(methodRequiredParam);
}
}
if (missingMandatoryParameter && requiredParametersValueMissing.size() > 0) {
throw new YourCustomException("Missing Parameters = " + StringHelper.ArrayToString(missingParameters) +
"\nParameter value missing for " + StringHelper.ArrayToString(requiredParametersValueMissing));
} else if (missingMandatoryParameter) {
throw new YourCustomException("Missing Parameters = " + StringHelper.ArrayToString(missingParameters), MisbarErrorCode.VALIDATION_WRONG_INPUT_ERROR, "Customers");
} else if (requiredParametersValueMissing != null &&
requiredParametersValueMissing.size() > 0) {
throw new YourCustomException("Parameter value missing for " + StringHelper.ArrayToString(requiredParametersValueMissing));
}
}
return containerRequest;
}
#Override
public ContainerRequestFilter getRequestFilter() {
return this;
}
#Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
/**
* To fetch the parameters sent to webservice call, these will be used to find if required parameter
* are present or not
*
* #param queryParams the queryparams sent
* #return all the parameters sent in URL
*/
private List<String> getURLParameters(MultivaluedMap<String,String> queryParams) {
parametersValueMissing = new ArrayList<String>();
List<String> arr = new ArrayList<String>();
for(String key:queryParams.keySet())
{
arr.add(key);
if(queryParams.get(key)==null)
parametersValueMissing.add(key);
}
if(!arr.isEmpty())
return arr;
return null;
}
}
#Override
public List<ResourceFilter> create(AbstractMethod am) {
Required required = am.getAnnotation(Required.class);
if(required!=null)
{
return Collections.<ResourceFilter>singletonList(new RequiredParamFilter(required.value()));
}
return null;
}
}
Below sample shows how to use this annotation, so in below webservice; file_id and count are mandatory parameters:
#GET
#Produces(MediaType.APPLICATION_JSON+";charset=utf-8")
#Cacheable(isCacheable = true)
#Path("posts/clusters")
#Required({"file_id","count"})
#Timed
public Response getClusters(
#QueryParam("file_id") Integer fileId,
#QueryParam("count") Integer count,
#DefaultValue("-1")#QueryParam("start_time") Long startTime){
;
}
If mandatory parameters are not provided in webservice call, you receive an error like below, mentioning the parameter names that are missing:
{
message: "Missing Parameters = file_id, count",
errorCode: "600"
}
Hope this solves your problem.