Go to inscription page - java

i'm have problem with load page by id. I'm creating simple forum in Spring and when i created topic i got page like this /topic/10 (10 is id topic) and nextly i want to add inscription to this topic so after click button submit should be /inscription/topic/10 (10 is id topic). Now is the problem, when i click button i got Error 405 but when i take this line and write by hand or copy address and paste it again then i got inscription page. Where is problem? Its can be thymeleaf or spring request?
Code is below
#Controller
#RequestMapping("/inscription/")
public class InscriptionController {
private InscriptionService inscriptionService;
private TopicService topicService;
#Autowired
private InscriptionController(InscriptionService inscriptionService, TopicService topicService) {
this.inscriptionService = inscriptionService;
this.topicService = topicService;
}
#GetMapping("topic/{id}")
public String in2(#ModelAttribute("inscription") Inscription inscription, #PathVariable Long id, Model model) {
Topic topic = topicService.findOne(id);
model.addAttribute("inscription", inscription);
return "inscription";
}
Thymeleaf - here when i press button New Message should be go to inscription/topic/id
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Create new topic</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-light" style="background-color: #969bd9;">
<span class="navbar-brand">Create new topic</span>
</nav>
<div class = "container">
<div class = "row">
<div class = "col-md6 col-md-offset-3">
<form th:action="#{/inscription/topic/{id}(id = ${topic.id})}" th:object="${inscription}" method="post">
<h5>
<a th:href="#{/topic/{id}(id = topic.id)}"></a>
<span th:text="${topic.title}"></span>
</h5>
<div class="col s10">
<div class="row">
<div class="col s11">
Stworzony
<p th:text="${topic.createdAt} ? ${#calendars.format(topic.createdAt, 'HH:mm dd MMMM yyyy')}"></p>
<p th:utext="${#strings.replace(topic.text,T(java.lang.System).getProperty('line.separator'),'<br />')}"></p>
<div class="divider"></div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">New message</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>

405 error means "Method Not Allowed". When you click the submit button, your form will perform the POST method, which doesn't have the corresponding mapping in your controller. You should add POST mapping to your controller or change the form method to GET.

Related

Why is Only One Object Appearing in my Database? (Using Spring and MongoDB)

I am working on an ecommerce website using Eclipse, Spring, and MongoDB. Whenever I try creating a new category (URL is http://localhost:8080/admin/categories), the first one appears, but when I try creating a new one, it just replaces my first one. For example, if I create a category called "car", it appears, but then when I create a new one called "bike", the latter takes the place of the former. I of course want category car to be first and category bike to be second. I am assuming it has something to do with the id not saving properly because in my MongoDB collection, the entry shows nothing for _id (normally it does show something for _id).
Here is my code:
package com.ecommerce.website.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.ecommerce.website.model.Category;
import com.ecommerce.website.service.CategoryService;
#Controller
public class AdminController {
//Injecting dependency
#Autowired
CategoryService categoryService;
//This method maps for /admin endpoint. It shows the adminHome.html page. The method is #GetMapping because you are getting information
//#return the adminHome page
#GetMapping("/admin")
public String adminHome() {
//Display html page
return "adminHome";
}
//This method maps for /admin/categories endpoint. It shows the categories.html page. The method is #GetMapping because you are getting information
//#return the categories page
#GetMapping("/admin/categories")
public String getCat(Model model) {
model.addAttribute("categories", categoryService.getAllCategories());
//Display html page
return "categories";
}
//This method maps for /admin/categories endpoint. It shows the categoriesAdd.html page, but before that, it creates
//a model that is sent to the html file via Thymeleaf. The categoriesAdd.html page is a form for adding a category
//The method is #GetMapping because you are getting information
//#param model will hold the category object so that the form can add information to it
//#return the categoriesAdd page
#GetMapping("/admin/categories/add")
public String getCatAdd(Model model) {
//Adding the model name "category", and creating a new Category object and putting it in the model
model.addAttribute("newCategory", new Category());
//Display html page
return "categoriesAdd";
}
//This method maps for /admin/categories endpoint. It allows the user to add a category to the list of categories
//The method is #PostMapping because you are sending information
//#param category gets its value from the ModelAttribute, which gets its value from the form
//#return the categories page
#PostMapping("/admin/categories/add")
public String postCatAdd(#ModelAttribute("newCategory") Category category) {
//Calling categoryService to add the category
categoryService.addCategory(category);
//Redirecting to page that shows all categories
return "redirect:/admin/categories";
}
}
package com.ecommerce.website.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ecommerce.website.model.Category;
import com.ecommerce.website.repository.CategoryRepository;
#Service
public class CategoryService {
//Injecting dependency
#Autowired
CategoryRepository categoryRepository;
//This method calls categoryRepository to add a category to the database
//#param category is the category that is being added
public void addCategory(Category category) {
//Saving the category to the database
categoryRepository.save(category);
}
//This method calls categoryRepository to retrieve a list of categories
//#return the list of categories
public List<Category> getAllCategories() {
return categoryRepository.findAll();
}
}
package com.ecommerce.website.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.ecommerce.website.model.Category;
public interface CategoryRepository extends MongoRepository<Category, String> {
}
package com.ecommerce.website.model;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection = "categories")
public class Category {
#Id
private String id;
private String name;
public Category() {
}
public Category(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This is the page that is supposed to show all the categories
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css"
integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<title>Document</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" >
<div class="container-fluid">
<a class="navbar-brand" href="#">
<img th:src="#{/images/logo.png}" src="../static/images/logo.png" width="auto" height="40" class="d-inline-block align-top" alt=""/>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto"></ul>
<ul class="navbar-nav">
<li class="nav-item active">
<!-- This anchor allows the user to go to the admin home page. It maps to the method with
/admin endpoint -->
<a class="nav-link" th:href="#{/admin}" href="#">admin-home</a>
</li>
<li class="nav-item active">
<!-- This anchor allows the user to logout. It maps to the method with
/logout endpoint -->
<a class="nav-link" th:href="#{/logout}" href="#">logout</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<!-- This anchor allows the user to go to the categoriesAdd page. It maps to the method with
/admin/categories/add endpoint -->
<a th:href="#{/admin/categories/add}" style="margin: 20px 0" class="btn btn-primary">Add Category</a>
<table class="table">
<!-- Creating the table heads -->
<thead class="thead-light">
<tr>
<th scope="col">SN</th>
<th scope="col">Category Name</th>
<th scope="col">Delete</th>
<th scope="col">Update</th>
</tr>
</thead>
<tbody>
<!-- Looping through each category and displaying its name (iStat is responsible for the serial numbers) -->
<tr th:each="category, iStat : ${categories}">
<!-- iStat.index is 0th index, so we add 1 so that the SN's start at 1 -->
<th scope="row" th:text="${iStat.index + 1}">1</th>
<td th:text="${category.name}">Larry</td>
<!-- ????Buttons: first deletes the product; second maps to the /update endpoint, which takes the user to edit.html
for whichever product the product.id is for (id is appended to the URL, which is how the /show endpoint
is able to access it -->
<td>Delete</td>
<td>Update</td>
</tr>
</tbody>
</table>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
This is the page for adding a new category
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css"
integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">
<title>Document</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" >
<div class="container-fluid">
<a class="navbar-brand" href="#">
<img th:src="#{/images/logo.png}" src="../static/images/logo.png" width="auto" height="40" class="d-inline-block align-top" alt=""/>
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto"></ul>
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" th:href="#{/admin}" href="#">admin-home</a>
</li>
<li class="nav-item active">
<a class="nav-link" th:href="#{/logout}" href="#">logout</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-sm-4">
<!-- Mapping to the /admin/categories/add endpoint (#PostMapping one). We are using post method since we are
sending info. The category object comes from the getCatAdd() method -->
<!-- This is the real work: send form data to /admin/categories/add. "category" is the model attribute -->
<form th:action="#{/admin/categories/add}" method="post" th:object="${newCategory}">
<!-- Hidden id field to show which category is being added. It will bind to ModelAttribute to tell your app
which category is being added. *{category_id} selects category_id property on referenced th:object (category) -->
<input type="hidden" name="id" th:field="*{id}">
<div class="form-group">
<label for="name">Name</label>
<!-- Input field. *{name} selects name property on referenced th:object (category) -->
<input type="text" class="form-control" required th:field="*{name}" name="name" id="name" placeholder="Enter name">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>

Paginate doesn't word in grails

I have problem with paginate, I use grails 2.4.4
This my index.gsp:
<%# page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title></title>
</head>
<body>
<div>
<g:paginate controller="user" action="index" total="${userTotal}"/>
</div>
</body>
</html>
This is my controller:
class UserController {
def index() {
List<User> users = User.findAll()
render(view: "index", model: [users: users, userTotal: 4])
}
}
In the console I don't have any error and in my page I see nothing.
Array users isn't empty, I checked.
render(view: "index", model: [users: users, userTotal: 4])
You have hardcoded userTotal to be 4. The paginate tag defaults to 10 items per page, so pagination is not required.
If you are concerned about pagination then User.findAll() is probably a bad idea because it will return all of the data.
Default scaffolding will do something like this which is a better idea...
Controller action:
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond userService.list(params), model:[userCount: userService.count()]
}
GORM Data Service:
import grails.gorm.services.Service
#Service(User)
interface UserService {
User get(Serializable id)
List<User> list(Map args)
Long count()
void delete(Serializable id)
User save(User user)
}
The relevant GSP:
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'user.label', default: 'User')}" />
<title><g:message code="default.list.label" args="[entityName]" /></title>
</head>
<body>
<g:message code="default.link.skip.label" default="Skip to content…"/>
<div class="nav" role="navigation">
<ul>
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
<li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
</ul>
</div>
<div id="list-user" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<f:table collection="${userList}" />
<div class="pagination">
<g:paginate total="${userCount ?: 0}" />
</div>
</div>
</body>
</html>
If you really don't want to use a service (highly recommended that you do) then you could change the controller to do something like this...
params.max = Math.min(max ?: 10, 100)
respond User.list(params), model:[userCount: User.count()]
It is my solution:
gsp:
<div class="content scaffold-list">
<g:form controller="user" action="index">
<label>Input user's name:</label>
<div class="form-group">
<g:textField name="userName"/>
<g:submitButton name="search"/>
</div>
<g:each var="user" in="${users}">
<p>User with name: ${user.name}</p>
</g:each>
</g:form>
<div class="pagination">
<g:paginate controller="user" action="index"
max="5" total="${userCount}"/>
</div>
</div>
controller:
def index(String userName) {
initUsersAndPokemons()
PagedResultList users = fourthService.findUsersByName(
userName,
params.int('max', 5),
params.int('offset', 0))
[users: users, userCount: users.getTotalCount()]
}
service:
PagedResultList findUsersByName(String userName, int max, int offset) {
BuildableCriteria bc = User.createCriteria()
bc.list(max: max, offset: offset) {
like('name',userName)
}
}

How to send information of a checkbox from the view to the controller in Thymeleaf?

I'm trying to send the values of looped checbox for print them in the controller. When I press a button, I want the information of the selected checbox to be send to the controller and print it in the console, but when I press my button to send the information to the controller method, it throws me a NullPointerException.
My HTML look like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Select Cities</title>
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row align-items-center">
<div class="col-4 mt-3">
<form action="">
<div class="form-check" th:each="names : ${namesOfCities}">
<label for="" class="form-check-label">
<input type="checkbox" name="lista" th:value="${names}" th:text="${names}">
</label>
</div>
Aceptar
</form>
</div>
<div class="col-8">
<div id="chart" style="height: 400px"></div>
</div>
</div>
</div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-3d.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="../js/jquery-3.3.1.min.js"></script>
<script src="../js/popper.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
</body>
</html>
Here in the HTML I create a checkbox for each element in the list sended by the controller.
I have two methods in the Controller, the first one:
#GetMapping("/selectCities")
public ModelAndView selectCities(Model model){
ModelAndView mav = new ModelAndView(ViewConstant.SELECT_CITIES);
//List<String> citiesNames = namesOfCities();
List<String> citiesNames = recortarList();
model.addAttribute("namesOfCities", citiesNames);
return mav;
}
This method shows the HTML view and send a List of String that contains cities names.
The second method looks like this:
#GetMapping("/showSelectedCities")
public ModelAndView showSelectedCities(#RequestParam(name = "lista", required = false)List<String> id){
ModelAndView mav = new ModelAndView(ViewConstant.SELECT_CITIES);
for(int x=0;x<id.size();x++){
System.out.println(id.get(x));
}
return mav;
}
In this I want to recive the names of the cities of the selected checkbox sended by the view and print them in the console, but when I try it throws me a NullPointerException. How is the correct form to send information from a checkbox to the controller?
You have used form but you are submitting information through a link which is not possible. To solve this problems :
1) Give an action to the form as :
2) And add submit button inside form.
here
3) Clicking on submit button you will be redirected to action url.
Now you would get information filled inside form.

How the Spring maps url from a jsp to its respective controller?

I am working on a Spring web project , I have many JSP files and many controllers , but I am not able to grab how this
<form:form action="updateCustomer" autocomplete="true" commandName="customer">
form is automatically mapped to the respective controller in which the updateCustomer is defined. There are other controllers also but how exactly the url updateCustomer goes to respective controller.
The Customer.jsp file is as follows :
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html lang="en">
<head>
<link
href="${pageContext.request.contextPath}/static/css/bootstrap-nav-wizard.css"
rel="stylesheet">
<link
href="${pageContext.request.contextPath}/static/css/intlTelInput.css"
rel="stylesheet">
<style>
ul.nav-wizard li a i {
margin-right: 15px;
}
</style>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="${pageContext.request.contextPath}/static/js/flickity.pkgd.min.js"></script>
<script src="${pageContext.request.contextPath}/static/js/jquery.fancybox.pack.js"></script>
<script src="${pageContext.request.contextPath}/static/js/waypoints.min.js"></script>
<script src="${pageContext.request.contextPath}/static/js/custom/customer.js"></script>
<script src="${pageContext.request.contextPath}/static/js/jqueryform-validator.js"></script>
<script src="${pageContext.request.contextPath}/static/js/custom/common.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/intlTelInput.min.js"></script>
</head>
<body>
<form:form action="updateCustomer" autocomplete="true" commandName="customer">
<form:hidden path="buyerId"/>
<form:hidden path="user.userId" />
<section>
<div class="container" style="margin-top: 10px;">
<div class="row">
<h3 class="main-title">My Profile</h3>
</div>
<div class="row">
<div>
<!-- Main Content Start -->
<div id="myTabContent" class="tab-content">
<!-- Step 1 Content Start -->
<div class="tab-pane fade active in" id="step1">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Personal Details</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-sm-4 form-group">
<label>First Name</label><span class="req">*</span>
<form:input class="form-control" path="user.firstName"
type="text" maxlength="75"
/>
</div>
<div class="col-xs-12 col-sm-4 form-group">
<label>Middle Name</label>
<form:input class="form-control" path="user.middleName" maxlength="75"
type="text" />
</div>
<div class="col-xs-12 col-sm-4 form-group">
<label>Last Name</label><span class="req">*</span>
<form:input class="form-control" path="user.lastName"
type="text" maxlength="75"
/>
</div>
</div>
</div><!--//panel body over -->
</div><!--//panel panel default over -->
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Company Details</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-xs-12 col-sm-6 form-group">
<label>Company Name</label><span class="req">*</span>
<form:input path="companyName" class="form-control"
type="text"
maxlength="45"
/>
</div>
</div>
</div>
</div>
</div>
<div class="row" style="display: none;" id="mainBtn">
<div class="col-xs-6 col-sm-2 pull-right" style="min-width: 170px;">
<button class="btn" type="submit" name="action" value="2" style= "min-width: 170px;">Save & Continue</button>
</div>
<div class="col-xs-6 col-sm-2 pull-right" style="text-align: right; padding-right:0px;"> <!-- added property padding-right:0px; to style on 17/7 -->
<button class="btn" type="submit" name="action" value="1" style= "min-width: 170px;">Save</button>
</div>
</div>
<div class="row" id="editBtn">
<div class="col-xs-6 col-sm-2 pull-right">
<a class="btn pull-right" id="edit"
href="#" onclick="makeEditable()" style="min-width: 170px;">Edit</a>
</div>
</div>
<br> <br>
</div>
<!-- Step 1 Content End -->
</div>
<!-- Main Content End -->
</div>
</div>
</div>
<!-- /container -->
</section>
</form:form>
</body>
</html>
The controller File is as follows :
package com.htss.web.controller;
//assume all imports
#Controller
#RequestMapping("/buyer")
public class BuyerController {
#Autowired
private BuyerService customerService;
#Autowired
private UserService userService;
#Autowired
private CommonService commonService;
#Autowired
private MessageSource messageSource;
#RequestMapping(value = "/open/customer")
public String customerInfo() {
return "customer";
}
#RequestMapping(value = "/edit_profile")
public String editCustomerProfile(HttpSession session, Model model) {
Integer buyerId = (Integer) session.getAttribute("entityId");
BuyerFormBean bean = customerService.retrieveCustomer(buyerId);
Long userId = (Long) session.getAttribute("userId");
try {
UserFormBean user = userService.getUser(userId);
bean.setUser(user);
} catch (IllegalAccessException | InvocationTargetException e) {
}
model.addAttribute("customer", bean);
model.addAttribute("countries", commonService.getCountryDropdown());
model.addAttribute("action", "updateCustomer");
return "buyerProfile";
}
#RequestMapping(value = "/updateCustomer")
public String updateCustomerProfile(Model model, HttpSession session, BuyerFormBean customer) {
try {
if (action == 1 || action == 2) {
customer = customerService.modifyCustomer(customer);
}
}
catch (Exception e) {
e.printStackTrace();
model.addAttribute("error",messageSource.getMessage("msg.Error",null,Locale.US));
}
Integer buyerId = (Integer) session.getAttribute("entityId");
BuyerFormBean bean = customerService.retrieveCustomer(buyerId);
Long userId = (Long) session.getAttribute("userId");
try {
UserFormBean user = userService.getUser(userId);
bean.setUser(user);
} catch (IllegalAccessException | InvocationTargetException e) {
}
model.addAttribute("customer", bean);
model.addAttribute("message",messageSource.getMessage("msg.Success",null,Locale.US));
return "Customer";
}
}
Now the question is when I click save button the url formed is :
http://localhost:8080/82ism/buyer/updateCustomer
How this happened ? and now when I need a button to some other controller I need to give the whole URL as follows :
${pageContext.request.contextPath}/seller/edit_profile
The project is working all fine I am just trying to understand this concept.
The whole point of spring is so you don't have to worry about that stuff.
jsp's get found cause of the propperty's in application.propperties:
like:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
For the forms and methods... It's not like it magicly happens.
A form you have to cal by name and methods are eighter mapped to a url or action
like:
#RequestMapping("/")
or
#RequestMapping(method=RequestMethod.POST)
To call the values of a form from the controller you first have to bind them to a entity model with the fields of the form as variables.
The method would look like:
#RequestMapping(method = RequestMethod.POST)
public String processRegister(#ModelAttribute("userForm") User user,
Map<String, Object> model) {
...
return "view";
}

Control over where a form display the output from your submission

In my web application, I have a home page where the options available to the user are placed in a fixed sidebar in the top of the screen, and each one of this options are opened inside of a tag <div> in this same page.
My problem is: when this content is a form, and I submit it to the server, after the processing, the output page isn't opened in this <div>, but in the entire navigation space. What I want is a way of capture this return and display it in the same <div> it was originated.
the code for my home page is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.ico">
<title>HorarioLivre</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="navbar-fixed-top.css" rel="stylesheet">
<!-- Just for debugging purposes. Don't actually copy this line! -->
<!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body onload="close_page()">
<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">HorarioLivre</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Evento</li>
<li>Lista Horarios</li>
<li>Cadastra Horarios</li>
<li>Usuarios</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
${usuario.nome} <b class="caret"></b>
<ul class="dropdown-menu">
<li>Perfil</li>
<li>Configurações</li>
<li>Sair</li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<div class="page-header">
<h1></h1>
</div>
<div class="panel panel-default" id="results">
<div class="panel-heading">
<div align="right"><button type="button" class="btn btn-lg btn-danger" onclick="close_page()">Fechar</button></div>
</div>
<div class="panel-body" id="content">
Panel content
</div>
</div>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script>
function load_page(url){
$('#results').css("display", "block");
$('#content').load(url);
$('#container').draggable();
}
function close_page(){
$('#results').css("display", "none");
$('#content').empty();
}
</script>
</body>
</html>
I am using Spring, and the pages linked here are handled by Controller. By example,the page "cadastra_evento.html" is:
<%# 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>Lista de Eventos</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="alert alert-info">
<strong>Eventos</strong> Segue a lista de eventos cadastrados.
</div>
<div class="container">
<div class="row">
<div class="col-md-3">Nome</div>
<div class="col-md-3">Descrição</div>
<div class="col-md-3">Periodo</div>
<div class="col-md-3">Duração</div>
</div>
<c:forEach var="item" items="${lista}">
<div class="row">
<div class="col-md-3"><c:out value="${item.nome}"/></div>
<div class="col-md-3"><c:out value="${item.descricao}"/></div>
<div class="col-md-3"><c:out value="${item.data_inicial}"/> - <c:out value="${item.data_final}"/></div>
<div class="col-md-3"><c:out value="${item.duracao}"/></div>
</div>
</c:forEach>
</div>
<div class="alert alert-info">
<strong>Novo</strong> Cadastre um novo evento.
</div>
<form method="post" action="cad_evento.html">
<input type="text" name="nome" placeholder="Nome" size=20 maxlength=40> <br/>
<input type="text" name="descricao" placeholder="Descrição" size=30 maxlength=100> <br/>
<h3>Periodo da Data</h3>
inicio: <input name="data_inicial" placeholder="DD-MM-AAAA" required pattern="\d{2}-\d{2}-\d{4}" /> <br/>
final: <input name="data_final" placeholder="DD-MM-AAAA" required pattern="\d{2}-\d{2}-\d{4}" /> <br/>
<h3>Periodo do Horário</h3>
inicio: <input name="hora_inicial" placeholder="HH:MM:SS" required pattern="\d{2}:\d{2}:\d{2}" /> <br/>
final: <input name="hora_final" placeholder="HH:MM:SS" required pattern="\d{2}:\d{2}:\d{2}" /> <br/>
<input type="text" name="duracao" placeholder="duração" size=20 maxlength=2> <br/>
<button type="submit" class="btn btn-lg btn-primary">Cadastrar</button>
</form>
</body>
</html>
To finish, the page "cad_evento.html" used as action for the form above, is handled by method of same name from Controller:
#RequestMapping(value="/cad_evento", method=RequestMethod.POST)
public ModelAndView cadastra_evento(#RequestParam("nome") String nome, #RequestParam("descricao") String descricao, #RequestParam("data_inicial") String data_inicial, #RequestParam("hora_inicial") String hora_inicial, #RequestParam("data_final") String data_final, #RequestParam("hora_final") String hora_final, #RequestParam("duracao") int duracao) {
if(sessao != null)
{
if(sessao.getUsuario().temAutorizacao("cad_evento"))
{
Date d_inicio = new Date(Date.parse(data_inicial));
Date d_final = new Date(Date.parse(data_final));
Time h_inicio = new Time(Time.parse(hora_inicial));
Time h_final = new Time(Time.parse(hora_final));
EventoDAO evento = new EventoDAO(nome, descricao, d_inicio, d_final, h_inicio, h_final, duracao, sessao.getUsuario());
int saida = evento.cadastra();
if(saida == 0)
{
ModelAndView mav = new ModelAndView();
mav.addObject("message", "Erro ao cadastrar o evento");
return mav;
}
else
{
ModelAndView mav = new ModelAndView();
mav.setViewName("/listagem_evento");
return mav;
}
}
else
{
ModelAndView mav = new ModelAndView();
mav.addObject("message", "Usuário sem permissão de acesso");
return mav;
}
}
else
{
ModelAndView mav = new ModelAndView();
mav.setViewName("/usuario_login_page");
return mav;
}
}
Someone have any thoughts about how to do that?
Well, spring mvc just open new page with a content you set in ModelAndView. If you want to load somthing just in some part of page ( in this case ) there pure javascript / jquery ajax is needed. So steps needed here:
Add javascript which will do ajax request to controller
Controller need to return JSON ( #ResponseBody can help you )
You have to do some DOM manipulation using javascript/jquery to put JSON answer to your div.

Categories

Resources