Upload an XML file to Java backend in Spring - java

I have an HTML page like this:
<table class="generate-full-width">
<tr>
<td colspan="5" width="100%">
<strong>* Upload the License XML file here. *</strong>
</td>
</tr>
<br><br><br>
<tr>
<td width="100%" colspan="5">
<button mat-raised-button color="primary" type="button" style='margin-right:auto' (click)="selectFile()">File Upload</button>
<input #fileUploadInput type="file" id="fileUpload" hidden name="avatar" (change)="fileChangeEvent($event)">
<br><br>
<a class="generate-full-width" style="color: darkred;" *ngIf="fileName"><strong>{{fileName}}</strong></a>
</td>
</tr>
</table>
The component.ts for this is:
#Component({
selector: 'upload-license-file-dialog',
templateUrl: 'upload-license-file.html',
})
export class uploadFileDialog {
constructor(
public dialogRef: MatDialogRef<AddProductDialog>,
private generateLicenseService: GeneratelicenseService,
private builder: FormBuilder, public dialog: MatDialog,
#Inject(MAT_DIALOG_DATA) public data) {
}
#ViewChild('fileUploadInput', {static: false})
fileUploadVariable: ElementRef;
fileName;
filesToUpload = [];
resetFile(){
this.fileUploadVariable.nativeElement.value = "";
}
selectFile(){
this.resetFile();
let el: HTMLElement = this.fileUploadVariable.nativeElement as HTMLElement;
el.click();
}
fileChangeEvent(fileInput: any) {
let file = fileInput.target.files[0]
console.log(file)
console.log(file.toString());
this.filesToUpload = [];
this.filesToUpload.push(file);
this.fileName = file['name'];
}
}
Right now I cannot do anything with the file. How can I upload the file to the backend, maybe save ot in a temporary location, so that at backend I can parse this file.The backend is Java. Please help.

Related

Spring MVC - fill model on the form

I want to fill the form according to the related book when I click the view or update the link on the page. I know, there is a solution with opening another page but I want to do it on the same page. As you can see on the picture below I can properly get the list on the left table. I have tried a post method below but did not work. So what would you recommend to do it?
Controller class:
#PostMapping(path = "/listbooks")
public String getBook(#ModelAttribute BookConfig bookConfig, Model model)
throws IOException {
model.addAttribute("book", bookConfig);
return "list";
}
#GetMapping(path = "/listbooks")
public String showAllBooks(Model model) throws IOException {
model.addAttribute("books", bookService.getBookConfigList());
return "list";
}
HTML file:
<div class="table-responsive" th:if="${not #lists.isEmpty(books)}">
<table class="table table-hover" style="height:50px;">
<thead class="thead-inverse">
<tr>
<th>Name</th>
<th>View</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tr th:each="book : ${books}">
<td th:text="${book.name}">Book Name</td>
<td>View</td>
<td>Update</td>
<td>Delete</td>
</tr>
</table>
</div>
This is what I am trying to do on the HTML file:
<form th:if="${book != null}" th:object="${book}" th:action="#{/book/}"
method="post">
<div class="panel-heading">
<h4 class="panel-title"
">Edit
Book Configuration</h4>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-3 form-group"
>
<label>Book name</label>
<input type="text" class="form-control" th:field="*{name}"/>
</div>
...
I have solved using JavaScript, Firstly, I have adjusted the getBook method below
#PostMapping("/books")
public String getBook(#RequestBody String bookName) throws IOException {
return "list";
}
and then I have add these two JS functions:
$(document).ready(function () {
$(".view").click(function () {
var $row = $(this).closest("tr"); // Find the row
var $text = $row.find(".bookname").text(); // get the text on the view link using its the class name
$.post("http://localhost:8081/books",
{
bookName: $text
},
function (data, status) {
assignDataToTable(data);
});
});
});
function assignDataToTable(data) {
alert("hey" + data);
document.getElementById("booknameinput").value = data;
}

Thymeleaf: Update Table on Form Submit

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.

Passing thymeleaf information to a hidden form

I am trying to pass the information from a thymeleaf list and trying to add it to database.
I am getting data from the tmdb and it will be changing so i display the information obtain to the endpoint "/LatestMovies" this information is not saved in the db and ether should it be. so i am trying to add a save button for the custumer to add the movie listed.(its simple it just haves movieid and moviename)
Showing the movies listed i have no problem and it works fine but where i get error is when i add a hidden form. The current code i have is this:
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form action="#" th:action="#{/LatestMovies}" th:object="${addMovies}" method="post">
<p><input type="hidden" th:field="*{id}" th:attr="value = ${LatestMovies.id}" /></p>
<p><input type="hidden" th:field="*{movieName}" th:attr="value = ${LatestMovies.movieName}" /></p>
<p><input type="submit" value="Submit" /></p>
</form>
</td>
</tr>
</table>
#Controller
public class LatestMoviesController {
#Autowired
private LatestMoviesDao listOfMovies;
#Autowired
private savedMoviesDao movieRepo;
#GetMapping("/LatestMovies")
public String prueba(Model model) {
TmdbMovies movies = new TmdbApi("22914f477aaa3e7f86c6f5434df8d1eb").getMovies();
ResultsPage<MovieDb> movie = movies.getPopularMovies("en", 1);
for(int i=0; i <= 19; i++){
int movieId = movie.getResults().get(i).getId();
String movieName = movie.getResults().get(i).toString();
listOfMovies.save(new LatestMovies(movieId, movieName));
}
model.addAttribute("latestMovies", listOfMovies.findAll());
return "index";
}
#PostMapping("/LatestMovies")
public String save(#ModelAttribute("addMovies") Model model, SavedMovies addMovies) {
movieRepo.save(addMovies);
return "index";
}
}
Thx in advance
First, let's change your form. You don't need to add a new object to it, since you are already iterating through a list of them. That way, you will also avoid having to add the value for each field manually using th:attr. What we are gonna do, is send the required params separately and then build our movie object with them.
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form th:action="#{/LatestMovies}" method="post">
<p><input type="hidden" th:value="${LatestMovies.id}" name="id"/></p>
<p><input type="hidden" th:value="${LatestMovies.movieName}" name="name"/></p>
<p><input type="submit" value="Submit"/></p>
</form>
</td>
</tr>
</table>
</div>
Now, on your controller, do the following modifications.
#PostMapping("/LatestMovies")
public String save(#RequestParam("id") Integer id, #RequesParam("name") String name) {
SavedMovies movie = new SavedMovies();
movie.setId(id);
movie.setName(name);
movieRepo.save(movie);
return "index";
}
These changes should do the trick.

HTTP Status 400 - Required String parameter 'userid' is not present

i tried this code for login page and am getting the above error , am new to spring please help me.
#Controller
#RequestMapping("/login")
public class LoginController {
#Autowired
private LoginService loginser;
#RequestMapping("/loginadmin")
public String loginAdmin() {
return "loginadmin";
}
#RequestMapping("/loginemployee")
public String loginEmployee() {
return "loginemployee";
}
#RequestMapping("/adminvalidate")
public #ResponseBody String validateAdmin(#RequestParam(value="userid") String userid, #RequestParam(value="password") String password) {
String result = loginser.validate(userid, password);
if (result.equals("pass")) {
return "redirect:/admin/view";
}
return "error";
}
}
ui
<div id="wrapper">
<div id="header">
<h1>Admin Login</h1>
</div>
</div>
<div id="container">
<div id="content">
<form:form action="adminvalidate"
method="POST">
<table>
<tbody>
<tr>
<td><label>User-Id : </label></td>
<td><input type="text" path="emp_Id" placeholder="User Id" id="userid"/></td>
</tr>
<tr>
<td><label>Password : </label></td>
<td><input type="password" path="emp_firstname" placeholder="Password" id="password"/></td>
</tr>
<tr>
<td><label></label></td>
<td><input type="submit" value="login"></td>
</tr>
</tbody>
</table>
<input type="button" value="back" onclick="window.location.href='/';return false">
</form:form>
</div>
</div>
i need to write code for login page that to check the credentials and am getting 400 error
Since you put an image instead of code ,I can not see the entire code of yours,
According to your question,the reason is the userid parameter is not passed to your controller method,check if you have set the name of user id input element as below:
<input type='text' name='userid' path='emp_id'>
Another possible way to avoid this issue is set the required=false in your controller method:
public #ResponseBOdy String validateAdmin(#RequestParam(value="userid",required=false)){
}
400 error comes when the server was unable to process the request sent by the client due to invalid syntax. check your URL syntax and you didn't give the method name in controller Like POST

Parameter not received inside controller

I try to send a parameter applicationNo wrapped inside my form tag.The data inside input generated via javascript snippet. I need to pass this data to my controller, but it always throw null pointer exception, I am not able to figure it out what is the problem.
So kindly suggest me the best way to achieve. I also attached required source code and snapshot.
I want to send the data highlighted in red area in below screenshot.
JSP CODE:
<form action="${baseURL}view_grp_conn_applications" id="grpCreationForm" method="post" commandName="command" >
<div class="col-sm-12">
<table id="addAppTable" class="table table-responsive table-bordered table-striped text-center" id="newField">
<thead>
<tr>
<th>#</th>
<th>Application No.</th>
<th>Name</th>
<th>Mobile No.</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
<c:set var="i" value="0"></c:set>
<tr>
<td valign="center"><input name="workOrderPostSps[${i}]" id="workOrderPostSps[${i}]" type="checkbox" value="${wo.woPostIdEnc}" onclick="highlightrow(this);" /></td>
<td align="center"><b><input onkeypress="show_list('${i}');" id="appNo1${i}" name="applicationNo" class="form-control start" autocomplete="off" data-validate="required" required="true" placeholder="press key on keyboard"/></b></td>
<td align="left"><span id="appName1${i}"></span></td>
<td align="left"><span id="appContact${i}"></span></td>
<td align="left"><span id="email1${i}"></span></td>
</tbody>
</table>
</div>
<div class="col-md-12">
<input type="submit" class="btn btn-turquoise pull-right no-margin " name="saveBtn" id="saveBtn" value="Next >>" onclick="myfunction()">
</div>
</form>
JAVA CODE:
This method open the JSP from where I wish to send the applicationNo
#RequestMapping(value = "/create_group_connection")
public ModelAndView createConnection(Model model) {
ModelAndView mav = new ModelAndView("user/create_group_connection");
Application application = new Application();
mav.addObject("command", application);
return mav;
}
This method will open the jsp where i need to extract that applicationNo
#RequestMapping(value = "/view_grp_conn_applications", method = RequestMethod.POST)
public ModelAndView viewApplications(#ModelAttribute("command")Application application,HttpServletRequest request, HttpSession session) {
ModelAndView mav = new ModelAndView("user/grp_conn_applications");
try {
System.out.println("inside view group applications");
String[] applicationNo = request.getParameterValues("applicationNo");
System.out.println("inside " + applicationNo[0]);
// for (int i = 0; application.length > 0; i++) {
// System.out.println("application number is" + application[i]);
// }
} catch (Exception e) {
System.out.println("Exception occured");
e.printStackTrace();
}
return mav;
}
<td><b><input onkeypress="show_list('${i}');" id="appNo1${i}" name="applicationNo" class="form-control start" autocomplete="off" data-validate="required" required="true" placeholder="press key on keyboard"/></b></td>
you just use the below instead of above
<input type='hidden' id="applicationNo" name="applicationNo" /></b></td>
you just set the application number using Javascript through id of hidden field on any event like onBlur, onKeyPress,Your Controller code is Correct

Categories

Resources