Hi I'm new to JSON and I've been trying to get my List into a JSONArray, so that I can use it later with JQuery and include it on a website, but it keeps returning an empty array. I'm using Java EE and wrote a named query, I'm not too sure that the named query is the thief behind it. Here's most probably the appropiate code I hope.
The named query in Review.class:
#NamedQueries ({
#NamedQuery(name="Review.findByTitleOrName", query = "SELECT r FROM Review r WHERE r.artist.artistNr = (SELECT a.artistNr FROM Artist a WHERE a.artistName Like :A) OR r.track.trackID = (SELECT t.trackID FROM Track t WHERE t.trackTitle LIKE :A)")
})
Method in the EAO for reviews that should work:
public List<Review> getReviewsByTitleOrName(String searchParameter) {
TypedQuery<Review> tq = em.createNamedQuery("Review.findByTitleOrName", Review.class);
tq.setParameter("A", searchParameter);
List<Review> reviewList = tq.getResultList();
return reviewList;
}
Servlet code:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json; charset=utf-8");
JsonArrayBuilder arrayOfJsonReviews = Json.createArrayBuilder();
String searchParameter = request.getParameter("ajax_searchParameter");
List<Review> reviews = facade.getReviewsByTitleOrName(searchParameter);
for(Review r : reviews){
JsonObjectBuilder review = Json.createObjectBuilder();
review.add("date", r.getDate());
review.add("comment", r.getComments());
review.add("rating", r.getRating());
review.add("user", r.getUserName());
arrayOfJsonReviews.add(review);
}
response.getWriter().write(arrayOfJsonReviews.build().toString());
}
And last but not least the JQuery:
$(document).ready(function() {
$(".SearchBtn").click(function() {
console.log("Clicked button");
$.getJSON("http://localhost:8080/DynamicDolphinProject/DolphinServlet", function(data){
console.log(data);
//placeReviewDat(data);
console.log("Should have data");
});
});
//function placeReviewData(reviews){
//}
})
Related
my Task ist to test a HttpServlet written in Java, which connects to a database and has the following methods implemented:
doGet(), doPost(), doDelete(), doOptions()
To test the functionality independently from the database connection I've implemented an InMemoryDao which populates a H2 database with test data from a Json file and gets injected into my ServletTest class.
Here's an example of the doGet() Method:
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
boolean all = req.getParameter("all") != null;
boolean specific = req.getParameter("songId") != null;
if (all == specific) {
resp.setStatus(400);
writePlaintext(resp, "Specify either 'all' or 'songId'.");
return;
}
if (all) doGetAll(req, resp);
if (specific) doGetSpecific(req, resp);
}
My InMemorySongDao class looks like this:
public class InMemorySongDao extends MysqlSongDao {
public InMemorySongDao() throws SQLException {
super(new ComboPooledDataSource());
UUID uuid = UUID.randomUUID();
// Connect to a unique in-memory database identified by a random uuid
this.dataSource.setJdbcUrl("jdbc:h2:mem:" + uuid);
try (PreparedStatement st = this.dataSource.getConnection().prepareStatement(
"CREATE TABLE songs (" +
"id int not null primary key auto_increment," +
"title varchar(100) not null," +
"artist varchar(100)," +
"label varchar(100)," +
"released int" +
")")) {
st.execute();
}
}
/**
* Creates a songs dao prefilled with the songs from the given resource.
*/
public InMemorySongDao(String resourceName) throws SQLException, IOException {
this();
final ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(getClass().getResource(resourceName));
// Read array node or use empty node
ArrayNode array = (rootNode.isArray()) ? (ArrayNode) rootNode : mapper.createArrayNode();
try (PreparedStatement st = this.dataSource.getConnection().prepareStatement("INSERT INTO songs (id, title, artist, label, released) values (?,?,?,?,?)")) {
// Iterate over the array and populate the database with the songs
Iterator<JsonNode> elements = array.elements();
while (elements.hasNext()) {
JsonNode node = elements.next();
if (!node.isObject()) continue;
st.setInt(1, node.get("id").asInt());
st.setString(2, node.get("title").asText());
st.setString(3, node.get("artist").asText());
st.setString(4, node.get("label").asText());
st.setInt(5, node.get("released").asInt());
st.addBatch();
}
st.executeBatch();
}
}
}
Would be very thankful if somebody could provide me any help with this. Unfortunately I couldn't find any proper examples by research...
Kind Regards,
Mic
I'm writing my first bigger app and I have one issue, my code below:
InitDB.java
public void requestInitialized(ServletRequestEvent arg0) {
EntityManager em = DBConfig.createEntityManager();
BooksDAO booksDAO = new BooksDAO(em);
CategoryDAO categoriesDAO = new CategoryDAO(em);
ServletRequest req = arg0.getServletRequest();
req.setAttribute("booksDao", booksDAO);
req.setAttribute("categoriesDao", categoriesDAO);
}
BooksDAO.java
EntityManager em = DBConfig.createEntityManager();
public BooksDAO(EntityManager em) {
this.em = em;
}
public List<Books> getBooksByCategory(String category) {
Query q = this.em.createQuery("SELECT b FROM Books b WHERE b.category = :category ", Books.class).setParameter("category", category);
List<Books> booksByCategory = q.getResultList();
return booksByCategory;
}
booksCategoryServlet.java
#WebServlet("/booksCategory")
public class booksCategoryServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String category = request.getParameter("category");
if (category != null) {
BooksDAO dao = (BooksDAO) request.getAttribute("booksDao");
List<Books> booksByCategory = dao.getBooksByCategory(category);
request.setAttribute("booksByCategory", booksByCategory);
request.getRequestDispatcher("/booksCategory.jsp").forward(request, response);
} else
response.sendRedirect(request.getContextPath() + "/");
}
bookCategory.jsp
<c:forEach var="book" items="${booksDao.booksByCategory}">
<tr>
<td>${book.title}</td>
<td>${book.author}</td>
<td>${book.description}</td>
<td>${book.category}</td>
<td>${book.year}</td>
<td>show details</td>
</tr>
</c:forEach>
index.jsp
<c:forEach var="category" items="${categoriesDao.categories}">
<li>${category}</li>
</c:forEach>
In index page I have listed categories, and when i want go to choosen category and display books for this category i got this exception:
org.apache.jasper.el.JspPropertyNotFoundException: /booksCategory.jsp(40,4) '${booksDao.booksByCategory}' Property 'booksByCategory' not found on type DAO.BooksDAO
Can someone tell me what I did wrong?
You're calling a method thinking you're calling for an actual object.
I'd create a List<Books> object in DAOBooks and send it with the request to the JSP.
Solution
DAOBooks
EntityManager em = DBConfig.createEntityManager();
List<Books> booksByCategory = new ArrayList<>(); // Or whatever list type you need.
public BooksDAO(EntityManager em) {
this.em = em;
}
public void setBooksByCategory(String category) {
Query q = this.em.createQuery("SELECT b FROM Books b WHERE b.category = :category ", Books.class).setParameter("category", category);
booksByCategory = q.getResultList();
}
public List<Books> getBooksByCategory(){
return booksByCategory;
}
And in your JSP
<c:forEach var="book" items="${booksByCategory}">
Make a direct reference to the List<Books> object because it is the one you're sending via the request.
EDIT
Try to have a distinct setter and getter method. It'll help you have a more readable code and will solve those type of problems instantly.
I made an example in my post but it is not necessarily a correct one, you have to find the ways to implement them following your application logic.
In my spring aplication, I am trying pass a array of strings from my view, through this code:
$( ".form" ).submit(function( event ) {
event.preventDefault();
var $form = $( this ), url = $form.attr( "action" );
var selecao_permissoes=[];
$('#selecao option').each(function(){
selecao_permissoes.push($(this).val());
});
var nome = $("input[name=nome]").val();
$.ajax({
type: "POST",
url: url,
data: { nome: nome, permissoes: selecao_permissoes }
}).done(function( msg ) {
$("#"+msg).show();
$(".form").each (function(){
this.reset();
});
});
});
To this method from my Service class:
public boolean cadastra(HttpServletRequest request, HttpServletResponse response) {
String nome_grupo = request.getParameter("nome");
String[] permissoes = request.getParameterValues("permissoes");
if(nome_grupo == null || permissoes == null) {
System.out.println("nome_grupo = "+nome_grupo);
System.out.println("permissoes = "+permissoes);
return false;
}
GrupoPermissao grupo = new GrupoPermissao();
grupo.setNome(nome_grupo);
List<Permissao> lista = new ArrayList<Permissao>();
for(int i=0; i<permissoes.length; i++)
lista.add(permissao.findById(Integer.valueOf(permissoes[i]).intValue()));
grupo.setPermissao(lista);
return grupo_permissao.persist(grupo);
}
The atribute 'nome' is receiving the correct value, but the atribute 'permissoes' is receiving a null value.
Anyone can tell me why this is happening? I can't figure out a motive for that.
Try with:
String[] permissoes = request.getParameterValues("permissoes[]");
I don't know why, it's just annoying and how jquery are doing if for some reason if your posting an array and want it in your java servlet.
I have an MVC app that is creating new offices instead of updating them on when using an edit form. Please help me understand why this is happening.
Search method that populates the search results:
#RequestMapping(value = "/searchResults", method = RequestMethod.POST)
public ModelAndView search(#RequestParam String searchCriteria, HttpServletRequest request) {
List<Office> offices = officeServiceImpl.search(searchCriteria);
return new ModelAndView("searchResults", "offices", offices);
}
Here's what the link to the edit form looks like on the search results page:
Edit Office
Here is the Controller's edit GET method that populates the form with the existing Office:
#RequestMapping(value = "/{officeId}/edit", method = RequestMethod.GET)
#Transactional(noRollbackFor=NoResultException.class)
public ModelAndView initUpdateOfficeForm(
#PathVariable("officeId") Long officeId, Model model) {
Office office = officeServiceImpl.find(officeId);
//prepareEditFormModelAndView(office) just converts some objects to strings for typeahead form population
return prepareEditFormModelAndView(office);
}
Here is the edit POST method:
#RequestMapping(value = "/{officeId}/edit", method = RequestMethod.POST)
public ModelAndView processUpdateOfficeForm(#ModelAttribute("office") #Valid Office office,
BindingResult result, SessionStatus status) {
if (! "united states of america".equals(office.getFolderStrings().toLowerCase())) {
//This portion of code converts the typeahead strings to objects
result = tryCountries(office, result);
result = tryDepartments(office, result);
result = tryEmployees(office, result);
}
if (result.hasErrors()) {
return prepareEditFormModelAndView(office);
} else {
officeServiceImpl.save(office);
status.setComplete();
return new ModelAndView("editResult", "office", office);
}
}
officeServiceImpl calls officeRepositoryImpl method save which looks like:
#Override
public Office save(Office office) {
em.merge(office);
em.flush();
return office;
}
Thanks
Edit: Adding prepareEditFormModelAndView(office), This method attempts to build strings from associated objects:
#Transactional(noRollbackFor={NoResultException.class, IndexOutOfBoundsException.class})
private ModelAndView prepareEditFormModelAndView(Office office) {
String departmentStrings = "";
String employeeStrings = "";
List<OOM> officeOOMs = new ArrayList<OOM>();
StringBuilder sb = new StringBuilder();
try {
officeOOMs = oomServiceImpl.getOOMsForCurrentOffice(office.getId());
} catch (NoResultException e) {
officeOOMs = null;
}
for (OOM o : officeOOMs) {
try {
Employee tempEmployee = employeeServiceImpl.find(o
.getEmployeeId());
sb.append(tempEmployee.getDisplayName() + ", ");
} catch (NoResultException e) {
sb.append("Not found in system");
}
}
employeeStrings = sb.toString();
if ((! "".equals(office.getDepartmentStringsOnForm())) && office.getDepartmentStringsOnForm() != null) {
departmentStrings = office.getDepartmentStringsOnForm();
}
String folderStrings = "";
try {
folderStrings = kmlFolderServiceImpl.getInternationalOfficeString(office.getId());
LOGGER.info("Folder Strings: " + folderStrings);
} catch (NoResultException e) {
folderStrings = "";
LOGGER.info("Folder Strings: " + "no result");
}
boolean isInternational = office.isInternational();
ModelAndView result = new ModelAndView("editOfficeForm", "office", office);
result.addObject("departmentStrings", departmentStrings);
result.addObject("isInternational", isInternational);
result.addObject("folderStrings", folderStrings);
result.addObject("employeeStrings", employeeStrings);
return result;
}
I am adding a previous comment here, for better clarification. According to the OP the following fixes the problem:
When the ID is not in the form then when the model is posted back no ID is set to the entity making the persistence provider believe it is new entity.
Therefor the most obvious solution is to post the ID of the entity as well in the save operation (probably using a hidden field).
Another solution would be to try to load the entity in the database based on some business key
to see if the entity is new or not.
i have some problem using Morris Chart.
I want to show the details of transaction using Morris Chart using JSON from external source. Here's my code:
$(document).ready(function() {
//getting JSON data from external sources
var json_data = (function() {
var json;
$.ajax({
type:'GET',
url: 'http://localhost:8080/masterpiece/chartGetTransaction',
async: false,
global: false,
success: function(data) {
json = data;
},
error:function(){
alert("Error loading chart");
}
});
return json;
})();
//testing purposes to see whether json is shown up or not.
alert(json_data);
new Morris.Bar({
// ID of the element in which to draw the chart.
element: 'pesanan-chart-area',
data: json_data,
xkey: 'tahun',
ykeys: ['jml'],
labels: ['Jumlah'],
smooth: false
});
});
But it always broken.
The JSON itself:
[{"tahun":"2013-10-12","jml":3},{"tahun":"2013-11-16","jml":2},{"tahun":"2013-12-23","jml":4},]
when i place the JSON manually to 'data:' attribute, the chart is shown up. But when it referenced from external source (json_data var) it is broken
any ideas?
thanks.
UPDATE
update! the JSON is generated from JAVA function using third party library called json-simple (https://code.google.com/p/json-simple/downloads/list)
protected List<JSONObject> statisticPesanan(){
List<JSONObject> det = new ArrayList<JSONObject>();
try {
//create JSONObject to executed
String sql = "SELECT * FROM vstatisticpesanan";
cs = datman.logOn().prepareCall(sql);
ResultSet result = cs.executeQuery();
while (result.next()) {
JSONObject details = new JSONObject();
details.put("tahun", result.getString(1));
details.put("jml", result.getInt(2));
det.add(details);
}
} catch (SQLException se) {
Logger.getLogger(Analytics.class.getName()).log(Level.SEVERE, null, se);
java.lang.System.out.println("Error on Analytics Generate JSON Pesanan Statistics : " + se.toString());
} finally {
datman.logOff();
}
return det;
}
then called via servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/* Execution of jSON Chart */
Analytics show = new Analytics();
List<JSONObject> json = show.getStatisticPesanan();
out.print('[');
for(JSONObject js : json){
out.print(js.toJSONString()+",");
}
out.print(']');
} finally {
out.close();
}
}
is there any solution? thanks.
alrite after searching and creating new function, i have realize that morris.js cannot parse the JSON object.
first change the servlet into:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
/* Execution of jSON Chart */
Analytics show = new Analytics();
List<JSONObject> json = show.getStatisticPesanan();
out.print(js.toJSONString());
} finally {
out.close();
}
}
then it will shows the right JSON object like this:
[{"1":"2013-10-12","2":3},{"1":"2013-11-16","2":2},{"1":"2013-12-23","2":4},{"1":"2014-02-11","2":10}]
then parse the JSON object into
new Morris.Bar({
// ID of the element in which to draw the chart.
element: 'pesanan-chart-area',
data: $.parseJSON(json_data),
xkey: 'tahun',
ykeys: ['jml'],
labels: ['Jumlah'],
smooth: false
});
we NEED to use function $.parseJSON to make the graph shows correctly, otherwise the graph will show undefined.
i hope this will help someone.