I am learning Spring Boot now and I wrote a small application. The application has this controller:
#Controller
#RequestMapping("/")
public class ApplicationController {
#RequestMapping(value="/account", method = RequestMethod.POST)
public String getAccountVo(ModelMap model) {
AccountVO vo = new AccountVO();
vo.setAccountNo("0102356");
vo.setAccountHolderName("Dinesh");
model.addAttribute("acc", vo);
return "account";
}
}
... and the page (view) is:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Account Details</title>
</head>
<body>
<form>
Account number <input type="text" name="acctNo" value="${acc.getAccountNo()}"><br>
Account Holder Name <input type="text" name="name" value="${acc.getAccountHolderName()}"><br>
</form>
</body>
</html>
When I ran the application, I got HTTP Status 405 with the message Request method 'GET' not supported. But when I changed the method in the #RequestMapping annotation to method=RequestMethod.GET I got my expected page.
Why did this happen?
#RequestMapping(value="/account", method = RequestMethod.POST)
This means that getAccountVo method handler is responsible for POST requests on the /account endpoint. So when you fire a GET request to /account endpoint, since you haven't define any method handler to process that, Spring complains with 405 Method Not Supported.
If your intent is to have a form processing workflow, a typical approach is define two method handlers on the /account endpoint: One for displaying the form and other for processing the submitted form, kinda like this:
#Controller
#RequestMapping("/")
public class ApplicationController {
#RequestMapping(value="/account", method = RequestMethod.GET)
public String displayAccountForm(...) {
// do whatever suits your requirements
return "account";
}
#RequestMapping(value="/account", method = RequestMethod.POST)
public String handleSubmittedForm(...) {
// do whatever suits your requirements
return "successPage";
}
}
Related
I've created a project with a Spring Initilizr. I'm trying to parse a string into a "code.html" file and recover it with a #GetMapping. Here's the file:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Code</title>
</head>
<body>
<pre>
<p th:text="${code}">
</pre>
</body>
</html>
And here's the method:
#GetMapping("/code")
public ModelAndView getHTML(HttpServletResponse response) {
response.addHeader("Content-Type", "text/html");
ModelAndView model = new ModelAndView();
model.addObject("code", code.getCode());
model.setViewName("code.html");
return model;
}
(I have a seperate class for the code so code.getCode() just returns a string.)
Unfortunately, http://localhost:8080/code returns an empty screen. What am I doing wrong? Maybe there's an easier way to achieve the task?
i work with springboot and thymeleaft
maybe you need send only the view in the code
like this
#GetMapping("/code")
public ModelAndView getHTML(HttpServletResponse response,Model model) {
model.addAtributte("key", "code");
return new ModelAndView ("templates/code");
}
the model is shipped with the view
in the html try this
<p th:text="${key}">
or you can try the <th:block>
check thymeleaf documentation
i am trying to display a string in springboot web page but it,s not working correctly !
controller
#Controller
public controller {
#RequestMapping("/")
public ModelAndView get(){
ModelAndView model = new ModelAndView("index.html");
String name = "World";
model.addObject("name",name);
return model;
}
}
index.html
<html>
<body>
<h1>Hello <span th:text="${name}"></span></h1>
</body>
</html>
it works like this
#Controller
public controller {
#RequestMapping("/")
public ModelAndView get(){
ModelAndView model = new ModelAndView("index");
String name = "World";
model.addObject("name",name);
return model;
}
}
Test by removing the .html
Also add th="http://www.thymeleaf.org" like below.
<html xmlns:th="http://www.thymeleaf.org">
<h1>Hello th:text="${name}"></h1>
Try removing the span or correctly add the content inside the span.
Thank you
You don't need to change anything in java classes and even you don't need to remove the span in the HTML file. Check with the namespace in the HTML. The following is working without any issue with spring-boot <2.2.9.RELEASE> and using the thymeleaf template engine.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class TestController {
#RequestMapping("/")
public ModelAndView get(){
ModelAndView model = new ModelAndView("index.html");
String name = "World";
model.addObject("name",name);
return model;
}
}
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8" />
<title>test</title>
</head>
<body>
<h1>
Hello <span th:text="${name}"></span>
</h1>
</body>
</html>
I am using SpringBoot with Thymeleaf to build a trivial example to help me learn the two technologies.
I am basing my example on THIS GUIDE
The entity is a Greeting which has an Id and a Content.
I create the Greeting just fine, and I can list all the Greetings I've created.
I then wanted to add a delete option against each Greeting in the list page. When clicking delete, I want the object to be deleted and the list page served up again.
Alas, when I load the list page I get this error:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'greeting' available as request attribute
Controller and respository objects
#Controller
public class GreetingController {
#Autowired
GreetingRepo gr;
#RequestMapping(value="/greeting/list", method=RequestMethod.GET)
public String greetingsForm(Model model) {
model.addAttribute("greetings", gr.findAll());
return "greeting/list";
}
#RequestMapping(value="/greeting/delete", method=RequestMethod.POST)
public String deleteGreeting(#ModelAttribute("greeting") Greeting greeting) {
gr.delete(greeting);
return "redirect:/greeting/list";
}
}
#RepositoryRestResource
interface GreetingRepo extends JpaRepository<Greeting, Long> {
}
List.html page:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<div th:each="greeting : ${greetings}">
<p th:text="'id: ' + ${greeting.id}" />
<p th:text="'content: ' + ${greeting.content}" />
<form action="#" th:action="#{/greeting/delete}" th:object="${greeting}" method="post">
<input type="hidden" th:field="*{id}"/>
<input type="hidden" th:field="*{content}"/>
<input type="Submit" value="Delete"/>
</form>
</div>
Add another
Show All
</body>
</html>
Would appreciate a push in the right direction here :-)
I think you miss this line .
model.addAttribute("greeting", new Greeting());
#RequestMapping(value="/greeting/list", method=RequestMethod.GET)
public String greetingsForm(Model model) {
model.addAttribute("greeting", new Greeting());
model.addAttribute("greetings", gr.findAll());
return "greeting/list";
}
you dont have to use a form to delete the greeting you can do it very easily with this approach. hide the id of the greeting within the url. so you dont need to use a form and hidden tags. and annotate the controller method with following approach, to accept incoming id of the greeting.
replace the current form with given html code and replace the delete method in the controller as well.
<a th:href="#{/greeting/{id}/delete(id=${greeting.id})}" th:text="delete"></a>
#RequestMapping(value="/greeting/{id}/delete",method=RequestMethod.GET)
public String deleteGreeting(#PathVariable int id) {
gr.delete(id);
return "redirect:/greeting/list";
}
edit:- since you need the object to be present within the controller
you can use findOne method to fetch the object from the given id.check out the following example.
<a th:href="#{/greeting/{id}/edit(id=${greeting.id})}" th:text="edit"></a>
#RequestMapping(value="/greeting/{id}/edit",method=RequestMethod.GET)
public String Edit(#PathVariable int id){
greeting greetingob = gr.findOne(id);
return "edit";
}
Problem:
I have a simple controller which returns me a list of hardcoded locations. When i want to get my locations in my javascript file using $.get and print it in my console, i get some weird "undefined" results.
Controller:
#RestController
#RequestMapping("/locationOverview")
public class LocationOverviewController {
private LocationGuide service;
public LocationOverviewController() {
this.service = new LocationGuide("Memory");
}
#RequestMapping(method = RequestMethod.GET)
protected ModelAndView getLocations() {
ArrayList<Location> locations = new ArrayList<Location>();
locations.add(new Location(1,"KHL",new Geolocation(51,51)));
locations.add(new Location(2,"KUL",new Geolocation(51,51)));
return new ModelAndView("locationOverview", "locations", locations);
}
}
mapScript JS:
function initialize() {
$.get("locationOverview.htm", function(data){
for(var i=0; i<data.length; i++){
console.log(data[i].name);
}
})
}
JSP file:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#page import="domain.Location"%>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Leuven Speaks</title>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>
<script type="text/javascript" src="<c:url value="/js/mapScript.js" />"></script>
</head>
<body onload="initialize()">
<jsp:include page="header.jspf"/>
</body>
</html>
You should actually inspect with dev tools what that data contains. The controller method you show us looks like it is not the one mapped to locationOverview.htm. If you want to query data with ajax, return the list using the #ResponseBody annotation instead.
Data passed in a model would be available in the JSP page that you define as the view in ModelAndView.
Some learning resources:
http://www.beingjavaguys.com/2014/05/json-response-with-responsebody_31.html
https://developer.chrome.com/devtools/docs/javascript-debugging
I am using Eclipse, Spring MVC, Maven and Tomcat. This index.jsp displays exactly as show below in the web browser. It is not rendering properly.
Any idea what is wrong?
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Index</h1>
</body>
</html>
#Controller
public class HelloController {
#RequestMapping("/greeting")
public String sayHello() {
System.out.println("Greeting");
return "hello";
}
#RequestMapping("/")
public String index() {
System.out.println("Index page");
return "index";
}
}
A controller has a GET and a POST RequestMethod.However at a quick glance you need to change #RequestMapping("/greeting") to #RequestMapping(value = "/greeting") just for starters. By default your jsp file should be in /src/main/webapp/WEB-INF/views (Spring MVC Starter Project)
When you return a String - Spring MVC will look for a jsp with that .jsp. So in this example you just want to have greeting.jsp
#Controller
public class GreetingController {
/**
* GET
*/
#RequestMapping(value = "/greeting", method = RequestMethod.GET)
public String handleRequest() {
// This will be used when you GET the URL
return "greeting";
}
/**
* POST
*/
#RequestMapping(value = "/greeting", method = RequestMethod.POST)
public String processSubmit(){
// This will be used when you POST to the URL
//TODO Do something here and it will put you right back in your page
return "greeting";
}
}
Go ahead and comment if you have any other questions. Also check my account for my other example Neither BindingResult nor plain target object for bean name available as request attr
Hope this helps. Good Luck!
Just a note Spring has more RequestMethod's but GET and POST are the most used and easiest to understand.
It could be that the only thing you're missing is to
Right click on the jsp page and click RUN AS, then RUN ON SERVER.