I have got a form with file upload and sometimes I'm catching 415 unsupported media type with no messages in log. This is my form:
<form:form method="post" enctype="multipart/form-data"
class="form-horizontal" modelAttribute="massSMSForm"
style="width: 650px;">
<c:if test="${!empty errorFlag}">
<div class="alert alert-danger">
× <b>Ошибка.
</b>
<form:errors path="*" />
</div>
</c:if>
<div class="well" style="width: 650px;">
<table style="width: 100%">
<tr>
<td align="left"><b>Наименование рассылки*</b></td>
<td align="right"><form:input path="title" type="text"
class="form-control" id="title" style="width:340px;"
maxlength="15" /><br /></td>
<tr>
<td align="left"><b>Отправитель*</b></td>
<td align="right"><form:input path="from" type="text"
maxlength="15" class="form-control" id="from" style="width:340px;" /><br /></td>
</tr>
<tr>
<td align="left"><b>Дата начала рассылки</b></td>
<td align="right"><form:input id="deliveryDate"
path="deliveryDate" type="text" autocomplete="off"
class="form-control" placeholder="сейчас" style="width:310px;" /><br /></td>
</tr>
<tr>
<td align="left"><b>Срок жизни</b></td>
<td align="right"><form:input id="expiration" path="expiration"
type="number" min="1" max="72" autocomplete="off"
class="form-control" placeholder="в часах" style="width:310px;" /><br /></td>
</tr>
<tr>
<td align="left"><b>Файл рассылки*</b></td>
<td align="right"><input type="file" name="file"
accept="text/xml, text/plain" id="mass" /><br /></td>
</tr>
</table>
<br /> <b>Текст сообщения рассылки</b><br /> <br />
<c:choose>
<c:when test="${massSMSForm.ignore==false}">
<form:textarea path="message" class="form-control" rows="5"
id="message" placeholder="..." maxlength="500" />
</c:when>
<c:otherwise>
<form:textarea path="message" class="form-control" rows="5"
id="message" placeholder="..." disabled="true" maxlength="500" />
</c:otherwise>
</c:choose>
<br />
<form:checkbox path="ignore" id="ignoreBox" />
<small>Игнорировать сообщение</small>
</div>
<div style="text-align: right">
<a href="/${initParam['appName']}/userRole/"
class="btn btn-link btn-sm">Назад</a><input
class="btn btn-success btn-sm" type="submit" name="send"
onclick="myAlert()" value="Отправить" />
</div>
</form:form>
<script type="text/javascript">
function confirmSend() {
if (confirm("Отправляем сообщения?")) {
return true;
} else {
return false;
}
}
</script>
<script type="text/javascript">
jQuery('#deliveryDate')
.datetimepicker(
{
lang : 'ru',
i18n : {
ru : {
months : [ 'Январь', 'Февраль', 'Март',
'Апрель', 'Май', 'Июнь', 'Июль',
'Август', 'Сентябрь', 'Октябрь',
'Ноябрь', 'Декабрь', ],
dayOfWeek : [ "Вс", "Пн", "Вт", "Ср", "Чт",
"Пт", "Сб", ]
}
},
dayOfWeekStart : 1,
timepicker : true,
format : 'Y-m-d H:i'
});
</script>
<script type="text/javascript">
document.getElementById('ignoreBox').onchange = function() {
document.getElementById('message').disabled = this.checked;
};
</script>
And method:
#RequestMapping(value = "/sms/mass", method = RequestMethod.POST, headers = "content-type=multipart/form-data")
public String massSMSProcess(Map<String, Object> map,
#ModelAttribute("massSMSForm") MassSMSForm massSMSForm,
BindingResult result, HttpSession session) throws IOException {
session.removeAttribute(SESSION_KEY);
massSMSFormValidator.validate(massSMSForm, result);
if (result.hasErrors()) {
map.put("errorFlag", true);
return massSMSPage(map, massSMSForm, session);
} else {
try {
SMS sms = SmsBuilder.build(massSMSForm);
session.setAttribute(SESSION_KEY, sms);
map.put("title", "Подтверждение операции");
map.put("count", sms.getSmsEntityList().size());
} catch (IOException e) {
// mailer.send("/sms/mass :" + e.getMessage() + "form:"
// + massSMSForm);
map.put("error", "Ошибка ввода/вывода");
return distributionListPage(map);
}
return "confirmMassSMSPage";
}
}
What is wrong? Is it js problem or what? Should I add new headers? What's your thoughts?
No need to set headers in #RequestMapping. Post request from Form with enctype="multipart/form-data" is by default consider as a multipart request in Controller.
So here your request is multipart already, you just need to to add some maven repository for file upload to support your multipart-data.
Refer this Spring file upload documentation and Go through this example
Try to change :
headers = "content-type=multipart/form-data"
to :
consumes="multipart/form-data"
So your #RequestMapping will become like this :
#RequestMapping(value = "/sms/mass",
method = RequestMethod.POST,
consumes="multipart/form-data")
If you have not done this already, try adding multipartResolver bean in application context. Add this in application / servlet context xml file.
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
And supporting jar file commons-fileupload jar. Maven dependency for this jar is :
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
Try adding exception handler to the controller. It will help you to identify the real cause of the issue:
#ExceptionHandler({Exception.class})
public void resolveException(Exception e) {
e.printStackTrace();
}
Related
I have a view in which I have a Form to create a new Exercise object, and a table to display all exercises. Now I want that the table automatically refreshes with the newly created exercise. Currently it displays the table as empty, until I manually go to localhost:8080/exercise again.
Here's my controller:
#Controller
public class ExerciseController {
#Autowired
private ExerciseService exerciseService;
#Autowired
private ModelMapper modelMapper;
#GetMapping("/exercise")
public String exerciseView(final Model model) {
List<Exercise> exerciseList = exerciseService.getAllExercises();
model.addAttribute("exerciseDTO", new ExerciseDTO());
model.addAttribute("title", "Create an Exercise");
model.addAttribute("exercises", exerciseList);
return "exercise";
}
#PostMapping("/exercise")
public String createExercise(#ModelAttribute final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
this.exerciseService.createExercise(exercise);
return "exercise";
}
}
And my thymeleaf template:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form action="#" th:action="#{/exercise}" th:object="${exerciseDTO}" method="post">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" th:field="*{bpm}" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Now I thought the createExercise method returning "exercise" would call the exerciseView method and thus calling exerciseService.getAllExercises(). Is there a way to achieve this functionality? Or is there an even better way, without reloading the whole page?
To serve up data without page refreshes you'd need a client side technology like Angular or React. Or plain old javascript. But you can't serve up new data to a page in spring mvc w/o page refreshes.
You can use AJAX to send requests from a client side to a server side and receive an answer without refreshing the page.
Unfortunately I don't have enough time and I can't complete the code but you can do something like this:
function submitItems() {
var contextPath = $("meta[name='ctx']").attr("content");
var exerciseDto = {};
exerciseDto.name = $("#name").val();
exerciseDto.description = $("#description").val();
exerciseDto.typeSelector = $("#typeSelector).val();
exerciseDto.bpmInput = $("#bpmInput").val();
$.ajax({
dataType : "json",
type : "post",
url : contextPath + "/exercise",
data : JSON.stringify(exerciseDto),
cache : false,
contentType : "application/json",
beforeSend : function(xhr) {
xhr.setRequestHeader(header, token);
},
success : function(data) {
console.log(data);
//HERE YOU NEED ACTION TO UPDATE TABLE.
},
error : function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
console.log('getJSON request failed! ' + textStatus);
}
});
}
and then your view must be like this:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form onsubmit="submitItems();return false;">
<p>Name: <input id="name" type="text" /></p>
<p>Description: <input id="description" type="text" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Bear in mind that you need to create an JS action that will update the table. There are quite a few ways of doing that (you can push new data to the Datatable or add new content using JS functions).
I hope this will help you understand a bit more how the AJAX works.
PS. You will have to update your controller as well to return the results, in your instance will be
#PostMapping("/exercise")
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
//this.exerciseService.createExercise(exercise);
//return "exercise";
return this.exerciseService.createExercise(exercise);
}
You will have to change this line
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
to your createExercise Domain Type.
Need some advice how should I retrieve a list of exhibits.
In my html template below, I only put one record of exhibit. If i were to put additional rows/records of exhibit, how do i go about mapping them to the controller.
HTML Template
<h3>Exhibit Details</h3>
<div class="table-responsive">
<table id="exhibitTable"
class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>Exhibit Type</th>
<th>Description</th>
<th>Marking</th>
<th>Remarks</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-group col-md-3">
<div class="cols-sm-10">
<select class="form-control selectpicker cols-md-3"
th:value="${exhibit.exhibitType}" id="exhibitType"
name="exhibitType" roleId="exhibitType">
<option value="">Select Type</option>
<option>Desktop</option>
<option>Laptop</option>
<option>Mobile Device</option>
<option>Portable Storage</option>
<option>Server</option>
<option>Video System</option>
<option>Save As</option>
<option>Others</option>
</select>
</div>
</div>
</td>
<td>
<div class="form-group col-md-3">
<input type="text" name="exhibitDescription"
id="exhibitDescription"
th:value="${exhibit.exhibitDescription}" />
</div>
</td>
<td>
<div class="form-group col-md-3">
<input type="text" name="exhibitMarking" id="exhibitMarking"
th:value="${exhibit.exhibitMarking}" />
</div>
</td>
<td><div class="form-group col-md-3">
<input type="text" name="exhibitRemarks" id="exhibitRemarks"
th:value="${exhibit.exhibitRemarks}" />
</div></td>
</tr>
</tbody>
</table>
</div>
Controller
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerIncidentPost(#ModelAttribute("incident") Incident incident,
#ModelAttribute("exhibit") Exhibit exhibit, Principal principal) throws Exception {
long year = Calendar.getInstance().get(Calendar.YEAR);
incident.setIncidentYear(year + "");
Long refNo = incidentService.findMaxRefNoCurrentYear(year + "");
if (refNo == null)
refNo = (long) 1;
else
refNo += 1;
incident.setIncidentRefNo(refNo);
incident.setIncidentStatus(Incident.INCIDENT_REGISTERED);
incident.setIncidentOpeningTimestamp(new Date());
User user = userService.findByUsername(principal.getName());
incident.setIncidentCreatedBy(user);
incidentService.createIncident(incident);
exhibitService.createExhibit(exhibit);
return "redirect:/incident";
}
I've attempted to add the following to my template
<tr data-th-each="exhibit:${exhibitList}">
and the following to my controller
#ModelAttribute("exhibitList") ArrayList<Exhibit> exhibitList
but did not work.
Thanks in advance.
I can only assume this is vb.net since you didn't specify. You need to pass in the complete dataset to the page. Each item in the dataset will be one pre-loaded instance of the model. Then you can do a for each loop on the page itself and generate the html dynamically. Hope this helps.
I have a one welcome.jsp page where I am collecting few information and with the help of HTML FORM sending this request and response object to servlet to insert data into DB, so after this operation I want to go back to the same Welcome.jsp, but when I tried to use the
RequestDispatcher rs = request.getRequestDispatcher("Welcome.jsp");
rs.forward(request, response);
I lost all the populated values on the same Welcome.jsp,
So please suggest is there a way where I can send the existing request and response object with new request and response to the servlet and will send back old request and response object from servlet to JSP.
So below is code from "Welcome.jsp"
<!DOCTYPE html>
<%#page import="***********"%>
<%#page import="java.io.Console"%>
<%#page import="java.sql.Connection"%>
<%#page import="java.sql.PreparedStatement"%>
<%#page import="java.sql.ResultSet"%>
<%#page import="java.util.ArrayList"%>
<html>
<head>
<title>Treatment Dashboard</title>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- <script type="text/javascript">
function noBack()
{
window.history.forward()
}
noBack();
window.onload = noBack;
window.onpageshow = function(evt) { if (evt.persisted) noBack() }
window.onunload = function() { void (0) }
</script> -->
</head>
<body>
<%
HttpSession sessions = request.getSession();
String lanId = (String)sessions.getAttribute("lanid");
System.out.println("session Lanid:- " + lanId);
%>
<!-- Codrops top bar -->
<div class="codrops-top">
<a>
<strong> VALUES </strong>
</a>
<span class="right">
<strong> VALUE </strong>
</span>
<div class="menu-area">
<div id="dl-menu" class="dl-menuwrapper">
<button class="dl-trigger">Open Menu</button>
<ul class="dl-menu">
<li>Profile</li>
<li>Weekends Shift</li>
<li>Comp Off</li>
<li>Log Off</li>
</ul>
</div>
</div>
<!-- intro area -->
<div id="intro">
<div class="intro-text">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="intro-data">
<div class="brand">
<%
String fname = (String) request.getAttribute("fname");
String lname = (String) request.getAttribute("lname");
String emailid = (String) request.getAttribute("emailid");
String ext = (String) request.getAttribute("ext");
String rmlanid = (String) request.getAttribute("rmlanid");
String role = (String) request.getAttribute("role");
String ipadd = (String) request.getAttribute("ipadd");
String wcounts = (String) request.getAttribute("weekendsCount");
String acocounts = (String) request.getAttribute("appliedCompOff");
String rcocounts = (String) request.getAttribute("remainingCompOff");
String pacocounts = (String) request.getAttribute("appliedCompOffPendingApprovalcount");
%>
<table style="width:100%" >
<tr>
<td>
<label for="userName" class="uname" data-icon="u"> Name :- </label>
</td>
<td>
<label for="userName" class="uname" data-icon="u"><%=fname%> <%=lname%></label>
</td>
</tr>
<tr>
<td>
<label for="userEmail" class="email" data-icon="u"> Email :- </label>
</td>
<td>
<label for="userEmail" class="email" data-icon="u"><%=emailid%> </label>
</td>
</tr>
<tr>
<td>
<label for="userExt" class="ext" data-icon="u"> EXT :- </label>
</td>
<td>
<label for="userExt" class="ext" data-icon="u"><%=ext%> </label>
</td>
</tr>
<tr>
<td>
<label for="userRmlanid" class="rmlanid" data-icon="u"> RM Lan-Id :- </label>
</td>
<td>
<label for="userRmlanid" class="rmlanid" data-icon="u"><%=rmlanid%> </label>
</td>
</tr>
<tr>
<td>
<label for="userIpadd" class="ipadd" data-icon="u"> TechM Machine IP :- </label>
</td>
<td>
<label for="userIpadd" class="ipadd" data-icon="u"><%=ipadd%> </label>
</td>
</tr>
<tr>
<td>
<label for="userWeekendsNumber" class="weekends" data-icon="WND"> Worked ON Weekends :- </label>
</td>
<td>
<label for="userWeekendsNumber" class="weekends" data-icon="WND"> <%=wcounts%> </label>
</td>
</tr>
<tr>
<td>
<label for="userCompOffApplied" class="compoff" data-icon="u"> Applied Comp Off :- </label>
</td>
<td>
<label for="userCompOffApplied" class="compoff" data-icon="u"> <%=acocounts%> </label>
</td>
</tr>
<tr>
<td>
<label for="userCompOffAvailed" class="compoff" data-icon="u"> Remaining Comp Off :- </label>
</td>
<td>
<label for="userCompOffAvailed" class="compoff" data-icon="u"> <%=rcocounts%> </label>
</td>
</tr>
<tr>
<td>
<label for="userCompOffPendingApproval" class="compoff" data-icon="u"> CompOff Pending For Approval :- </label>
</td>
<td>
<label for="userCompOffPendingApproval" class="compoff" data-icon="u"> <%=pacocounts%> </label>
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit" value="Update"/>
<!-- <input type="submit" value="Cancel"/> -->
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Weekend Shift -->
<section id="WeekendsShift" class="home-section bg-white">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="intro-data">
<form method = "post" action="AddWeekendsShiftDetails" autocomplete="on" >
<div class="brand">
<table style="width:100%" >
<tr>
<td>
<p> <br><br><br>
<label for="weekendDetails" class=""> Worked On Weekend :- </label>
</p>
</td>
<td>
<p><br><br><br>
<input type="text" id= "datepicker1" placeholder="Weekend Date" name="pickedDate"/>
<script>
var datepicker = $("#datepicker1").datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true
}).val();
</script>
</p>
</td>
</tr>
<tr>
<td>
<p> <br>
<label for="processname" class="uname" data-icon="PN" > Process Name :- </label>
</p>
</td>
<td>
<p> <br>
<input id="processname" name="processname" required="required" type="text" placeholder="ex:-BAC"/>
</p>
</td>
</tr>
<tr>
<td> </td>
<td>
<p> <br>
<input type="submit" value="Submit"/>
<input type="reset" value="Reset"/>
</p>
</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
<!-- Comp Off -->
<section id="compoff" class="home-section bg-white">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="intro-data">
<form method = "post" action="AddCompOffDetails" autocomplete="on" >
<div class="brand">
<%
final String USER_WEEKENDS_COMPOFF_DETAILS_QRY = "SELECT WEEKEND_DATE FROM tbl_weekend_rota WHERE (LANID= ? and IS_COMPOFF_CONSUMED = 'N' and IS_APPROVED != 'P')";
Connection con = null;
con = DBConnection.createConnection();
PreparedStatement ps = null;
ps =con.prepareStatement(USER_WEEKENDS_COMPOFF_DETAILS_QRY);
ps.setString(1, lanId);
ResultSet rs = ps.executeQuery();
%>
<table style="width:100%" >
<tr>
<td>
<p> <br><br><br>
<label for="userName" class=""> Apply CompOff :- </label>
</p>
</td>
<td>
<p><br><br><br>
<select name="compOffDate">
<option>-- Available CompOffs --</option>
<% while(rs.next()) { %>
<option><%=rs.getString(1)%></option>
<% } %>
<% con.close();%>
</select>
<p>
</td>
</tr>
<tr>
<td> </td>
<td>
<p><br>
<input type="submit" value="Apply"/>
<input type="reset" value="Reset"/>
<br><br>
</p>
</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</body>
</html>
But when I clicked on Submit button it calls the AddWeekendsShiftDetails servlet,
So in this case this form will send its own request and response object right ?
So from the AddWeekendsShiftDetails servlet I'm inserting values to the Mysql DB
Below is the code from AddWeekendsShiftDetails servlet:-
package com.taskManagment.login;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Date;
//import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/AddWeekendsShiftDetails")
public class AddWeekendsShiftDetails extends HttpServlet {
private static final long serialVersionUID = 1L;
public AddWeekendsShiftDetails() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String sDate = request.getParameter("pickedDate");
String processName = request.getParameter("processname");
try {
Date sqlDate=Date.valueOf(sDate);
Connection con = null;
con = DBConnection.createConnection();
String lanId = SessionDetails.getDetailsFromSession(request, "lanid");
System.out.println("session Lanid from Weekend Servlet:- " + lanId);
insertWeekendShiftDetails(con, lanId, processName, sqlDate);
con.close();
/*RequestDispatcher rs = request.getRequestDispatcher("Welcome.jsp");
rs.forward(request, response);*/
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void insertWeekendShiftDetails(Connection con, String lanId, String processname, Date date ) {
PreparedStatement ps = null;
try {
String insertWeekendRotaDetails = "MY INSERT QUERY";
java.sql.Date sqlDate = new java.sql.Date(new java.util.Date().getTime());
ps = con.prepareStatement(insertWeekendRotaDetails);
ps.setString(1, null); ps.setString(2, lanId);
ps.setDate(3, (java.sql.Date) date); ps.setString(4, processname);
ps.setString(5, "Y"); ps.setString(6, "N");
ps.setString(7, null); ps.setDate(8, null);
ps.setString(9, "N"); ps.setDate(10, sqlDate);
ps.setDate(11, null);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now from the doPost when I want to go back to the "Welcome.jsp" with the code like
RequestDispatcher rs = request.getRequestDispatcher("Welcome.jsp");
rs.forward(request, response);
so it will send back the request and response object of the form which was called from the section
and because of which the other values on the fields are getting null,
So I want a way with which I can hold the old values on Welcome.jsp page.
before sending it back you need to set the attributes you want to the request. You can do that using request.setAttribute("attribute_name","attribute_value"); and the you can retrieve it by using request.getAttribute in the next page. For example
request.setAttribute("errorMsg", "Invalid data . Please correct the input data");
requestDispatcher = request.getRequestDispatcher("error.jsp");
requestDispatcher.forward(request, response);
And then in error.jsp you can use:
<%=request.getAttribute("errorMsg") %>
Not sure what I'm doing wrong on this one. Attempting to make a button that can delete added entities from database. I'm getting a 405 error but I am not sure if I'm getting this because of something I'm doing in the controller or something badly I wrote in thymeleaf. Thanks for any help.
Controller:
#Controller
public class BuyerController {
private BuyerService buyerService;
#Autowired
public void setBuyerService(BuyerService buyerService){
this.buyerService = buyerService;
}
#RequestMapping("/add-buyer")
public String showBuyerPager(Model model){
List<Buyer> buyers = buyerService.findAllBuyers();
model.addAttribute("buyers", buyers);
model.addAttribute("buyer", new Buyer());
return "add-buyer";
}
#GetMapping("/showBuyerForm")
public String addBuyerForm(Model model){
model.addAttribute("buyer", new Buyer());
model.addAttribute("buyerId", new Buyer().getBuyerId());
return "add-buyer";
}
#PostMapping("/addBuyer")
public String postBuyerForm(#ModelAttribute("buyer") Buyer buyer, Model model){
buyerService.saveBuyer(buyer);
model.addAttribute("buyer", new Buyer());
return "redirect:/";
}
#GetMapping("/deleteBuyer")
public String deleteBuyer(#RequestParam("buyerid") Long id){
buyerService.deleteBuyer(id);
return "redirect:/";
}
}
View:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Title</title>
<link href="styles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<header> Welcome to Toner Stock </header>
<h1>Add Buyer</h1>
<div id="mynav" align="center">
<ul>
<li>Home</li>
<li>Add Buyer</li>
<li>Add Manager</li>
<li>Current Stock</li>
<li>Transactions</li>
<li>Order Form</li>
</ul>
</div>
<div id="display-table" align="center">
<form th:action="#{/addBuyer}" th:object="${buyer}" style="width:100%" method="post">
<table>
<td><label>First Name: </label></td>
<td><input type="text" th:field="*{firstName}"/></td>
<td><label>Last Name: </label></td>
<td><input type="text" th:field="*{lastName}"/></td>
<td><label>Enter Address: </label></td>
<td><input type="text" th:field="*{buyerAddress}"/></td>
<td><input type="submit" value="save"/></td>
</table>
</form>
</div>
<div>
<div>
<table id="info-table" align="center" border="1">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
<tr th:each="buyer : ${buyers}">
<td th:text="${buyer.firstName}"></td>
<td th:text="${buyer.lastName}"></td>
<td th:text="${buyer.buyerAddress}"></td>
<td>
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="post">
<input type="hidden" name="buyerid" id="buyerid" value="${buyer.buyerId}"/>
<input type="submit" value="Delete" onClick="return confirm('sure?')"/>
</form>
</td>
</tr>
</table>
</div>
</div>
<div>
<select>
<option th:each="buyer : ${buyers}"
th:text="${buyer.firstName}"
th:value="${buyer.buyerId}"
></option>
</select>
</div>
<div>
<div>
</div>
</div>
</body>
</html>
I don't know much about Thymeleaf but you can keep it simpler and change your front-end code from form to basic link :
<c:url var="deleteBuyer" value="/DeleteBuyer">
<c:param name="buyerId" value="${buyer.buyerId}" />
</c:url>
<a class="simpleLink" href="${deleteBuyer}">delete</a>
And handle it in your controller :
` #GetMapping("/DeleteBuyer")
public String deleteAnswer(#RequestParam("buyerId") int theId) {
buyerService.deleteBuyer(theId);
return "redirect:/";
}`
I hope this help you.
Change the
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="post">
To GET to conform with the Spring request mapping
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="get">
Here are all available HTTP Methods
Hi:) I want to display data on "input" when select "select option".
I included jsp page, which have "input" tag, so using ajax send data to included jsp page.
Here's my code. Name is "new_order.jsp"
<script>
$('select#product').change(function() {
var param = "code=" + $('#product').val();
$.ajax({
url : 'add_products/add_products.jsp',
contentType : "application/x-www-form-urlencoded; charset=UTF-8",
data : param,
type : 'POST',
dataType : 'html',
success : function(data, textStatus, jqXHR){
}
});
});
...
</script>
<body>
<table class="add_products_tb table" data-toggle="table">
<tr>
..
</tr>
<tr>
..
</tr>
<tr>
<td>
..
</td>
<td>
<table>
<tr>
<td>
<select name="product" id="product" class="selectpicker" data-width="150px">
<option data-hidden="true">-Select-
<%
try {
query = "select * from new_product";
rs = stmt.executeQuery(query);
while (rs.next()) {
product_code = rs.getString("product_code");
%>
<option value="<%= product_code %>"> <%= product_code %>
<%
}
} catch (SQLException e) {
out.println(e);
} finally {
}
%>
</select>
</td>
</tr>
</table>
</td>
<jsp:include page="add_products/add_products.jsp" />
</tr>
</table>
</body>
The Next Code. This is included jsp, "add_product.jsp"
<script>
$(document).ready(function() {
$('select#product').change(function() {
<%
product_code = request.getParameter("code");
int size = 0;
try {
query = "select * from new_product where product_code='"+product_code+"'";
rs = stmt.executeQuery(query);
while (rs.next()) {
size = rs.getInt("sizes");
%>
$('#size').val("<%= size %>");
<%
}
} catch (SQLException e) {
out.println(e);
} finally {
}
%>
});
});
</script>
...
<body>
<td>
<input type="text" id="size" class="form-control" name="size" />
</td>
<td>
<input type="text" id="color" class="form-control" name="color" />
</td>
<td>
<input type="text" id="price" class="form-control" name="price" value="0" readonly />
</td>
<td>
<input type="text" id="quantity" class="form-control" name="quantity" value="1" />
</td>
<td>
<input type="text" id="total_price" class="form-control" name="total" value="0" readonly />
</td>
</body>
The Problem is, I want to receive the data, "code", from "new_order.jsp" and display the data on "add_product.jsp", but it doesn't display on the page. I also have debugging the page, the data is sent to "add_product.jsp", but didn't display on input.
I changed a variable "product_code", placed on "add_product.jsp" script, to value, not jsp variable but special value in DB. So, there is data on "input"! Just One....
I want to display using jsp variable. Please help me...T.T Thanks.