Do Math in Java Spring - java

I'm trying to create add calculation in view, it was successfull, but how to create add operation's in controller?
here my code
public String jumlah(#RequestParam(value = "a") int angkaPertama, #RequestParam(value = "b") int angkaKedua, Model model) {
model.addAttribute("a", angkaPertama);
model.addAttribute("b", angkaKedua);
return "jumlah";
}
And i have one more question
here is my code:
<p th:text="'Welcome ' + ${name} + '!'">Good Morning</p>
Why "Good Morning" does'nt show up in my view?

Add #ResponseBody to the return type of method.And i hope you have proper request mapping for the url of your page.

Related

Using Object class as wrapper for input in spring boot RestController

I am bit new to spring boot and I am trying to design a search on user history which will provide 3 attributes to search user history {userId, searchKey, SearchValue}.
The search value datatype may differ based on search.
E.g
Userid=100, SearchKey=userAddress, searchValue='10 Downing Street'
Userid=100, SearchKey=external, searchValue=true
Userid=100, SearchKey=companyId, searchValue=25
I am trying to design a rest endpoint as below. This endpoint will integrate with react front end.
#GetMapping(value = "/searchUserHistoryByKeyValue")
public ResponseEntity<Object> searchUserHistoryByKeyValue(
#RequestParam(value = "userId") int userId,
#RequestParam(value = "searchKey") String searchKey,
#RequestBody Object searchValue) {
List<org.json.simple.JSONObject> entities =
userHistoryService.searchUserHisotryByKeyValue(userId, searchKey, searchValue);
return new ResponseEntity<>(entities, HttpStatus.OK);
}
I have implemented a dynamodb search on userhistory object which takes input as generic searchValue object as search filter as below.
Dynamo DB Querying - https://www.tutorialspoint.com/dynamodb/dynamodb_querying.htm
public List<JSONObject> searchUserHistoryByKeyValue(
int userId, String searchKey, Object searchValue) throws DataAccessException {
Table table = dynamoDB.getTable(userHistoryTable.getName());
Map<String, String> expressionAttributeNames =
DEFAULT_USER_FILTERS.stream()
.collect(
Collectors.toMap(attrib -> attrib, attrib -> attrib.substring(1), (a, b) -> b));
Optional<String> projectionExpression =
createProjectionExpression(
Collections.singletonList(searchKey), expressionAttributeNames);
Optional<String> filterProjectionExpression =
buildCustomProjectionExpression(
Collections.singletonList(searchKey), expressionAttributeNames);
QuerySpec querySpec =
new QuerySpec()
.withProjectionExpression(projectionExpression.orElse(StringUtils.EMPTY))
.withKeyConditionExpression("#userId = :userId")
.withFilterExpression(
String.format(
"%s = :searchValue",
filterProjectionExpression.orElseThrow(
() -> new IllegalArgumentException("Invalid Search Attributes"))))
.withNameMap(expressionAttributeNames)
.withValueMap(Map.of(":userId", userId, ":searchValue", searchValue))
.withScanIndexForward(false);
When I am trying use swagger or postman to test this endpoint , I am not able to pass in
#RequestBody Object searchValue . it just shows as empty braces - {}
Also it shows below error as -
'TypeError: Failed to execute 'fetch' on 'Window': Request with
GET/HEAD method cannot have body. '
I am not able to make this work? Appreciate your insights on this.
It's HTTP protocol.
You cannot pass any body object with the Get method. You have to use Post or Put method for using a body in HTTP request.
#RequestBody not for single value it is intended for your custom object that is used with POST or PUT but in you case you can #RequestParam also if #RequestParam take attribute required with boolean vlue which tell your endpoint caller which params is optional if you set it False and which is required if you set it True

How to share information between Spring controller methods from GET and POST requests?

I'm new to Spring and I want to:
1) when an user visits localhost/admin/users I want the predefined options to apply
2) On localhost/admin/users I have some buttons that perform a POST with four parameters because my boss don't want me to use get (and I think is better to use POST, too)
3) I have a controller method adminUsersPost that manages the POST request, and I want that method to be able to make my browser to reload using the adminUsersGet method, but with the information sent in the POST request.
What I'm getting now in my browser is an alert with a webpage content in some weird encoding, I hope it is correct but I don't know.
#RequestMapping(value = "/admin/users", method = RequestMethod.GET)
public ModelAndView adminUsersGet(
Integer page,
Integer items,
String sorting,
String sortingDirection)
{
// predefined options
Integer pagina = 1;
Integer itemsPorPagina = 10;
String ordenacion = "idUsuario";
String dirOrdenacion = "asc";
// end of predefined options
// Code that I want for it to use POST params from the other method
ModelAndView mv = new ModelAndView("adminUsers");
return mv;
}
#RequestMapping(value = "/admin/users", method = RequestMethod.POST)
public ModelAndView adminUsersPost(
#RequestParam(value = "pagina") Integer pagina,
#RequestParam(value = "itemsPorPagina") Integer itemsPorPagina,
#RequestParam(value = "ordenacion") String ordenacion,
#RequestParam(value = "dirOrdenacion") String dirOrdenacion)
{
// Here I try to pass the POST parameters to the GET method for reloading
// the webpage with the new content
return adminUsersGet(pagina, itemsPorPagina, ordenacion, dirOrdenacion);
}
The pattern POST params-->GET same parameters is a common one. What you need is RedirectAttributes which will store your parameters into the session and redirect to your GET method. Once the GET is hit spring will automatically remove all attributes from the session, thus none of the POST parameters will be displayed in the browser url in the GET method. Have a look here for a complete example and adjust it for your needs.

How to accept 2D arrays in Spring MVC controller?

I'm making a POST request via jQuery Ajax:
$.ajax({
type: "POST",
url: opts.save_url,
data: $(ul_obj).serializeFormList() + "&form_id=" + form_db_id,
});
The $(ul_obj).serializeFormList() creates a 2D array of request params.
Here's the screengrab of the params passed to the Spring MVC controller:
Now when I handle this in the Controller I get 404 Bad Request for frmb[][]
Here's the code:
public #ResponseBody String saveData(#RequestParam(value= "form_id", required = true) String formId,
#RequestParam(value= "frmb", required = true) String[][] formArray) {
//Content removed for brevity
}
What is the exact way to handle this request data? Please guide me. I'm stuck real bad.
As I see you are concatenating the parameters
"&form_id=" + form_db_id
you can do the same for "frmb"
frmb=1,2&frmb=2,3
so when you try get the String [][] using
#RequestParam(value= "frmb", required = true) String[][] formArray)
you will get
formArray = [[1,2],[2,3]]
Java has only index (integer) based Arrays:
So either you make your request using only integer based arrays:
form_Id
frmb[0][0] input_text
frmb[0][1] required
frmb[0][values] sdfsfds
or you use an other structure to fetch the data: For example an Array containing a Map
#RequestParam(value= "frmb", required = true) Map<String,String>[] formArray
If you are able to modify the sended json, then I would recommend to use a JavaBean instead of the Map

#ModelAttribute is returning something wrong

I'm building an application that has these methods in the Controller for a form handling:
//This will prepare the model and populate the form
#RequestMapping(value="verbete",method = RequestMethod.GET, params="new")
public String addVerbete(#ModelAttribute("verbeteform") VerbeteForm verbeteForm,
Map<String, Object> model){
verbeteForm.getNomes().add(new NomesVerbete());
// add one significado
verbeteForm.getSignificados().add(new SignificadosVerbete());
// depois de implementar o Security
verbeteForm.getVerbete().setAutor(usuarioService.buscarUsuarioPorLogin("greati"));
// seta a data
verbeteForm.getVerbete().setDataLancamento(new Date());
// popula categorias
verbeteForm.setCategorias(verbeteService.listarCategorias());
return "editorVerbete";
}
#RequestMapping(value="verbete", params="new", method = RequestMethod.POST)
public String addVerbeteFromForm(#ModelAttribute("verbeteform") VerbeteForm verbeteForm,
Map<String, Object> model){
Verbete verbete = verbeteForm.getVerbete();
List<NomesVerbete> nomes = verbeteForm.getNomes();
List<SignificadosVerbete> significados = verbeteForm.getSignificados();
long idVerbeteSalvo = verbeteService.addVerbete(verbete);
Verbete verbeteSalvo = verbeteService.getVerbetePorId(idVerbeteSalvo);
for(NomesVerbete nome:nomes){
nome.setVerbete(verbeteSalvo);
verbeteService.addNomesVerbete(nome);
}
for(SignificadosVerbete significado:significados){
significado.setVerbete(verbeteSalvo);
significado.setCategoria(verbeteService.getCategoriaPorNome(significado.getCategoria().getNome()));
verbeteService.addSignificadosVerbete(significado);
}
return "editorVerbete";
}
So, I was expecting that the date and the author would be setted in the model, but, when I submit the form, it says that the attributes dataLancamento (it's a date) and autor are not in the model, throwing an error because they cannot be null in the database.
Maybe I didn't understand how #ModelAttribute works, or maybe I'm doing something wrong.
A solution would be set the dataLancamento and autor in the second method, but I don't know if it's right. So, could you show me a way?
(Some words are in Portuguese... Please, tell me if it's a problem.)
When the first method is execute and the form is rendered the first time, the autor should be in the model. So using ${verbeteform.autor} should print the autor field.
But when you submit the form, the model is fullfilled with the data in the form. So if the form doesnt have a autor field like:
<form:form modelAttribute="verbeteform" method="POST">
<form:input path="autor"/>
</form:form>
the value is not added to the model, so in the second controller you have a null value in the autor field because the model is regenerated.

Get request parameter with Play Framework?

I am learning play framework and understand that I can map a request such as /manager/user as:
GET /manage/:user Controllers.Application.some(user:String)
How would I map a request like /play/video?video_id=1sh1?
You have at least two possibilities, let's call them approach1 and approach2.
In the first approach you can declare a routes param with some default value. 0 is good candidate, as it will be easiest to build some condition on top of it. Also it's typesafe, and pre-validates itself. I would recommend this solution at the beginning.
Second approach reads params directly from request as a String so you need to parse it to integer and additionally validate if required.
routes:
GET /approach1 controllers.Application.approach1(video_id: Int ?=0)
GET /approach2 controllers.Application.approach2
actions:
public static Result approach1(int video_id) {
if (video_id == 0) return badRequest("Wrong video ID");
return ok("1: Display video no. " + video_id);
}
public static Result approach2() {
int video_id = 0;
if (form().bindFromRequest().get("video_id") != null) {
try {
video_id = Integer.parseInt(form().bindFromRequest().get("video_id"));
} catch (Exception e) {
Logger.error("int not parsed...");
}
}
if (video_id == 0) return badRequest("Wrong video ID");
return ok("2: Display video no. " + video_id);
}
PS: LOL I just realized that you want to use String identifier... anyway both approaches will be similar :)
I would do it simply using:
GET /play/video Controllers.Application.video(video_id:String)
And at controller you would of course have, something like:
public static Result video(String video_id) {
return ok("We got video id of: " + video_id);
}
Alternatively, you dont have to add video_id:String since play seems to treat parameters as String by default, so it also works like this (at least with newest play):
GET /play/video Controllers.Application.video(video_id)
Typing localhost:9000/play/video?video_id=1sh1 to address bar should now you give view which prints:
We got video id of: 1sh1
To add more parameters is simple, like this:
GET /play/video controllers.Application.video(video_id:String, site:String, page:Integer)
Controller:
public static Result video(String video_id, String site, Integer page) {
return ok("We got video id of: " + video_id + " site: " + site + " page: " + page);
}
Typing localhost:9000/play/video?video_id=1as1&site=www.google.com&page=3 to address bar should now you give view which prints:
We got video id of: 1as1 site: www.google.com page: 3
You're welcome ^^.
I'm not quite sure if I got what you meant if you meant just to map a url to function in controller the answer of biesior is perfect but if you mean submitting a form with get method like
#helper.form(action = routes.YourController.page1()) {
}
and having the form's parameter in the url in the url-rewrited format like
page1/foo/bar instead of page1?param1=foo&param2=bar
There is no way to do that because that's http specs
I do often circumvent this limitation by getting the parameters in the first function in controller and then redirect them to another view just like the following
public static Result page1(){
String param1 = Form.form().bindFromRequest().get("param1");
String param2= Form.form().bindFromRequest().get("param2");
return ( redirect( routes.YourController.page2(param1,param2)));
}
Then have whatever in the page2
public static Result page2(String param1,String param2){
...............
}
And have this in the routes file :
GET page2/:param1/:param2 controllers.YourControllers.page2(param1 : String, param2 : String )
I hope it'd help but I'm not sure that's the best practise
Ok so I just read up the documentation and what I understand is that you need to
GET /play/video Controllers.Application.video()
And then in the controller call the getQueryString of the HttpRequest object
http://www.playframework.com/documentation/api/2.1.0/java/index.html

Categories

Resources