1)I called action which generates jfreechart using next jsp(using tiles) code :
<s:url var="chart" action="resultChart"/>
<img src="<s:property value="%{chart}"/>"/>
2)struts.xml
<package name="chart" extends="jfreechart-default" namespace="/">
<action name="resultChart" class="com.examples.actions.ChartAction">
<result name="success" type="chart">
<param name="width"> 1200 </param>
<param name="height"> 600 </param>
</result>
</action>
</package>
3)to generate chart - I use request parameters from previous action :
public class ChartAction extends ActionSupport implements RequestAware {
private static final long serialVersionUID = 1L;
private Map request;
private JFreeChart chart;
public String execute() throws Exception {
DataBean dataBean = (DataBean)request.get("dataBean");
.....
}
My problem next : I cant draw chart because request return null(dataBean=null)
NOTE : Without passing request parameters all works fine
My research - I used next code in ChartAction(before request.get) to investigate problem:
ValueStack valuestack = ActionContext.getContext().getValueStack();
System.out.println("valuestack.size() = " + valuestack.size());
System.out.println("valuestack root = " + valuestack.getRoot().toString());
And I saw that in ValueStack no records from action which put parameter(dataBean) into request
Please help
Related
I have used MultipartFile in my controller but it is not taking the file value. Could you please help me?
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.OK)
public String uploadFileHandler(
final Model model,
#ModelAttribute final FileUploadModel fileUploadModel,
final BindingResult bindingResult,
final ImportCSVSavedCartForm importCSVSavedCartForm
) {
final String file = fileUploadModel.getCsvFile();
if (!file.isEmpty()) {
uploadExcelFile(file);
}
You have to add your bean into the following part of the spring-filter-config.xml as a new entry in your storefront extension.
<alias name="defaultFileUploadUrlFilterMappings" alias="fileUploadUrlFilterMappings" />
<util:map id="defaultFileUploadUrlFilterMappings" key-type="java.lang.String" value-type="org.springframework.web.multipart.support.MultipartFilter">
<entry key="/import/csv/*" value-ref="importCSVMultipartFilter"/>
</util:map>
importCSVMultipartFilter bean will give you a clue on how to do that.
I have a struts2 action, which sets some error using addActionError something like below
public String del() {
if (new OrdersService().get(idorder) == null) {
addActionError("Order not found");
} else {
new OrdersService().remove(idorder);
addActionMessage("Order deleted successfully");
}
return SUCCESS;
}
So the above method NO MATTER WHAT always return "success" result.
But in struts.xml I've used the redirect result-type to redirect to another action
and that action is never executed instead I'm getting result "input", I'm unable to understand what's going wrong ?
Is it something like
If an action sets an actionError, another action can't be executed and straight away "input" result will be thrown. But it doesn't make sense (at least to me)!
[EDIT] including some part of struts.xml
<action name="/order/{idorder:[0-9]+}/del" class="actions.OrderAction" method="del">
<interceptor-ref name="store">
<param name="operationMode">AUTOMATIC</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="success" type="redirect">orders</result>
</action>
The default stack includes the "workflow" interceptor.
If there are action or field errors this interceptor returns the "input" result, because there was an error.
Reading some documentation will point you in the right direction. Note that your errors will be lost on a redirect anyway, unless you specifically save them.
Also, if you want to redirect to an action, use the "actionRedirect" result type.
public String del() {
if (new OrdersService().get(idorder) == null) {
addActionError("Order not found");
return ERROR;
} else {
new OrdersService().remove(idorder);
addActionMessage("Order deleted successfully");
return SUCCESS;
}
}
Also include return type 'error' as you have done for return type 'success' in your action mapping in struts.xml
i am writing the client web jsp page just like having one form(get) with user name search text box and submit button
when the user submits it returns the json format of user
but the url looks like when i submit it
http://myhost.net:8080?user=pavan&method.execute=submit
how can i convert this url to below one in struts2 .
http://myhost.net:8080/user/pavan
is there any .htaccess file in struts2
#Results( { #Result(name = "success", type = "redirectAction") })
public class UsersController implements ModelDriven<Object>,
ServletRequestAware {
private String username;
private HttpServletRequest request;
private String representation;
// GET /users/{username}
public HttpHeaders show() {
String acceptHeader = request.getHeader("Accept");
String type = "xml";
if (acceptHeader == null || acceptHeader.isEmpty() ||
acceptHeader.equals("application/xml")) {
representation = UserBO.getXML(username);
} else if (acceptHeader.equals("application/json")) {
representation = UserBO.getJSON(username);
type = "json";
}
return new DefaultHttpHeaders(type).disableCaching();
}
You can use Parameters after the Action name.
To use parameters in the URL, after the action name, make sure this is set:
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
Then the action mapping will look like:
<package name="edit" extends="struts-default" namespace="/edit">
<action name="/person/*" class="org.apache.struts.webapp.example.EditAction">
<param name="id">{1}</param>
<result>/mainMenu.jsp</result>
</action>
</package>
When a URL like /edit/person/123 is requested, EditAction will be called, and its "id" field will be set to 123.
I have a few pages that needs a userId to work, thus the following code:
userpage.xhtml
<!-- xmlns etc. omitted -->
<html>
<f:metadata>
<f:viewParam name="userId" value="#{userPageController.userId}"/>
</f:metadata>
<f:view contentType="text/html">
<h:head>
</h:head>
<h:body>
<h:form>
<h:commandButton action="#{userPageController.doAction}" value="post"/>
</h:form>
</h:body>
</f:view>
userPageController.java
#Named
#ViewScoped
public class userPageControllerimplements Serializable {
private static final long serialVersionUID = 1L;
#Inject protected SessionController sessionController;
#Inject private SecurityContext securityContext;
#Inject protected UserDAO userDAO;
protected User user;
protected Long userId;
public UserPage() {
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
if(!FacesContext.getCurrentInstance().isPostback()){
User u = userDAO.find(userId);
this.userId = userId;
this.user = u;
}
}
public void doAction(){
}
}
However, after doAction is called, the view parameter in the url disappears. The bean still works due to its viewscoped nature, but it ruins my attempts of future navigation. When i search around, I get the impression that the view parameter should remain after a post thus reading userpage.jsf?userId=123, but this is not the case. What is really the intended behaviour?
Related to this, I've tried to implement automatic adding of view parameters when navigating to another page where I want to keep the userId. It seems to work for others, but for me, the userId in the ViewRoot is always null. Code below used to retrieve the viewparameter (i know i could use my temporarily stored userId in the bean for navigation, but this solution would be much fancier):
String name = "userId";
FacesContext ctx = FacesContext.getCurrentInstance();
ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler().getViewDeclarationLanguage(ctx, viewId);
ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId);
UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx);
UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME);
// Looking for a view parameter with the specified name
UIViewParameter viewParam = null;
for (UIComponent child : metadataFacet.getChildren()) {
if (child instanceof UIViewParameter) {
UIViewParameter tempViewParam = (UIViewParameter) child;
if (name.equals(tempViewParam.getName())) {
viewParam = tempViewParam;
break;
}
}
}
if (viewParam == null) {
throw new FacesException("Unknown parameter: '" + name + "' for view: " + viewId);
}
// Getting the value
String value = viewParam.getStringValue(ctx); // This seems to ALWAYS be null.
One last thought is that the setter methods still seem to work, setUserId is called with the correct value on post.
Have I completly missunderstood how view parameters work, or is there some kind of bug here? I think my use case should be extremly common and have basic support in the framework.
When i search around, I get the impression that the view parameter should remain after a post thus reading userpage.jsf?userId=123, but this is not the case. What is really the intended behaviour?
This behaviour is correct. The <h:form> generates a HTML <form> element with an action URL without any view parameters. The POST request just submits to exactly that URL. If you intend to keep the view parameters in the URL, then there are basically 3 ways:
Bring in some ajax magic.
<h:commandButton action="#{userPageController.doAction}" value="post">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
This way the initially requested page and thus also the request URL in browser's address bar remains the same all the time.
If applicable (e.g. for page-to-page navigation), make it a GET request and use includeViewParams=true. You can use <h:link> and <h:button> for this:
<h:button outcome="nextview?includeViewParams=true" value="post" />
However, this has an EL security exploit in Mojarra versions older than 2.1.6. Make sure that you're using Mojarra 2.1.6 or newer. See also issue 2247.
Control the generation of action URL of <h:form> yourself. Provide a custom ViewHandler (just extend ViewHandlerWrapper) wherein you do the job in getActionURL().
public String getActionURL(FacesContext context, String viewId) {
String originalActionURL = super.getActionURL(context, viewId);
String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
return newActionURL;
}
To get it to run, register it in faces-config.xml as follows:
<application>
<view-handler>com.example.YourCustomViewHandler</view-handler>
</application>
This is also what OmniFaces <o:form> is doing. It supports an additional includeViewParams attribute which includes all view parameters in the form's action URL:
<o:form includeViewParams="true">
Update: obtaining the view parameters of the current view programmatically (which is basically your 2nd question) should be done as follows:
Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());
for (UIViewParameter viewParam : viewParams) {
String name = viewParam.getName();
Object value = viewParam.getValue();
// ...
}
Am I right that for solution 1 <f:ajax execute="#form" render="#form" /> to work one would also have to include something like
<f:param name="userId" value="#{userPageController.userId}"/>
inside the <h:commandButton>?
Like it is described in https://stackoverflow.com/a/14026995/811046
My Action class have the following methods,
1.add
2.edit
3.loadEdit
4.remove
5.list
6.execute
in this i need to apply validation for add and edit..how do need to config in struts.xml.I followed,
<action name="editComment" method="edit"
class="com.mmm.ehspreg2.web.action.product.CommentAction">
<result name="success">/jsp/propertyManager/loadList.jsp</result>
</action>
<action name="removeComment" method="remove"
class="com.mmm.ehspreg2.web.action.product.CommentAction">
<interceptor-ref name="validation">
<param name="excludeMethods">remove</param>
</interceptor-ref>
<result type="tiles">listComment</result>
<result type="tiles" name="input">listComment</result>
</action>
When I configure it like this, remove action method is not getting called. I don't understand the problem. Please assist.
you can also use #SkipValidation before method initialization in action class
e.g.
#SkipValidation
public String save() {
String result = super.save();
if (result.equals(SAVE)) {
setMessage1(getText("save.successful"));
} else {
setMessage1(getText("save.unsuccessful"));
}
jsonResponse = new Hashtable<String, Object>();
jsonResponse.put(FIELD_JSONRESPONSE_STATUS,
KEY_JSONRESPONSE_MESSAGE_SUCCESS);
jsonResponse.put(FIELD_JSONRESPONSE_MESSAGE,
KEY_JSONRESPONSE_EMPTY_STRING);
jsonResponse.put(FIELD_JSONRESPONSE_VALUE, domainModel.getId());
// System.out.println("domainModel>>>>>>" + domainModel.getId());
return result;
}
Simply list all the methods you don't want to be run through the validation framework in the excludeMethods parameter. Since you only want add and edit validated, list the other 4 as follows:
<interceptor-ref name="validation">
<param name="excludeMethods">loadEdit,remove,list,execute</param>
</interceptor-ref>
You can read more about it in the Validation Interceptor docs.