I have set a property in Action class as follows
public class HelloWorld{
public String execute() { ANNOTATION #1
setCustomGreeting( GREETING + getName() );
return "SUCCESS";
}
private String customGreeting;
public String getCustomGreeting()
{
return customGreeting;
}
public void setCustomGreeting( String customGreeting ){
this.customGreeting = customGreeting;
}
}
And i m trying to render it on jsp as follows
<%# page contentType="text/html; charset=UTF-8" %>
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>HelloWorld</title>
</head>
<body>
<h3>Custom Greeting Page</h3>
<h4><s:property value="customGreeting"/></h4>
</body>
</html>
But it's printing nothing on the jsp, please help me?
Debugging suggestions:
Put breakpoints (or trace statements, or whatever) in the methods to confirm whether or not they are called.
Place an <s:debug/> tag on the page.
If that doesn't give any hints, then enable more detailed logging (how to do this will depend on what logging framework is being used), specifically for OGNL.
Your Code looks fine?
Do you call the JSP directly?
Is your Action mapped in the struts.xml?
Related
I know lots of people asked this but none have solved my issue, please look at the simple two code snippets, I'm using dotnet core 2.2.
What's wrong with the way I'm setting the data inside of ViewData.
Controller.cs:
public async Task<IActionResult> GetWebTripMetaData(Guid tripId)
{
try
{
ViewData["Greeting"] = "Hello World!";
return View();
}
catch (Exception)
{
return BadRequest("Internal Server Error");
}
}
View:
#page
#model TripTale.Backend.Pages.tripModel
<html>
<head>
<link href="#Url.Content("~/Styles/trip.css")" rel="stylesheet" type="text/css" />
</head>
<body>
#ViewData["Greeting"]
</body>
</html>
Please note that when removing the ViewData["Greeting"] from view page it work fine. When adding it, Object reference not set to an instance is thrown.
I simply used ViewBag.Greeting instead of ViewData["Greeting"] and it worked fine
If you are needing to set ViewBag data in .NET Core when your controller loads, override OnActionExecuting. My ViewBag data was always null when setting it in the controller's constructor.
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
this.ViewBag.FullAccountName = $"{this.CurrentLdapUser.DisplayName} ({this.CurrentLdapUser.UserNameWithDomain})";
}
We had a similar issue. We have changed ViewData to ViewBag.Greeting as Mohamad Mousheimish said. This worked for cases like ViewBag.Greeting.Title = "Title" but on my page I had some elements and model expressions that kept using ViewData. Then we removed the #Page directive and after that everything worked fine.
public IActionResult Index()
{
try
{
ViewData["Greeting"] = "Hello World!";
return View();
}
catch (Exception)
{
return BadRequest("Internal Server Error");
}
}
I have an object in session for example of a department and this department have children.I got the list of its children, now i want to add this department object in this list.This is very simple at server side but is it possible to do this in thymeleaf.
Yes it is possible to do it in Thymeleaf since it's using Object-Graph Navigation Language for evaluating expression values - content of ${...} block. You can access public methods normally on your model object so calling boolean List#add(E e) method works.
But as others mentioned it's NOT really good idea and you should redesign your application to fill your model in controller. On the other side if you need to make some nasty hack or just playing around see example below. It's using th:text to evaluate adding to list then th:remove to clean tag and leave no trace.
Department Model class:
public class Department {
private String name;
public Department(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Data in model (eg. session)
List<Department> children = new ArrayList<>();
children.add(new Department("Department 1"));
children.add(new Department("Department 2"));
// In model as *department* variable
Department department = new Department("Main Department");
department.setChildren(children);
Thymeleaf template:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<h1>Before</h1>
<ul>
<li th:each="child : ${department.children}" th:text="${child.name}"></li>
</ul>
<!--/* Here comes a nasty trick! */-->
<div th:text="${department.children.add(department)}" th:remove="all"></div>
<h1>Result</h1>
<ul>
<li th:each="child : ${department.children}" th:text="${child.name}"></li>
</ul>
</body>
</html>
Before
Department 1
Department 2
Result
Department 1
Department 2
Main Department
P.S. Spring Expression Language is used with Spring integration but for this example it makes no difference.
This would be like setting a value in a getXXXX method before returning a value. It doesn't fit the patter. Do your data manipulation in the Controller or the Controller to delegate to something else, but not in the view.
i am learning struts2 and facing some problems with showing the addFieldError message..nothing shows up ..
when i run my project and leave userID field blank it does enters into the validate method and even satisfies the condition of isEmpty method but it doesnt shows up any error message..
i put a s.o.p. statment in the isEmpty method to see ,it is entering or not..
the statment gets printed on console , the url changes to ../MyStruts/validation.action with no errors anywhere and nothing happens further..
can someone tell me where i am doing it wrong..
here is my code..
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>
<package name="validate" extends="struts-default">
<action name="validation" class="com.staction.DataAction">
<result name="success">/success.jsp</result>
<result name="input">/form1.jsp</result>
<result name="error">/error.jsp</result>
</action> </package>
</struts>
form1.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>
<s:form action="validation">
<h1>
<s:textfield label="UserName" name="userID" />
<s:password label="password" name="password" />
</h1>
<s:submit />
</s:form>
<s:a href="forget">forget password </s:a>
</html>
Action class...
package com.staction;
import org.apache.commons.lang3.StringUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class DataAction extends ActionSupport implements ModelDriven<User> {
private static final long serialVersionUID = 1L;
User user;
DataCheck dc;
public DataAction() {
user=new User();
dc=new DataCheck();
}
#Override
public void validate() {
if(StringUtils.isEmpty(user.getUserID()))
{
System.out.println("hellp");
addFieldError("user.userID", "wtf!!!!");
}
}
public String execute()
{
System.out.println("user.userID");
/* if(dc.isValid(user))
{
return SUCCESS;
}*/
return ERROR;
}
#Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
}
and finally the User class..
package com.staction;
import org.apache.commons.lang3.StringUtils;
import com.opensymphony.xwork2.ActionSupport;
public class User{
String userID;
String password;
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Your form:
<s:textfield label="UserName" name="userID" />
Your field error:
addFieldError("user.userID", "wtf!!!!");
See the difference?
Also:
I hope your code isn't actually formatted randomly like that; it's very difficult to read.
Why does your User class extend ActionSupport? If it's not an action, don't extend the base default action: it's pointless, and misleading.
Consider naming actions something meaningful: most actions are "data actions".
When posting examples, kindly trim out commented-out code and stuff that isn't directly related to the specific question.
In addition to response of Dave Newton, you must delete "user." in addFieldError so that Struts2 takes automatically the right object using getModel, or you must add set/get methods for object user in Action so that object is accessed using getter.
Jst use the name of your field that to be validated... Change ur code to
addFieldError("UserName", "wtf!!!!");
I have the following scenario:
Struts.xml
<action name="user_initNews" method="initNews" class="it.sba.bcc.sbarima.user.web.action.UserAction">
<result type="dispatcher">
<param name="location">pages/elementicomuni/elencoNews.jsp</param>
</result>
</action>
User Action
public class UserAction extends BaseAction
{
private NewsService newsService = null;
private User utente;
private List<News> news;
public String initNews()
{
return SUCCESS;
}
public void elencoNews()
{
try
{
newsService = UserServiceFactory.getNewsService();
this.news = newsService.getNews(getAbiUserProfile(), getMatricolaUserProfile());
}
catch (ServiceException e)
{
e.printStackTrace();
}
}
public List<News> getNews()
{
return news;
}
}
elencoNews.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<?xml version="1.0" encoding="utf-8"?>
<%# taglib uri="/struts-tags" prefix="s" %>
<html>
<body>
<s:action name="user_elencoNews!elencoNews"></s:action>
<s:iterator value="news" var="n">
<label><s:property value="descrizione"/></label>
</s:iterator>
</body>
</html>
Whene the elencoNews.jsp is rendered, I would like to call from the JSP page an action thath return a set of POJO to iterate.
The elencoNews.action is correctly called, but I do not know how to treat data on the elencoNews.jap
How can I do that?
I'm afraid you are misunderstanding the whole Struts2 typical workflow. You dont (typically) want to call another action from the JSP, in the typical workflow the JSP renders after your action has processed your request, and it just displays data (typically from your Action instance, which is found in the value stack).
Eg read here
In your example, you'd should code in your JPS:
<s:iterator value="news" var="n">
<s:property value="descrizione"/>
</s:iterator>
If you have this concepts clear (and you have coded the most basic-typical struts2 cases), the disregard this and be more explicit about what are you trying to accomplish - why you have two actions involved for a single request and jsp.
If you want a dynamic jsp page, you can look into using the Struts2-jQuery plugin which will allow you to call another action in your JSP and load the results. See examples at http://www.weinfreund.de/struts2-jquery-showcase/index.action under Ajax Link or Ajax Div sections.
When requesting http://someserver.com/user/btyndall
I'd like to return HTML
When requesting http://someserver.com/user/btyndall?format=xml
I'd like to return XML representation of my model
I've downloaded MvcContrib. (I can't believe XmlResult is not a part of the core framework)
What is the proper way to handle the request in the controller. With JSON you have a JsonResult and Json(). I see a XmlResult but not an Xml() method
I could use a little guidance. What I have so far (which is nada):
public ActionResult Details(int id)
{
return View();
}
UPDATE:
see all comments
This post shows a nice way of achieving what you are looking for.
What about just returning two different views?
public ActionResult Details(int id, string format) {
if (!String.IsNullOrEmpty(format) && format == "xml") {
return View("MyView_Xml");
}
else {
return View("MyView_Html");
}
}
Then create two views. MyView_Xml:
<%# Page Inherits="System.Web.Mvc.ViewPage<Customer>" ContentType="text/xml">
<?xml version="1.0" encoding="utf-8" ?>
<customer>
<first_name><%= Model.FirstName %></first_name>
<last_name><%= Model.FirstName %></last_name>
</customer>
and MyView_Html
<%# Page Inherits="System.Web.Mvc.ViewPage<Customer>">
<html>
<body>
<div><label>First Name:</label><%= Mode.FirstName %></div>
<div><label>Last Name:</label><%= Mode.LastName %></div>
</body>
</html>