I have configured result as follows : Its my custom result type.
<result-types>
<result-type name="myBytesResult" class="blahblah.MyBytesResult" />
</result-types>
<action name="myAction" class="blahblah.MyAction">
<result name="success" type="myBytesResult">
<param name="pptId">${pptId}</param>
</result>
</action>
And my result has setter/getter for pptId and MyAction also has setter/getter for pptId. But when i check in my result, Its not setting pptId (I am getting ${pptId} as string in result). It seems its not getting getter from Action.
What could be reason for the same ?
The code MyAction
public String doDefault() {
System.out.println("Default Called");
setPptId("MyPpt");
return "success";
}
public byte[] getMyImageInBytes() throws Exception {
try {
//.....
} catch (Exception e) {
}
return null;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getPptId() {
return this.pptId;
}
public void setPptId(String pptId) {
this.pptId = pptId;
}
MyBytesResult
private String contentType;
private String pptId;
public void execute(ActionInvocation invocation) throws Exception {
HttpServletResponse response = ServletActionContext.getResponse();
//...Some more code for settign response
System.out.println("pt Id[" + this.pptId + "]");
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getPptId() {
return pptId;
}
public void setPptId(String pptId) {
this.pptId = pptId;
}
Updated answer
So, after some digging, it appears that this is actually working properly. It is the responsibility of the Result to evaluate the incoming data as an OGNL expression if that is necessary. This is how the redirect and http header results work. You can parse the value against the stack in your custom result as follows:
String resolvedPptId = TextParseUtil.translateVariables(pptId, stack)
From the Javadoc for translateVariables:
Converts all instances of ${...}, and %{...} in expression to the value returned by a call to {#link ValueStack#findValue(java.lang.String)}. If an item cannot
be found on the stack (null is returned), then the entire variable ${...} is not
displayed, just as if the item was on the stack but returned an empty string.
Related
I am calling struts2 action class through a ajax call from javascript, which redirect it to b.jsp on success return. In action class I am setting a parameter called dummyValue, for which i have defined getter and setter in the action class. But when i try to display the value of this dummyValue using it does not shows any value.
struts.xml
<package name="AbcAction" namespace="/" extends="struts-default">
<action name="abcAction" class="com.AbcAction">
<result type="stream">
<param name="contentType">text/html</param>
<param name="inputName">stream</param>
</result>
<result name="input" type="dispatcher">/errorPage.jsp</result>
</action>
Setting the result type as stream on purpose.
AbcAction class
public class AbcAction extends ActionSupport {
private InputStream stream;
private String dummyValue;
public String execute() {
dummyValue = "Hello";
try
String str = "success";
stream = new ByteArrayInputStream(str.getBytes());
return SUCCESS;
}
catch (Exception e) {
e.printStackTrace();
String str = "error";
stream = new ByteArrayInputStream(str.getBytes());
return ERROR;
}
}
public InputStream getStream() {
return stream;
}
public void setStream(InputStream stream) {
this.stream = stream;
}
public String getDummyValue() {
return dummyValue;
}
public void setDummyValue(String dummyValue) {
this.dummyValue = dummyValue;
}
}
Javascript function to call action class
function callAbcAction() {
$.ajax({
url : "abcAction",
type: 'post',
data: { },
success : function(result){
if (result == "success") {
window.location='b.jsp';
}
else {
window.location='errorPage';
}
},
});
}
Tag to print dummyMsg in b.jsp
<div class="col-md-3">
<p>Dummy Value is : <s:property value="dummyValue"/></p>
</div>
It is redirecting to b.jsp on success return, but println only "Dummy Value is : " no value is coming.
Please help.
Thanks,
Savvy
I have a pretty complex problem about struts2 chaining actions, thanks in advance for your patience reading my problem. I will try my best to describe it clearly.
Below is my struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.enable.SlashesInActionNames" value="true" />
<constant name="struts.devMode" value="false" />
<package name="default" extends="struts-default" namespace="/">
<action name="test" class="com.bv.test.TestAction1" >
<result name="success" type="chain">y</result>
</action>
<action name="x">
<result name="success">/index.jsp</result>
</action>
<action name="y" class="com.bv.test.TestAction2">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
My logic is like this:
When accessing to /myapp/test, TestAction1 will handle the request;
In TestAction1, I "include" action x (my 2nd action in my config) like this:
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
rd.include(request, myResponse);
And the important thing is I am using a customized ResponseIml when including "x.action".
After including, I return "success", so the result chains to action y (3rd action in my config);
And at last, TestAction2 continue to handle the request, it will go to success result, and the jsp should be rendered, but what I see is a blank page.
The jsp file is very simple:
index.jsp
<h1>Test!</h1>
My question/puzzle is:
In TestAction1, if I get the response from ServletActionContext, I
am getting different ones before and after including; before
including is the default response, but after including I got an
instance of my customized ResponseImpl; I expect to get the same
one: i.e.: the default response;
In TestAction2, I get response from ServletActionContext, what I got
is the instance of my customized ResponseIml. This is my most important thing, I think I should get a default response instance here, i.e.: org.apache.catalina.connector.Response, I am running on JBoss;
I am getting a different ActionContext in TestAction2 (compared with
the ActionContext I get in TestAction1).
This problem really drive me on the nuts, I have spent days on it.
Any advice will be appreciated!
Thanks a million!!
My Code:
TestAction1:
public class TestAction1 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("Before including: the action context is : " + ac);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("Before including: the response is : " + response);
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
}
ac = ActionContext.getContext();
System.out.println("After including : the action context is : " + ac);
response = ServletActionContext.getResponse();
System.out.println("After including : the response is : " + response);
return "success";
}
}
ResponseImpl:
import java.util.Locale;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.Cookie;
import javax.servlet.jsp.JspWriter;
/**
*
*
*/
public class ResponseImpl extends HttpServletResponseWrapper {
//=========================================================
// Private fields.
//=========================================================
private ServletOutputStream outputStream = null;
private ByteArrayOutputStream byteArrayOutputStream = null;
private StringWriter stringWriter = null;
private PrintWriter printWriter = null;
private HttpServletResponse _response = null;
private String contentType= "text/html";
private String encoding = "UTF-8";
/**
*
*/
class ServletOutputStream extends javax.servlet.ServletOutputStream {
private OutputStream outputStream = null;
/**
*
*/
ServletOutputStream(ByteArrayOutputStream outputStream) {
super();
this.outputStream = outputStream;
}
/**
*
*/
public void write(int b) throws IOException {
this.outputStream.write(b);
}
}
//=========================================================
// Public constructors and methods.
//=========================================================
/**
*
*/
public ResponseImpl(HttpServletResponse response) {
super(response);
this._response = response;
}
/**
*
*/
public String getOutput() {
if (this.stringWriter != null) {
return this.stringWriter.toString();
}
if (this.byteArrayOutputStream != null) {
try {
return this.byteArrayOutputStream.toString(this.encoding);
}
catch (UnsupportedEncodingException e) {
}
return this.byteArrayOutputStream.toString();
}
return null;
}
//=========================================================
// Implements HttpServletResponse interface.
//=========================================================
public void addCookie(Cookie cookie) {
}
public void addDateHeader(String name, long date) {
}
public void addHeader(String name, String value) {
}
public void addIntHeader(String name, int value) {
}
public boolean containsHeader(String name) {
return false;
}
public String encodeRedirectURL(String url) {
if (null != this._response) {
url = this._response.encodeRedirectURL(url);
}
return url;
}
public String encodeURL(String url) {
if (null != this._response) {
url = this._response.encodeURL(url);
}
return url;
}
public void sendError(int sc) {
}
public void sendError(int sc, String msg) {
}
public void sendRedirect(String location) {
}
public void setDateHeader(String name, long date) {
}
public void setHeader(String name, String value) {
}
public void setIntHeader(String name, int value) {
}
public void setStatus(int sc) {
}
public void resetBuffer() {
}
//=========================================================
// Implements deprecated HttpServletResponse methods.
//=========================================================
public void setStatus(int sc, String sm) {
}
//=========================================================
// Implements deprecated HttpServletResponse methods.
//=========================================================
public String encodeRedirectUrl(String url) {
return encodeRedirectURL(url);
}
public String encodeUrl(String url) {
return encodeURL(url);
}
//=========================================================
// Implements ServletResponse interface.
//=========================================================
public void flushBuffer() {
}
public int getBufferSize() {
return 0;
}
public String getCharacterEncoding() {
return this.encoding;
}
public String getContentType() {
return this.contentType;
}
public Locale getLocale() {
return null;
}
public javax.servlet.ServletOutputStream getOutputStream() {
if (this.outputStream == null) {
this.byteArrayOutputStream = new ByteArrayOutputStream();
this.outputStream =
new ServletOutputStream(this.byteArrayOutputStream);
}
return this.outputStream;
}
public PrintWriter getWriter() {
if (this.printWriter == null) {
this.stringWriter = new StringWriter();
this.printWriter = new PrintWriter(this.stringWriter);
}
return this.printWriter;
}
public boolean isCommitted() {
return true;
}
public void reset() {
}
public void setBufferSize(int size) {
}
public void setCharacterEncoding(String charset) {
}
public void setContentLength(int len) {
}
public void setContentType(String type) {
int needle = type.indexOf(";");
if (-1 == needle) {
this.contentType = type;
}
else {
this.contentType = type.substring(0, needle);
String pattern = "charset=";
int index = type.indexOf(pattern, needle);
if (-1 != index) {
this.encoding = type.substring(index + pattern.length());
}
}
}
public void setLocale(Locale locale) {
}
}
TestAction2:
public class TestAction2 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("In TestAction 2 : the action context is : " + ac);
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("In TestAction 2 : the response is : " + response);
return "success";
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts2 Application</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
This is my debug info.
Before including: the action context is
:com.opensymphony.xwork2.ActionContext#c639ce
Before including: the response is :
org.apache.catalina.connector.ResponseFacade#8b677f
get from response: <h1>Test!</h1>
After including : the action context is :
com.opensymphony.xwork2.ActionContext#2445d7
After including : the response is : com.bv.test.ResponseImpl#165547d
In TestAction 2 : the action context is
:com.opensymphony.xwork2.ActionContext#19478c7
In TestAction 2 : the response is : com.bv.test.ResponseImpl#165547d
So, I have different ActionContext instances before and after the including!!
When you do rd.include another request is fired internally inside the web server. So from struts point of view it sees a completely new request and a new action context is created as a result. (that's why you need to include 'INCLUDE' thing on the struts2 filter.. so that it's seeing included requests as well). Probably since thread local variables are used to track action context and all that when you do ActionContext.getContext() the context related to the new request (related to the include) gets retrieved.
Did you try resetting the response to the initial one in a finally block like below
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
} finally {
ServletActionContext.setResponse(response);
}
If this resolves the response issue.. you could probably store the string 's' as a variable in the action context and retrieve it inside your Action2
You could also try the following as well. Instead of using chaining.. inside your TestAction1 include the TestAction2 with the original response. return 'none' from the action as the return value.
public class TestAction1 {
public String execute() {
ActionContext ac = ActionContext.getContext();
System.out.println("Before including: the action context is : " + ac);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
System.out.println("Before including: the response is : " + response);
ResponseImpl myResponse = new ResponseImpl(response);
RequestDispatcher rd = request.getRequestDispatcher("/x.action");
try {
rd.include(request, myResponse);
String s = myResponse.getOutput();
System.out.println("get from response: " + s);
}
catch (Exception e) {
e.printStackTrace();
}
RequestDispatcher rd = request.getRequestDispatcher("/y.action");
try {
rd.include(request, response);
}
catch (Exception e) {
e.printStackTrace();
} finally {
return "none";
}
}
}
In Struts 1.x , I have prepopulated the forms text fields using form bean's with default values as follows,
<html:form action="/actions/signup1">
First name: <html:text property="firstName"/><BR>
And in form bean, I have default value as follows...
public class ContactFormBean {
private String firstName = "First name";
But in Struts 2.x , when I tried with struts-tags textfield as follows, its not prepopulating the default value from the bean,
<s:form action="signup1">
<s:textfield name="formBean.firstName" label = "First Name" />
I have the formBean declared in my Action class as follows with appropriate getter and setter methods...
public class SignupAction1 extends ActionSupport {
private ContactFormBean formBean;
#Override
public String execute() throws Exception {
....
}
public ContactFormBean getFormBean(){
return formBean;
}
public void setFormBean(ContactFormBean fb){
formBean = fb;
}
}
Please let me know if this can be accomplished at Request level and not at session level.
Thanks in advance.
<--Edited-->
struts.xml
<struts>
<constant name="struts.devMode" value="true" />
<package name="basicstruts2" extends="struts-default">
<action name="index">
<result>/index.jsp</result>
</action>
<action name="signup">
<result>/SignUp.jsp</result>
</action>
<action name="signup1" class="coreservlets.action.SignupAction1" method="execute">
<result name="success">/SignUp-Confirmation.jsp</result>
<result name="error">/SignUp.jsp</result>
</action>
</package>
</struts>
SignUp.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Sign UP</title>
</head>
<body>
<H1 ALIGN="CENTER">Sign Up</H1>
<s:form>
<s:textfield name="formBean.firstName" label = "First Name" />
<s:textfield name="formBean.lastName" label = "Last Name" />
<s:textfield name="formBean.email" label = "Email Address" />
<s:textfield name="formBean.faxNumber" label = "Fax Number" />
<s:submit action="signup1" method="loginAfterSubmit" value="Click here to Submit"/>
</s:form>
</body>
</html>
ContactFormBean.java
public class ContactFormBean {
private String firstName = "First name";
private String lastName = "Last name";
private String email = "user#host";
private String faxNumber = "xxx-yyy-zzzz";
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return(lastName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return(email);
}
public void setEmail(String email) {
this.email = email;
}
public String getFaxNumber() {
return(faxNumber);
}
public void setFaxNumber(String faxNumber) {
this.faxNumber = faxNumber;
}
public boolean isMissing(String value) {
if ((value == null) || (value.trim().equals(""))) {
return(true);
} else {
for(int i=0; i<defaultValues.length; i++) {
if (value.equals(defaultValues[i])) {
return(true);
}
}
return(false);
}
}
}
SignupAction1.java
public class SignupAction1 extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
private ContactFormBean formBean;
#Override
public String execute() throws Exception {
this.formBean = new ContactFormBean();
return SUCCESS;
}
public String loginAfterSubmit() {
String firstName = formBean.getFirstName();
String lastName = formBean.getLastName();
String email = formBean.getEmail();
String faxNumber = formBean.getFaxNumber();
if (formBean.isMissing(firstName)) {
return ERROR;
} else if (formBean.isMissing(lastName)) {
return ERROR;
} else if ((formBean.isMissing(email)) ||
(email.indexOf("#") == -1)) {
return ERROR;
} else if (formBean.isMissing(faxNumber)) {
return ERROR;
} else {
return SUCCESS;
}
}
public ContactFormBean getFormBean(){
return this.formBean;
}
public void setFormBean(ContactFormBean fb){
formBean = fb;
}
}
Change your signup action declaration to
<action name="signup" class="coreservlets.action.SignupAction1">
<result>/SignUp.jsp</result>
</action>
and signup1 to
<action name="signup1" class="coreservlets.action.SignupAction1" method="signup1">
create method signup1 in your SignupAction1 action class and move your logic from execute to it. In execute then create new instance of your ContactFormBean.
put your default value to the constructor:
public class ContactFormBean {
private String firstname;
public ContactFormBean (){
this.firstName = "First name";
}
}
You are returning a null formBean object with the getFormBean method,
then the constructor is never called and the attempt to acces the formBean attribute firstName is giving an error (that is not showed because it is wrapped by the Struts2 tag on the JSP.
You can
1) instantiate it on your execute method:
public String execute() throws Exception {
this.formBean = new ContactFormBean();
}
2) instantiate it lazily on your getter:
public ContactFormBean getFormBean(){
if (formBean==null)
this.formBean = new ContactFormBean();
return this.formBean;
}
EDIT (due to your comments):
I don't know how you've structured your web application;
But if you are on a JSP, an Action (and its execute() method, or another method if specified) was called BEFORE rendering the JSP.
So, regardless if you have ActionOne loading stuff and ActionTwo called after submit, or ActionOne loading stuff and another method of ActionOne called after submit, you can know if you are in a "pre-JSP" state or in a "post-submit" state...
That said, if you are exposing an Object, and you want its value or its attributes to be different from null, you have to instantiate it in one of the way described above.
Obviously, your object should contain getters and setters for its attributes, and they must have been bound to your JSP objects.
In your example, you could have:
ContactFormBean:
public class ContactFormBean {
private String firstName = "First name";
public String getFirstName(){
return this.firstName;
}
public String setFirstName(String firstName){
this.firstName = firstName;
}
}
Your Action:
public class SignupAction1 extends ActionSupport {
private ContactFormBean formBean;
public ContactFormBean getFormBean(){
return formBean;
}
public void setFormBean(ContactFormBean fb){
formBean = fb;
}
#Override
public String execute() throws Exception {
/* this method is executed before showing the JSP */
/* first time initialization */
this.formBean = new ContactFormBean();
return SUCCESS;
}
public String loginAfterSubmit() throws Exception {
/* this method is executed after the submit button was pressed */
/* i don't initialize nothing here,
ContactFormBean is coming from the page */
System.out.println("ContactFormBean's firstName value is: " +
this.formBean.getFirstName());
return "goSomewhereElse";
}
}
and in Your JSP:
<s:form>
<s:textfield name="formBean.firstName" label = "First Name" />
<s:submit action="signup1" method="loginAfterSubmit" value="Press here to submit" />
</s:form>
You can do this with two Action by splitting the execute() and the loginAfterSubmit() methods into two execute() methods of two different Actions;
Then you must have your formBean in BOTH the Actions, with at least the getter in the first, and the setter in the second.
You can also set the Name value in your bean in execute method, it will populate it in your JSP page. Example is :
public String execute() throws Exception {
this.formBean = new ContactFormBean();
//Set your Name value here
formBean.setName("John Doe");
return SUCCESS;
}
Once JSP is populated you will find this value in Name text box.
Hope this will help.
Tapan
I've got a problem with redirecting from one action to another in struts 2.
In action one (called: StudentZuPruefungHinzufuegen) i am creating action errors and want to show these in action two (called:ZeigePruefungsliste).
If i just use the "redirectAction" from struts it shows the correct action error at the place i wanted to show it. The problem is that the framework doesn't invoke my "execute" method before showing the resultpage with the action errors. Though the table I am filling within my "execute" method is empty and the resulting page is in fact useless.
Can somebody tell me how I can tell Struts to invoke the method while redirecting to action two?
My struts.xml looks like that:
<action name="ZeigePruefungsliste"
class="de.nak.multiplechoice.action.ZeigePruefungslisteAction">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="defaultLoginStack" />
<result type="tiles" name="*">pruefungsListe</result>
</action>
<action name="StudentZuPruefungHinzufuegen"
class="de.nak.multiplechoice.action.EditiereTeilnehmerAction">
<result type="tiles">studentZuPruefungHinzufuegen</result>
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultLoginStack" />
<result name="input" type="redirectAction">
<param name="actionName">
ZeigePruefungsliste
</param>
</result>
</action>
EDIT:
Code of my action classes.
public class EditiereTeilnehmerAction extends AbstractAction {
private static final long serialVersionUID = 882657701678551299L;
private Long ausgewaehltePruefungId;
private List<Nutzer> studenten;
private List<Long> ausgewaehlteStudenten;
#Override
public String execute() {
if (ausgewaehltePruefungId == null) {
addActionError("Es muss eine Prüfung ausgewählt werden.");
return INPUT;
}
studenten = getNutzerService().ladeAlleStudenten();
return SUCCESS;
}
public String zuPruefungHinzufuegen() {
getPruefungService().registriereStudentenFuerPruefung(ausgewaehltePruefungId, ausgewaehlteStudenten);
return SUCCESS;
}
public List<Nutzer> getStudenten() {
return studenten;
}
public void setStudenten(List<Nutzer> studenten) {
this.studenten = studenten;
}
public Long getAusgewaehltePruefungId() {
return ausgewaehltePruefungId;
}
public void setAusgewaehltePruefungId(Long ausgewaehltePruefungId) {
this.ausgewaehltePruefungId = ausgewaehltePruefungId;
}
public List<Long> getAusgewaehlteStudenten() {
return ausgewaehlteStudenten;
}
public void setAusgewaehlteStudenten(List<Long> ausgewaehlteStudenten) {
this.ausgewaehlteStudenten = ausgewaehlteStudenten;
}
}
public class ZeigePruefungslisteAction extends AbstractAction {
private static final long serialVersionUID = -7559234907568287686L;
private List<Pruefung> pruefungen;
#Override
public String execute() {
pruefungen = getPruefungService().getAllePruefungen(getAktuellenNutzer());
return SUCCESS;
}
public List<Pruefung> getPruefungen() {
return pruefungen;
}
}
public abstract class AbstractAction extends ActionSupport {
private static final long serialVersionUID = -6905222101893534102L;
private INutzerService nutzerService;
private IPruefungService pruefungService;
public HttpSession getHttpSession() {
HttpServletRequest request = (HttpServletRequest) ActionContext
.getContext().get(StrutsStatics.HTTP_REQUEST);
return request.getSession(true);
}
public Nutzer getAktuellenNutzer() {
return nutzerService.get(((Nutzer) getHttpSession().getAttribute(
StrutsKonstanten.NUTZER)).getId());
}
protected INutzerService getNutzerService() {
return nutzerService;
}
public void setNutzerService(INutzerService nutzerService) {
this.nutzerService = nutzerService;
}
protected IPruefungService getPruefungService() {
return pruefungService;
}
public void setPruefungService(IPruefungService pruefungService) {
this.pruefungService = pruefungService;
}
}
Greetings,
Marcus
I want to send String as a response to the AJAX xhrPOST method. I am using Struts2 to implement the server side processing. But, I am not getting how to send the result "type" as string and the mapping which should be done to send the string from the struts2 action class to the AJAX response.
You can have your action method return not a String result, but a result of type StreamResult.
In other words:
class MyAction {
public StreamResult method() {
return new StreamResult(new ByteArrayInputStream("mystring".getBytes()));
}
}
You don't necessarily have to return a String from a Struts2 action method. You can always return an implementation of the Result interface from xwork.
copy this in action class
private InputStream inputStream;
public InputStream getInputStream() {
return inputStream;
}
public String execute(){
inputStream = new StringBufferInputStream("some data to send for ajax response");
return SUCCESS;
}
Struts.xml
<action name=....>
<result type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
This works when we want to send a single data in response
You could create a simple StringResult pretty easily by extending StrutsResultSupport, but nothing exists built-in to the framework as far as I know.
Here's an implementation that I've used in the past of a simple StringResult:
public class StringResult extends StrutsResultSupport {
private static final Log log = LogFactory.getLog(StringResult.class);
private String charset = "utf-8";
private String property;
private String value;
private String contentType = "text/plain";
#Override
protected void doExecute(String finalLocation, ActionInvocation invocation)
throws Exception {
if (value == null) {
value = (String)invocation.getStack().findValue(conditionalParse(property, invocation));
}
if (value == null) {
throw new IllegalArgumentException("No string available in value stack named '" + property + "'");
}
if (log.isTraceEnabled()) {
log.trace("string property '" + property + "'=" + value);
}
byte[] b = value.getBytes(charset);
HttpServletResponse res = (HttpServletResponse) invocation.getInvocationContext().get(HTTP_RESPONSE);
res.setContentType(contentType + "; charset=" + charset);
res.setContentLength(b.length);
OutputStream out = res.getOutputStream();
try {
out.write(b);
out.flush();
} finally {
out.close();
}
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
}
I've used the json plugin to do similar things. If you use that, you can use the following to expose a single String property in your action:
<result name="success" type="json">
<param name="root">propertyToExpose</param>
</result>