spring mvc requestmapping dynamic url - java

How do I change my request mapping for dynamic urls? URLs might look like this:
http://zz.zz.zz.com:8080/webapp/p1/q9/e3/test?Id=2&maxrows=5
http://zz.zz.zz.com:8080/webapp/a1/b2/c3/test?Id=2&maxrows=5
http://zz.zz.zz.com:8080/webapp/x1/y2/z3/test?Id=2&maxrows=5
Here's the working controller syntax when the url is in this format:
http://zz.zz.zz.com:8080/webapp/test?Id=2&maxrows=5
#RequestMapping(value = "/test", method = RequestMethod.GET)
public #ResponseBody void test(
#RequestParam(value = "Id", required = true) String Id,
#RequestParam(value = "maxrows", required = true) int maxrows
) throws Exception {
System.out.println("Id: " + Id + " maxrows: " + maxrows);
}

Try this:
#RequestMapping(value = "/test/{param1}/{param2}/{param3}")
public #ResponseBody void test(
#RequestParam(value = "Id", required = true) String Id,
#RequestParam(value = "maxrows", required = true) int maxrows,
#PathVariable(value = "param1") String param1,
#PathVariable(value = "param2") String param2,
#PathVariable(value = "param3") String param3) {
...
}
For more information look at Spring Reference Documentation

Related

Unit testing for Spring MVC controller with Date value as #RequestParam

Please help me to pass this Date object to MVCMock.
Since param() only accepts String as values.
I am not sure how to pass Date value here
MockHttpServletRequestBuilder mvcBuilder = get("/pam/holdings/getholdings")
.accept(MediaType.ALL)
.flashAttr("holdingsFilterViewData", holdingsFilter)
.param("group","")
.param("account","")
.param("selectedHoldingsview","");
public String loadSelectedHoldings(
#ModelAttribute("holdingsFilterViewData") HoldingsFilter holdingsFilter,
#RequestParam(value = "account", required = false) String account,
#RequestParam(value = "group", required = false) String group,
#RequestParam(value = "asOfDate", required = false) Date asOfDate,
#RequestParam(value = "selectedHoldingsview", required = false) String selectedViewName,
Model model, HttpServletResponse servletResponse)
throws NoUserLoggedInException, NoKeyOfTypeFoundException,
ParseException, IOException {

Spring Unit Testing File Upload

I am trying to test file upload using spring test.
#Test
public void testUploadDocument() {
File f = new File("C:\\Users\\JC\\Documents\\sample_test_2.xlsx");
System.out.println(f.isFile()+" "+f.getName()+f.exists());
FileInputStream fi1 = new FileInputStream(f);
MockMultipartFile fstmp = new MockMultipartFile("file", f.getName(), "text/plain", fi1);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
mockMvc.perform(MockMvcRequestBuilders.fileUpload("http://" + hostPort + "/AdminService/rest/document/saveDocument")
.file(fstmp)
.param("siteId","555").param("docTypeId","550").param("docSubTypeId", "5051").param("contentDate", "06-Oct-2017").param("contentDescription", "")
.param("docName", "Test Co-op Unit 2").param("isNewFile", "true"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
It is throwing Requested Method POST not supported even though I declared it as POST. Also I tried MockMvcRequestBuilders.post. But same problem.
#RequestMapping(value = "/saveDocument", method = RequestMethod.POST)
public ResponseEntity<String> saveDocument(
#RequestParam("siteId") Integer siteId, #RequestParam("docTypeId") Integer docTypeId,
#RequestParam("docSubTypeId") Integer docSubTypeId, #RequestParam("docName") String docName,
#RequestParam(value = "contentDescription", required = false) String contentDescription,
#RequestParam(value = "contentDate", required = false) String contentDate, #RequestParam(value = "docId", required = false) Integer docId,
#RequestParam(value = "isNewFile", required = false) boolean isNewFile,
#RequestParam(value = "file", required = false) MultipartFile file)

How to process twilio SMS status callback in java

I have following service method for SMS callback processing
#RequestMapping(value = "/", method = RequestMethod.POST)
#ResponseBody
public void processSms(#RequestParam(value = "MessageStatus", required = false) String messageStatus,
#RequestParam(value = "ApiVersion", required = false) String apiVersion,
#RequestParam(value = "SmsSid", required = false) String smsSid,
#RequestParam(value = "SmsStatus", required = false) String smsStatus,
#RequestParam(value = "To", required = false) String to,
#RequestParam(value = "From", required = false) String from,
#RequestParam(value = "MessageSid", required = false) String messageSid,
#RequestParam(value = "AccountSid", required = false) String accountSid){
TwilioCallBackResponse response = new TwilioCallBackResponse();
response.messageStatus = messageStatus;
response.apiVersion = apiVersion;
response.smsSid = smsSid;
response.smsStatus = smsStatus;
response.to = to;
response.from = from;
response.messageSid = messageSid;
response.accountSid = accountSid;
LOG.info("Incomming twilio callback: " + response.messageStatus);
smsService.processSmsCallback(response);
}
I can get and log response from twilio successfully.
Problem is that in twilio end response error is logged. Should I specify content type or respond with some response body? Any ideas?
This is from twilio log
and error 11200 HTTP retrieval failure is also logged
Status callbacks do not control application flow, so TwiML does not need to be returned in this instance; however, it's recommended that you respond to status callbacks with either a 204 No Content or a 200 OK with Content-Type: text/xml and an empty <Response/> in the body. Failure to respond properly will result in warnings in Debugger.
Ok, based on Jim answer this is what works for me and no more warnings on twilio side
#RequestMapping(value = "/", method = RequestMethod.POST, produces = "text/xml")
#ResponseBody
#ResponseStatus(value = HttpStatus.OK)
public String processSms(#RequestParam(value = "MessageStatus", required = false) String messageStatus,
#RequestParam(value = "ApiVersion", required = false) String apiVersion,
#RequestParam(value = "SmsSid", required = false) String smsSid,
#RequestParam(value = "SmsStatus", required = false) String smsStatus,
#RequestParam(value = "To", required = false) String to,
#RequestParam(value = "From", required = false) String from,
#RequestParam(value = "MessageSid", required = false) String messageSid,
#RequestParam(value = "AccountSid", required = false) String accountSid){
TwilioCallBackResponse response = new TwilioCallBackResponse();
response.messageStatus = messageStatus;
response.apiVersion = apiVersion;
response.smsSid = smsSid;
response.smsStatus = smsStatus;
response.to = to;
response.from = from;
response.messageSid = messageSid;
response.accountSid = accountSid;
LOG.info("Incomming twilio callback: " + JsonUtils.printJson(response));
smsService.processSmsCallback(response);
return "<Response/>";
}

Is it possible to using in elasticsearch spring data query IN like in MySQL?

I need using query IN like in MySQL so my question is it "is possible" ? I try find something in googl`e but with out result. If it possible how I should do that ?
Maybe use clousure should? But how in elasticsearch spring data I should use?
My code:
TransactionIndexRepository:
public interface TransactionIndexRepository extends ElasticsearchRepository<TransIndex, String> {
List<TransIndex> findBySellerIn(String sellers);
}
TransactionQueryController:
#RestController
public class TransactionQueryController {
private TransactionIndexRepository transactionIndexRepository;
private TransactionService transactionService;
#Autowired
public TransactionQueryController(TransactionService transactionService) {
this.transactionService = transactionService;
}
#RequestMapping(value = "/transaction/search", produces = MediaType.APPLICATION_JSON_VALUE)
private Map search(
#RequestParam(value = "commentText", required = false) String commentText,
#RequestParam(value = "commentType", required = false) Long commentType,
#RequestParam(value = "title", required = false) String title,
#RequestParam(value = "priceFrom", required = false) Long priceFrom,
#RequestParam(value = "priceTo", required = false) Long priceTo,
#RequestParam(value = "tsFrom", required = false) Long tsFrom,
#RequestParam(value = "tsTo", required = false) Long tsTo,
#RequestParam(value = "seller", required = false) Long seller,
#RequestParam(value = "item", required = false) Long item,
#RequestParam(value = "tree_cat", required = false) Long tree_cat,
#RequestParam(value = "buyer", required = false) Long buyer,
#RequestParam(value = "cat", required = false) Long cat,
#RequestParam(value = "sellers", required = false) String sellers,
Pageable pageable) {
System.out.println(transactionIndexRepository.findBySellerIn(sellers));
final TransIndexSearchParams searchParams = TransIndexSearchParams.builder()
.commentText(commentText)
.commentType(commentType)
.title(title)
.priceFrom(priceFrom)
.priceTo(priceTo)
.tsFrom(tsFrom)
.tsTo(tsTo)
.seller(seller)
.item(item)
.tree_cat(tree_cat)
.buyer(buyer)
.cat(cat)
.build();
return transactionService.searchByIndexParams(searchParams, pageable);
}
}
And I`v got ERROR:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
Whats wrong?
In your repository class, you can simply define a findByXyzIn() query method that takes a collection of strings, like this:
findByNameIn(Collection<String> names);
The equivalent DSL query that is going to be generated will look like this:
{
"bool": {
"must": {
"bool": {
"should": [
{
"field": {
"name": "name1"
}
},
{
"field": {
"name": "name2"
}
}
]
}
}
}
}

Spring RequestMapping URL with hierarchal values

Lets say I have a Category domain model object that follows a file tree structure. I want to be able to construct a RequestMapping annotation for the controller method so that
/category/art/macros
/category/people/weddings/2014/5-19
/category/sports/college/baseball/2014/5-19
can be handled by the minimum number of controller methods.
I already have one controller method defined:
#RequestMapping(value ={"/category/{category}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category){
model.addAttribute("message", category);
return "gallery";
}
This works for a single URL like
/category/sports
How can I adapt this to be more flexible?
The challenge is here that you can't make #PathVariable optional but you can have two or more controller methods which can call the same service code. So, for you three URL patterns you have to define three different controllers:
GET: /category/art/macros
#RequestMapping(value ={"/category/{category}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category){
model.addAttribute("message", category);
return "gallery";
}
GET: /category/people/weddings/2014/5-19
#RequestMapping(value ={"/category/{category}/{subcategory}/{year}/{date}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category,
#PathVariable(value = "subcategory") String subcategory,
#PathVariable(value = "year") String year,
#PathVariable(value = "date") String date
){
model.addAttribute("message", category, subcategory, year, date);
return "gallery";
}
GET: /category/sports/college/baseball/2014/5-19
#RequestMapping(value ={"/category/{category}/{subcategory}/{year}/{date}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category,
#PathVariable(value = "subcategory") String subcategory,
#PathVariable(value = "sub_sub_category") String sub_sub_category,
#PathVariable(value = "year") String year,
#PathVariable(value = "date") String date
){
model.addAttribute("message", category, subcategory, sub_sub_category, year, date);
return "gallery";
}
PS You can user #RequestParam which can be optional and reduce the number of controllers.

Categories