Why the class can use undefined members in JSTL? - java

I am reading JSP tutorial from a book and meeting a program that is hard to understand.
It has two beans, one is Message.java, another is MessageServies.java as below.
package com.jeecourse.model;
public class Message {
private String name;
private String text;
public Message() {
}
public Message(String name, String text) {
this.name = name;
this.text = text;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
And the MessageService.java
package com.jeecourse.model;
public class MessageService {
private Message[] fakeMessages;
public MessageService() {
fakeMessages = new Message[3];
fakeMessages[0] = new Message("Jimmy", "Jimmy's message!");
fakeMessages[1] = new Message("Jack", "Jack's message!");
fakeMessages[2] = new Message("Tom", "Tom's message!");
}
public Message[] getMessages() {
return fakeMessages;
}
}
And finnally the message.jsp with EL:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<jsp:useBean id="messageService" class="com.jeecourse.model.MessageService"/>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<title>NoteBook</title>
</head>
<body>
<table style="text-align: left; width: 100%;" border="1">
<tr>
<td>Name</td><td>Message</td>
</tr>
<c: forEach var="message" items="${messageService.messages}">
<tr>
<td>${message.name}</td><td>${message.text}</td>
</tr>
</c: forEach>
</table>
</body>
</html>
Please note here it uses messageService.messages in EL expression. It is very strange that messageService have neither such members, nor such functions. But it can work. Why?

When you write ${messageService.messages} it gets translated at compile time to messageService.getMessages. Just in the same way that ${message.text} is invoking actually message.getText().
For this kind of "magic" it is important to follow some conventions when naming your methods. If not, the compiler won't know which method it should call when you use the abbreviated version.
You can see more about EL here: https://stackoverflow.com/tags/el/info
This feature is at the top of the page.

Related

getting null while using request.setattriubute value in struts2

I am working on struts2 but getting issue in the jsp while accessing a variable in form class using a set variable inside property tag.
Please find the below full code.
Testactionform.java
public class Testactionform {
String name = "india";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
TestAction.java
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.SessionAware;
public class TestAction implements SessionAware
{
public Testactionform test;
public Testactionform getTest() {
return test;
}
public void setTest(Testactionform test) {
this.test = test;
}
private Map<String, Object> session;
public Map<String, Object> getSession() {
return session;
}
public void setSession(Map<String, Object> session) {
this.session = session;
}
public String execute()
{
final HttpServletRequest request = ServletActionContext.getRequest();
test=new Testactionform();
request.setAttribute("name1", "name");
test.setName("london");
session.put("Testactionform",test);
System.out.println("execute() method called");
return"success";
}
}
Success.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>error page</h1>
<s:set var="name2" value="#request.name1"></s:set>
<s:property value="%{#session.Testactionform.name2}"/>
</body>
</html>
In JSP with below line, I want to access the name variable in Testactionform, but I get nothing in the response.
<s:property value="%{#session.Testactionform.name2}"/>
Below is the command which is working fine for me .
<s:property value="#session.Testactionform[#name2]"/>

Spring MVC :how a form transfer an object to Controller?? Always 400 error

When i try to access http://localhost:8080/XX/articles/addArticle
and submit the form, there is always a "400 BAD REQUEST" error.
i've tried to look up for the reason, all i got is that object transfered from the form is not as same type as my model(, which is an Article object? here). However, i don't think i really get it..
All codes are here, the config is all good.
Here are 2 models:
Article.java
#Entity
#Table(name="article_inf")
public class Article {
private int articleId;
private String title;
private User author;
private String content;
public Article() {
}
public Article(String title, User author, String content) {
this.title = title;
this.author = author;
this.content = content;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getArticleId() {
return articleId;
}
public void setArticleId(int articleId) {
this.articleId = articleId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#ManyToOne(targetEntity=User.class)
#JoinColumn(name="author", referencedColumnName="userId", nullable=false)
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
User.java
#Entity
#Table(name="agri_user_inf")
public class User {
private int userId;
private String userName;
private String password;
private String cellPhone;
private List<Article> articles;
public User() {
articles = new ArrayList<>();
}
public User(String userName, String password, String cellPhone) {
this.userName = userName;
this.password = password;
this.cellPhone = cellPhone;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
#OneToMany(targetEntity=Article.class, mappedBy="author")
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
controller
ArticleController.java
#Controller
#RequestMapping("articles")
public class ArticleController {
private ArticleDao articleDao;
#Autowired
public ArticleController(ArticleDao articleDao) {
this.articleDao = articleDao;
}
#RequestMapping(value="addArticle", method=GET)
public String addArticle(ModelMap modelMap) {
List<User> authors = userDao.getAllUsers();
// add all authors
modelMap.addAttribute("authors", authors);
return "articles/addArticleForm";
}
#RequestMapping(value="addArticle", method=POST)
public String addArticle(Article article) {
articleDao.addArticle(article);
return "redirect:/articles";
}
// other code
my form addArticleForm.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post">
title: <input type="text" name="title"/><br/>
author: <select name="author">
<c:forEach items="${authors}" var="author">
<option value="${author}">${author.userName}</option>
</c:forEach>
</select>
<br/>
content: <input type="text" name="content"/><br/>
<input type="submit" value="add"/>
</form>
</body>
</html>
You are violating REST principles. Always use version in your endpoint and resource name after that. Example - /api/v1/articles. After that with help of HttpMethods access your resources. Example - If you want to
1.1 add new Article , use POST request to /api/v1/articles
1.2 delete existing Article, use DELETE request to /api/v1/articles/{articleId}
1.3 get one Article, use GET request to /api/v1/articles/{articleId}
1.4 get all Articles, use GET request to /api/v1/articles
1.5 update existing Article, use PUT request to /api/v1/articles/{articleId}
Never use your Entity which is going to be persisted in DB for all layers. It`s bad practice to connect Entity with your view, instead you can use DTO.
Use #ModelAttribute annotation in your controller layer with same name as in view to handle incoming Article object. Example
public String addArticle(#ModelAttribute("article") Article article )
To add new Article first you need to create endpoint which is returning empty Article object inside of ModelMap. Then you must handle this in your front end(JSP) and for submitting this form follow step 3.
Hope this will help.
I got solution :
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="post">
title: <input type="text" name="title"/><br/>
author: <select name="author.userId">
<c:forEach items="${authors}" var="author">
<option value="${author.userId}">${author.userName}</option>
</c:forEach>
</select>
<br/>
content: <input type="text" name="content"/><br/>
<input type="submit" value="add"/>
</form>
</body>
</html>
change name of <select> tag from "author" to "author.userId" . That works.

SQL is returning only the year, not the day nor the month

I'm working on a small personal project as a Java student and i've been asked to create a simple webpage that displays a Mysql database. In mySql, i declared my dates in type DATE.
See screanShot below.
The java code below shows how i retrieve the datas from my DB.
private Destination resultSetRowToCursist(ResultSet resultSet)
throws SQLException {
return new Destination (resultSet.getInt("CountryID"),
resultSet.getString("Destination"),
resultSet.getDate("DepartureDate"),
resultSet.getDate("ReturnDate"),
resultSet.getInt("Price"),
resultSet.getInt("AvailableSeats"));
}
Below is the screanshot of the output on my webpage.
DepartureDate and ReturnDate format on my webpage should be reflecting the same format as in the DB
This is my JSP code
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="styles/default.css">
<title>Travels</title>
</head>
<body>
<table border=1>
<tr>
<th>CountryId</th>
<th>Country</th>
<th>DepartureDate</th>
<th>ReturnDate</th>
<th>Price</th>
<th>AvailableSeats</th>
</tr>
<c:forEach var="destinationArrayListItem" items="${DestinationArrayList}">
<tr>
<td>${destinationArrayListItem.countryID}</td>
<td>${destinationArrayListItem.destination}</td>
<td>${destinationArrayListItem.departureDate}</td>
<td>${destinationArrayListItem.returnDate}</td>
<td>${destinationArrayListItem.price}</td>
<td>${destinationArrayListItem.availableSeats}</td>
</tr>
</c:forEach>
</table>
<br />
<c:url var="index" value="/IndexServlet" />
<a class="HPbutton" href="${index}">Home Page</a>
</body>
</html>
My Destination class with COnstructor and getters
import java.io.Serializable;
import java.sql.Date;
public class Destination implements Serializable {
private static final long serialVersionUID = 1L;
private int countryID;
private String destination;
private Date departureDate;
private Date returnDate;
private int price;
private int availableSeats;
public Destination () {
this.countryID=0;;
this.destination="geen";
this.departureDate= null;
this.returnDate= null;
this.price=0;
this.availableSeats=0;
}
public Destination(int countryID, String destination, Date departureDate,
Date returnDate, int price, int availableSeats) {
this.countryID = countryID;
this.destination = destination;
this.departureDate = departureDate;
this.returnDate = returnDate;
this.price = price;
this.availableSeats = availableSeats;
}
public int getCountryID() {
return countryID;
}
public void setCountryID(int countryID) {
this.countryID = countryID;
}
public Date getDepartureDate() {
return departureDate;
}
public void setDepartureDate(Date departureDate) {
this.departureDate = departureDate;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public Date getReturnDate() {
return returnDate;
}
public void setReturnDate(Date returnDate) {
this.returnDate = returnDate;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getAvailableSeats() {
return availableSeats;
}
public void setAvailableSeats(int availableSeats) {
this.availableSeats = availableSeats;
}
}
Are you using javax.sql.Date or java.util.Date. Remebering that EL tags use the toString() method, it may be worth formatting the date as shown in the following thread:
Convert java.util.Date to String
Another way to do this is to use JSTL tags in the following manner:
<td><fmt:formatDate value="${destinationArrayListItem.departureDate}" pattern="MM/yyyy" /></td>
<td><fmt:formatDate value="${destinationArrayListItem.returnDate}" pattern="MM/yyyy" /></td>
To do this, you will have to add the JSTL library to your JavaEE application as follows:
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
Note, this is different from the JSTL core.

Error with parsing on the view?

I try to make an web application that will conect with a repository on a server, and i want to print the data on the screen. Actually i try to create a RESTful client. Probably there is a parsing error that doesn't allow me to see the display data
My jsp is the following:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Get Author</h1>
<c:if test="${empty author}">
No records found!
</c:if>
<c:if test="${!empty author}">
<table style="border: 1px solid #333">
<tr>
<td style="width: 100px">Id</td>
<td>${data.id}</td>
</tr>
<tr>
<td>Name</td>
<td>${data.name}</td>
</tr>
<tr>
<td>Address</td>
<td>${data.address}</td>
</tr>
</table>
</c:if>
</body>
</html>
The controller is the following(i implement the controller with two different ways. The one of them is commented)
#Controller
public class Contraller {
protected static Logger logger = Logger.getLogger("controller");
private RestTemplate restTemplate = new RestTemplate();
#RequestMapping(value = "/datas", method = RequestMethod.GET)
public String getDatas(Model model) {
HttpEntity<Data> entity = new HttpEntity<Data>(headers);
// Send the request as GET
try {
ResponseEntity<DataList> result = restTemplate.exchange("http://www../data/",
HttpMethod.GET, entity, DataList.class);
// Add to model
model.addAttribute("datas", result.getBody().getData());
} catch (Exception e) {
}
// This will resolve to /WEB-INF/jsp/personspage.jsp
return "personspage";
}
/**
* Retrieves a single record from the REST provider
* and displays the result in a JSP page
*/
#RequestMapping(value = "/data", method = RequestMethod.GET)
public String getMyData(#RequestParam("id") Long id, Model model) {
try{
Data results = restTemplate.getForObject("http://www.../data/{id}",
Data.class, id);
model.addAttribute("data", results);
}catch(Exception e){
}
return "getpage";
}
The model:
#XmlRootElement(name = "data", namespace="http://www...")
#XmlAccessorType(XmlAccessType.FIELD)
public class Data {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setFirstName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
In the repository there are 4000 datas. When i give the following URL: localhost:8080/Client_for_rest/data?id=1
(all the id's from 1 to 4000) returns me the view but it doesn't display the data. If i give an id bigger than 4000, i.e. 4001 gives me back that there are no records which is true. According to this i suppose that the client connects with the server side but there is a problem(i suppose with parsing) that it doesn't allow the data to be dispayed on the view. I'm unfamiliar with the Spring MVC framework and i read something about marshaller and castor but i don't how to implement them. Actually i was wondering if there is an easier way to solve my problem. Do i have to use pojo maven dependencies etc?
if you method return type is string use map object and bindresult as the parameters to that method.
and add elements to that map object.
you can directly access that map object on your jsp page
as an example :
#RequestMapping("/locationUpdate.do")
public String locationUpdate(Map<String, Object> map,#ModelAttribute("location") Location location, BindingResult result) {
map.put("location", locationService.getLocationByCode(locationcode));
map.put("locGrp", listLocationGroup());
return "location/locationAdd";
}
now you can directly access location and locGrp in your jsp

Struts 2 radio button list [duplicate]

This question already has answers here:
Struts 2 select tag with values of a array list
(2 answers)
Closed 6 years ago.
am working on Struts 2 radio button.
I want to retrieve the list from my action class but it is giving following error
org.apache.jasper.JasperException: tag
'radio', field 'list', name
'user.yourGender': The requested list
key '#user.gender' could not be
resolved as a
collection/array/map/enumeration/iterator
type. Example: people or people.{name}
- [unknown location]
my action class & user class is as follow
HelloAction
package com.geekcap.struts2.action;
import com.geekcap.struts2.model.User;
import com.opensymphony.xwork2.ActionSupport;
import java.util.List;
import java.util.ArrayList;
public class HelloAction extends ActionSupport
{
private User user;
public String execute() throws Exception
{
return "success";
}
public void validate()
{
if(user.getName().length()==0)
{
addFieldError("user.name", "User Name is required");
}
if(user.getAge()==0)
{
addFieldError("user.age","Age is required");
}
if(user.getPassword().length()==0)
{
addFieldError("user.password","Please enter your password !");
}
/* if(user.getGender().equals("-1"))
{
addFieldError("user.gender","Please select gender !");
}*/
}
public User getUser()
{
return user;
}
public void setUser(User userbean)
{
user=userbean;
}
}
User class
package com.geekcap.struts2.model;
import java.util.List;
import java.util.ArrayList;
public class User
{
private String name,password;
// private List like;
private int age;
private List<String> gender;
private String yourGender;
public User()
{
gender= new ArrayList<String>();
gender.add("MALE");
gender.add("FEMALE");
gender.add("UNKNOWN");
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password=password;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
public List<String> getGender()
{
return gender;
}
public void setGender(List<String> gender)
{
this.gender=gender;
}
public void setYourGender(String yourGender)
{
this.yourGender=yourGender;
}
public String getYourGender()
{
return yourGender;
}
public String getDefaultGenderValue()
{
return "UNKNOWN";
}
helloForm.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome to Struts 2</title>
</head>
<body>
<s:form action="Hello">
<s:textfield name="user.name" label="User name" value="shahid"/>
<s:password name="user.password" label="Password"/>
<s:textfield name="user.age" label="Age"/>
<s:radio label="Gender" name="user.yourGender" list="user.gender" value="defaultGenderValue"/>
<s:submit/>
</s:form>
</body>
</html>
hello.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello, Struts 2</title>
</head>
<body>
<h4>
Hello, <s:property value="user.name"/>!
<br>Your password :<s:property value="user.password"/></br>
<br>your age :<s:property value="user.age"/></br>
<br>Gender :<s:property value="user.yourGender"/></br>
</h4>
</body>
</html>
Are you sure the list gender is NOT null in the JSP?
If it is null, then struts will not see it and therefore think it isn't there

Categories