Spring attribute not being added to model - spring

I want to add some attributes to the model, but for some reason, one of the attributes isn't being added to the model for a specific request handler.
The two attributes are numberDeleted and usersDeleted.
usersDeleted for some reason is not added to the model on the third request handler.
Here is the code: (Note: Some lines of code has been removed for brevity. Only the relevant code is displayed).
First I delete some selected users:
#RequestMapping(value = "/delete", method = RequestMethod.DELETE)
public String delete(
#ModelAttribute("credentials") Credentials credentials,
#ModelAttribute("deleteUsersForm") DeleteUsersForm form,
#ModelAttribute("searchCriteria") SearchForm searchForm,
Model model, RedirectAttributes redirect) {
String[] usersDeleted = form.getCheckedUsers();
if (usersDeleted != null) {
for (int i = 0; i < usersDeleted.length; i++) {
System.out.println("user (delete): " + usersDeleted[i]);
}
}
redirect.addFlashAttribute("usersDeleted", usersDeleted);
redirect.addFlashAttribute("numberDeleted", numberDeleted);
redirect.addFlashAttribute("searchForm", searchForm);
return "redirect:" + searchForm.getSelectedOption();
}
After the chosen users are deleted from the database, I make a REST API call to get the currently existing users and add them to the model, as well as the numberDeleted and usersDeleted from the delete function above:
#RequestMapping(value = "/getAllUsers", method = RequestMethod.GET)
public String getAllUsers(#ModelAttribute Credentials credentials,
RedirectAttributes redirect, Model model) {
SearchForm searchForm = new SearchForm("/getAllUsers", "allUsers");
redirect.addFlashAttribute("users", users);
redirect.addFlashAttribute("searchCriteria", searchForm);
/* If users deleted: */
Integer numberDeleted = (Integer) model.asMap().get("numberDeleted");
String[] usersDeleted = (String[]) model.asMap().get("usersDeleted");
redirect.addFlashAttribute("numberDeleted", numberDeleted);
redirect.addFlashAttribute("usersDeleted,", usersDeleted);
if (usersDeleted != null) {
for (int i = 0; i < usersDeleted.length; i++) {
System.out.println("user: (getAllUsers) " + usersDeleted[i]);
}
}
return "redirect:/adminHome";
}
The usersDeleted and numberDeleted are not null up to this point and I can print out their value.
Then I call the request to list the users:
#RequestMapping(value = "/adminHome", method = RequestMethod.GET)
public String getAdminHomePage(Model model) {
SearchForm searchCriteria = (SearchForm) model.asMap().get(
"searchCriteria");
/* If users were deleted: */
Integer numberDeleted = (Integer) model.asMap().get("numberDeleted");
String[] usersDeleted = (String[]) model.asMap().get("usersDeleted");
model.addAttribute("numberDeleted", numberDeleted);
model.addAttribute("usersDeleted,", usersDeleted);
if (usersDeleted != null) {
for (int i = 0; i < usersDeleted.length; i++) {
System.out.println("user: (adminhome) " + usersDeleted[i]);
}
}
.....
return "admin_home";
}
However, at this point, usersDeleted is null (since nothing prints out) but numberDeleted is not null.
I literally do not understand what is going on. How come it is null? I explicitly added it to the model.
EDIT 1:
Currently, my only workaround is to add usersDeleted to #SessionAttributes.
But I should not have to resort to this.

As per #Kingamere comments, I am posting this. There was a typo on the model key.
model.addAttribute("usersDeleted,", usersDeleted);
There was an extra comma at the end of the usersDeleted. After you remove that comma, it works perfectly for Kingmere.
model.addAttribute("usersDeleted", usersDeleted);

Related

.net web api AuthorizeAttribute pass parameter to the controller

A AuthorizedAttribute named as JwtAuthenticateAttribute is implemented and did something
It can be triggered for each request of the below API
[HttpGet]
[JwtAuthenticate]
public GetFaqListDS Index([FromUri] GetFaqListModel model)
{
List<MP_faqs> res = Faq.GetFaqList(model.curPage, model.pageSize);
var re = Request;
var hds = re.Headers;
GetFaqListDS ds = new GetFaqListDS();
ds.data = res;
return ds;
}
The question is, how to pass a value to this controller's function from the Attribute JwtAuthenticate.
P.S the value exists at the OnAuthorization of this attribute.
Thanks.
Add the required value in "actionContext.Request.Properties" in Onauthorize method and access these in controller.
Adding UserDetail Model :
actionContext.Request.Properties.Add("__user", new UserDetails(){userid=123, username="ABC"});
Retrieving values :
private static UserDetails GetUserDetailsFromRequest()
{
object tempVal;
try
{
var httpRequestMessage = (HttpRequestMessage)HttpContext.Current.Items["MS_HttpRequestMessage"];
httpRequestMessage.Properties.TryGetValue("__user", out tempVal);
if (tempVal == null) return null;
var user = (UserDetails)tempVal;
return user;
}
catch
{
}
return new UserDetails();
}
Hope this will helps you.

Is it possible to go to another page with #ResponseEntity in Spring MVC?

I have a page with many items on it. Each one has a button, that is supposed to take user to another jsp with another layout for detailed information about the current item. Can I even do this with ResponseEntity, as it doesn't redirect anywhere? Or may be there's some better way to do it and send my Object to the page? I tried "ResponseEntity.created(location).body(object)" but it doesn't do the job, I stay on the same page. May be I'm just using it wrong?
My method:
#RequestMapping(value = {"/details+{id}"}, method = RequestMethod.GET)
public ResponseEntity<Item> details(#PathVariable("id") int id) {
Item item = itemService.findById(id);
if(item == null){
return new ResponseEntity<Item>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<Item>(item, HttpStatus.OK);
}
Have a look at ModelAndView. It's purpose is to return a view with attached model to it. So for each value of the id, you can decide a pair of view and model to return.
#RequestMapping(value = {"/details+{id}"}, method = RequestMethod.GET)
public ModelAndView details(#PathVariable("id") int id) {
String viewToUse;
Map<String, Item> modelToUse;
if(id == ...) {
viewToUse = ...
modelToUse = ...
} else if (id == ...) {
viewToUse = ...
modelToUse = ...
} else if (id == ...) {
viewToUse = ...
modelToUse = ...
}
return new ModelAndView(viewToUse, modelToUse);
}

Hashmap value changed after requesting from session

I work on Java/HTML project. I've set a hashmap as a session attribute. I request the hashmap from session and put key/value in it
map.put("some string", "1")
. When this action is performed the second time, I print the hashmap content and the only value, that was '1' after the last operation on the hashmap, becomes '-1'.
Hashmap is the best data structure, in my opinion, for this project. Can anyone help?
public class Cart {
private HashMap<String, asd> list;
public Cart(){
list = new HashMap<String, asd>();
}
public HashMap<String, asd> getMap(){
return list;
}
/*
* Parameter: code
* -1: increase quantity by 1
* 0: delete product from the product list
* else: set the product quantity to the passed value
*/
public void alterProduct(int code, String product){
if(list.containsKey(product)) {
if(code == -1) plusOne(product);
if(code == 0) remove(product);
else setValue(product, code);
}else {
asd asd = new asd();
asd.a = 1;
list.put(product, asd);
}
}
private void plusOne(String product){
asd asd = list.get(product);
asd.a = asd.a + 1;
list.put(product, asd);
}
private void remove(String product){
list.remove(product);
}
private void setValue(String product, int code){
asd asd = new asd();
asd.a = code;
list.put(product, asd);
}
}
class asd{
int a;
public String toString(){
return ""+a;
}
}
JSP code where I set Cart object as session attribute:
<%
Cart myCart = new Cart();
session.setAttribute("cart",myCart);
%>
Servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Cart cart = (Cart) request.getSession().getAttribute("cart");
cart.alterProduct(-1, (String) request.getSession().getAttribute("name"));
doGet(request, response);
}
After I call alterProduct the second time for the same (String) request.getSession().getAttribute("name") the hashmap value for the same key is '-1'.
What is type/value of product? How it is connected to the "cart"?
I guess what's happen that you mess up data types. Another option is you have bug in the Cart.toString() method. I suggest you change the code with "plain" data type and recheck it. If it fails, use your Cart class without messy conversion and debug the code.
You have bug here:
public void alterProduct(int code, String product){
if(list.containsKey(product)) {
if(code == -1) plusOne(product);
if(code == 0) remove(product);
else setValue(product, code);
}
private void setValue(String product, int code){
asd asd = new asd();
asd.a = code;
list.put(product, asd);
}
Consider what happen when you call art.alterProduct(-1, "something") second time.
list.containsKey(product) is true (you use the same product"), code is -1. So
if(code == -1) plusOne(product); is executed as expected.
But then you have something weired
if(code == 0) remove(product);
else setValue(product, code);
code ==0 is evaluated to false, so else instruction is called. You are calling setValue(product, -1)
As you can see above setValue will assign -1 to the asd.a that is observed by you.

how to use two submitt in one jsp and call two actions

i am working with spring mvc framework. i have two submit buttons on a page. that are forwarding request to two different controller. how can i use two action on single jsp page .
please suggest.
my controller are as
1.
#RequestMapping(value = "/user/reset", method = RequestMethod.POST)
public String editUser(#ModelAttribute("users") User user,
BindingResult result) {
Integer uid=user.getId();
User resetUser = usersService.findUser(uid);
resetUser.setActive(0);
ResetPasswordLog resetPasswordLog=new ResetPasswordLog();
usersService.addUsers(resetUser);
resetPasswordLogService.setTempHash(uid);
String TEMPHASH= resetPasswordLog.getTempHash();
System.out.println("www.lacas.com/reset?uid="+uid+"&th="+TEMPHASH);
return "redirect:/secure/user/" + uid;
}
2.
#RequestMapping(value = "/user/edit", method = RequestMethod.POST)
public String addUser(#ModelAttribute("users") UserForm userForm,
BindingResult result) {
Map<String, String> map = new LinkedHashMap<String, String>();
User user = usersService.findUser(userForm.getId());
Integer userId = userForm.getId();
User newUser = usersService.findUser(userForm.getEmail());
user.setName(userForm.getName());
if (newUser == null) {
user.setEmail(userForm.getEmail());
user.getRoles().clear();
Integer[] roleIds = userForm.getRoleIds();
for (Integer roleId : roleIds) {
if (roleId != 0) {
Role role = roleService.findRole(roleId);
user.getRoles().add(role);
}
}
usersService.addUsers(user);
return "redirect:/secure/users/index";
} else {
edit_exist_user = true;
return "redirect:/secure/user/" + userId;
}
}
You can by using JavaScript, and changing form's action attribute dynamically. If this is your form:
<form id="myform" action="#" onsubmit="return pickDestination();">
<input type="submit" name="sbmitbtn" value="edit" onclick="document.pressed=this.value"/>
<input type="submit" name="sbmitbtn" value="reset" onclick="document.pressed=this.value"/>
</form>
Then your pickDestination JS function would look like:
function pickDestination()
{
var a = "/user/" + document.pressed;
document.getElementById("myform").action = a;
return true;
}
I'm going to preface this by saying that I'm not very familiar with spring applications, however in many other java based MVC systems I've accomplished this by simply giving my submit buttons a name and parsing off this in the action class by checking the request.
For example find which submit button was used by it's parameter name, call the appropriate methods. The following is an example of a struts based solution I use on occasion. If you can access the servlet request object in your spring controller, you could do something similar.
#Override
public String execute() throws Exception {
try {
// Check the request for a someone clicking the logout submit button
if (found("logout")) {
user.logout(); //invoke the logout method
session.remove("user");
return SUCCESS;
}
// Check the request for a someone clicking the login submit button
if (found("login")) {
user.login();
session.put("user", user);
return "login";
}
// Catch any login exceptions
} catch (Exception e) {
user = null;
addActionError(e.getMessage());
return INPUT;
}
return SUCCESS;
}
// The following method checks for a request paramater based on the key (String)
// provided. If the key is not found or the value for the parameters is empty, it
// returns false;
private boolean found(String param) {
Object temp = request.getParameter(param);
if (temp != null) {
if (temp.toString().isEmpty()) {
return false;
}
return true;
} else {
return false;
}
}

Page expired issue with back button and wicket SortableDataProvider and DataTable

I've got an issue with SortableDataProvider and DataTable in wicket.
I've defined my DataTable as such:
IColumn<Column>[] columns = new IColumn[9];
//column values are mapped to the private attributes listed in ColumnImpl.java
columns[0] = new PropertyColumn<Column>(new Model<String>("#"), "columnPosition", "columnPosition");
columns[1] = new PropertyColumn<Column>(new Model<String>("Description"), "description");
columns[2] = new PropertyColumn<Column>(new Model<String>("Type"), "dataType", "dataType");
Adding it to the table:
DataTable<Column> dataTable = new DataTable<Column>("columnsTable", columns, provider, maxRowsPerPage) {
#Override
protected Item<Column> newRowItem(String id, int index, IModel<Column> model) {
return new OddEvenItem<Column>(id, index, model);
}
};
My data provider:
public class ColumnSortableDataProvider extends SortableDataProvider<Column> {
private static final long serialVersionUID = 1L;
private List<Column> list = null;
public ColumnSortableDataProvider(Table table, String sortProperty) {
this.list = Arrays.asList(table.getColumns().toArray(new Column[0]));
setSort(sortProperty, true);
}
public ColumnSortableDataProvider(List<Column> list, String sortProperty) {
this.list = list;
setSort(sortProperty, true);
}
#Override
public Iterator<? extends Column> iterator(int first, int count) {
/*
first - first row of data
count - minimum number of elements to retrieve
So this method returns an iterator capable of iterating over {first, first+count} items
*/
Iterator<Column> iterator = null;
try {
if(getSort() != null) {
Collections.sort(list, new Comparator<Column>() {
private static final long serialVersionUID = 1L;
#Override
public int compare(Column c1, Column c2) {
int result=1;
PropertyModel<Comparable> model1= new PropertyModel<Comparable>(c1, getSort().getProperty());
PropertyModel<Comparable> model2= new PropertyModel<Comparable>(c2, getSort().getProperty());
if(model1.getObject() == null && model2.getObject() == null)
result = 0;
else if(model1.getObject() == null)
result = 1;
else if(model2.getObject() == null)
result = -1;
else
result = ((Comparable)model1.getObject()).compareTo(model2.getObject());
result = getSort().isAscending() ? result : -result;
return result;
}
});
}
if (list.size() > (first+count))
iterator = list.subList(first, first+count).iterator();
else
iterator = list.iterator();
}
catch (Exception e) {
e.printStackTrace();
}
return iterator;
}
The problem is the following:
- I click a column header to sort by that column.
- I navigate to a different page
- I click Back (or Forward if I do the opposite scenario)
- Page has expired.
It'd be nice to generate the page using PageParameters but I somehow need to intercept the sort event to do so.
Any pointers would be greatly appreciated. Thanks a ton!!
I don't know at a quick glance what might be causing this, but in order to help diagnose, you might want to enable debug logging for org.apache.wicket.Session or possibly more of the wicket code.
The retrieval of a page definitely involves calls to a method
public final Page getPage(final String pageMapName, final String path, final int versionNumber)
in this class, and it has some debug logging.
For help with setting up this logging, have a look at How to initialize log4j properly? or at the docs for log4j.

Resources