I am trying to build an application with spring boot and java in eclipse.
What I have tried so far:
HomeController.class
#Controller
#ComponentScan(basePackages = {"project.tool.frontend"})
public class HomeController {
#GetMapping("/home")
public String home(){
System.out.println("open page");
return "home";
}
}
home.html
<!DOCTYPE HTML>
<html>
<head>
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<form action="/home" method="get">
First name: <input type="text" name="fname"><br> Last
name: <input type="text" name="lname"><br> <input
type="submit" value="Submit">
</form>
</body>
</html>
Application.class
#SpringBootApplication
public class Application{
public static void main(String agrs[])
{
SpringApplication.run(Application.class);
}
}
When I run this Application I get the "Whitelabel ErrorPage" Error. I also enabled the whitelabel errorpage in my application.properties .
And a question for unserstandig: When I use #GetMapping("/home") in my HomeController and the <form action="/home" in my html file it will be mapped through the "/home" get method right?
Thank you all.
As a static resource, your home.html should be at resources/public/home.html (or /static/). Is it there?
Your Application should tell in which package your controller is located, so it gets picked up
Does adding a ComponentScan help?
#SpringBootApplication
#ComponentScan(basePackages = { "com.acme.controllers" })
public class Application{
}
If you have not configured any view resolver, try returning "/views/home.html" instead of just "home". Change "/views/home.html" to whatever be the path of the file.
I suggest using Thymeleaf as your viewresolver.
You can place the home.html in src/main/resources folder to be recognized.
As you are using .html extension then I suggest you to use the thymeleaf as a view resolver.
Using thymeleaf HTML:
<form th:action="#{/home}" th:method="get"
...
...
//Rest of your code goes here.
</form>
Use #ComponentScan annotation:
#SpringBootApplication
#ComponentScan(basePackages = { "<full package name where controller exists>" })
public class Application{
public static void main(String agrs[]){
SpringApplication.run(Application.class);
}
}
Related
This is my pom.xml file
pom.xml enter image description here
Application.properties File
#spring.thymeleaf.enabled=true
#spring.thymeleaf.prefix=/templates/
#spring.thymeleaf.suffix=.jsp
spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.jsp
Home.jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Registration</h1>
</body>
</html>
Controller
#RestController
public class LoginController {
#GetMapping(path="/home")
public String loginPage() {
System.out.println("hello");
return "home";
}
}
Application File
#SpringBootApplication
public class SpringJspDemoApplication {
public static void main(String[] args)
{
SpringApplication.run(SpringJspDemoApplication.class, args);
}
}
Output:
enter image description here this is the output I am getting a string value instead of jsp
Tried using Thymeleaf, tried to change #RestController-> #Controller, used #ComponentScan etc but issue not getting resolved.
Tried going through the solutions given on site but none of them are working for me, also they are quite older.
Project Structure :
enter image description here tried to put home.jsp at /webapp/WEB-INF/jsp/ that is also not working.
what will be the possible solution on this, can anyone please guide on this?
Below is the code when I change #Controller to #RestController
[![
Controller File
Blockquote
]1]1
And result is still
I have checked the status under network tab which is 200 only
Please Add #ComponentScan(basePackages={"com.web"}) in your main application file
Replace #RestController to #Controller like below
#Controller
public class LoginController {
#GetMapping(path="/home")
public String loginPage() {
System.out.println("hello");
return "home";
}
}
UPDATE: Switched the annotation from #RestController to #Controller and now I simply get a 404 when trying to hit http://localhost:8080/api/v1/create_short_url. I added a System.out.println into the controller and see it being printed, so I know it's making it into the controller. I think it just can't find the template.
#Controller
#RequestMapping("/api/v1")
public class UrlShorteningController {
#GetMapping("/create_short_url")
public String newShortUrl(Model model) {
System.out.println("^^^^^^^");
model.addAttribute("longUrl",
new String());
return "new-short-url-form";
}
Request
I have the a controller which I expect to render an HTML template. Instead, it just returns the name of the controller. What am I doing wrong here?
Actual:
Expected:
Rendering of the html page
Code
Controller in src/main/java/com/example/urlshortener/api/UrlShorteningController.java:
#RestController
....
#GetMapping("/create_short_url")
public String newShortUrl(Model model) {
model.addAttribute("longUrl",
new String());
return "new-short-url-form";
}
build.gradle:
...
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
...
}
Thymeleaf Template in src/main/resources/templates/new-short-url-form.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>New Short Url</title>
</head>
<body>
<form method="POST" th:action="#{/create_short_url_thymeleaf}" th:object="${String}">
<h1>Enter a url to shorten</h1>
<input type="text" id="longUrl" th:field="*{String}"/>
</form>
</body>
</html>
Thymeleaf Template in src/resources/templates/new-short-url-form.html
The path for templates should be src/main/resources/templates/
You're using a GetMapping instead of a RequestMapping. Use RequestMapping if you expect to provide a template. GetMapping is only for a get request which explains why you're receiving the literal String and not the template.
I realized my editor wasn't picking up the view name. I have no idea, why, as the folder structure seemed correct. I tried renaming it to "some-form" and it suddenly works. Not sure if there is a length restriction on html file names top be picked up.
Try using ModelAndView
#Controller
#RequestMapping("/api/v1")
public class UrlShorteningController {
#GetMapping("/create_short_url")
public ModelAndView newShortUrl() {
ModelAndView modelAndView = new ModelAndView();
System.out.println("^^^^^^^");
modelAndView.addObject("longUrl",
new String());
modelAndView.setViewName("new-short-url-form")
return modelAndView;
}
And replace your html tag with <html lang="en" xmlns:th="http://www.thymeleaf.org">
I try put 2 request mapping since i want to point to home/home since later i will be having another controller with same name which is about/home. But i not sure why it was not working. If have only home it is working but home/home or about/home not working. The class level not working.
This the controller
package com.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.constant.server.HelperConstant;
#Controller
#RequestMapping("/home")
public class HomeController
{
#RequestMapping("/home")
public String doDisplayPage()
{
return HelperConstant.VIEW_HOME;
}
}
This the jsp
<html>
<body>
<form action="home/home">
<input type="text" name="t1"><br>
<input type="text" name = "t2"><br>
<input type ="submit">
</form>
</body>
</html>
I am hitting HTTP Status 404 -
Edited
Attached the config files
package com.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class[] {SpringConfig.class};
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/"};
}
}
This another config file
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#ComponentScan({"com.controller"})
public class SpringConfig
{
#Bean
public InternalResourceViewResolver viewResolver()
{
InternalResourceViewResolver vr = new InternalResourceViewResolver();
//vr.setPrefix("/WEB-INF/");
vr.setSuffix(".jsp");
return vr;
}
}
Attached the picture of the folder structure
there is an additional findings as well whereby i trying to look for the jsp at home/home.jsp. can i know why such behaviour? by right should just look at home.jsp. If remvoe class level anotation, then it working fine or i create a folder inside webapp home it working fine but after click submit again it looks for home/home/home.jsp
I have added a method="POST"
now problem is after restart tomact
after click submit like this
if click submit again show eror 404
this my web.xml but i removed it already since i already use java or configurtion
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>home.html</welcome-file>
<welcome-file>home.htm</welcome-file>
<welcome-file>home.jsp</welcome-file>
</welcome-file-list>
</web-app>
The problem is your action path <form action="home/home"> This is a relative path meaning it will do the following.
http://example.com/web_main/home - form action - >
http://example.com/web_main/home/home (200) - form action ->
http://example.com/web_main/home/home/home (404)
Others are suggesting /home/home but that isn't taking to account your application context path. The following would be the result.
http://example.com/web_main/home - form action - > http://example.com/home/home
Notice that the web_main is gone.
To fix your issue you need to leverage JSTL, add this to the JSP.
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<c:url value="/home/home" var="homeUrl" />`
<form action="${homeUrl}">
Add the import to the top of the JSP.
There is one issue in the url.
Have you observed the actual url?
It is displaying /home/home/home after the context but url points to /home/home.
Solution might be removing one /home from the action url in the form tag
<html>
<body>
<form **action="home"**>
<input type="text" name="t1"><br>
<input type="text" name = "t2"><br>
<input type ="submit">
</form>
</body>
</html>
or
<html>
<body>
<form action="/home/home">
<input type="text" name="t1"><br>
<input type="text" name = "t2"><br>
<input type ="submit">
</form>
</body>
</html>
What does your Spring app class look like? If you do not have one you should create one.
Instead of having the #ComponentScan below the #Configuration tag, do something like below and it should be picked up easier, also maybe change your root tag to just / for easier for reading:
#SpringBootApplication
#ComponentScan(basePackages = {"com.*"})
class MyClass {
public static void main(String[] args) {
SpringApplication.run(MyClass.class)
}
}
#Controller
#RequestMapping("/")
public class HomeController
{
#RequestMapping("/home")
public String doDisplayPage()
{
return HelperConstant.VIEW_HOME;
}
}
When using RequestMapping default request mapping method value is GET method. Html form submit uses POST method by default. So you need to add post method to this url. You can give multiple method value for same request mapping.
in 404 tab there are 3 home not 2 as you want in URL so its showing 404 .
Instead of relative path home/home in submit form give absolute /home/home
This is works
#Controller
#RequestMapping("/home")
public class HomeController {
#RequestMapping(value = "/home")
public String doDisplayPage() {
return "../home";
}
}
#Controller
#RequestMapping("/about")
public class AboutController {
#RequestMapping(value = "/home")
public String doDisplayPage() {
return "../home";
}
}
<html>
<body>
<form action="/home/home">
<input type="text" name="t1"><br>
<input type="text" name = "t2"><br>
<input type ="submit">
</form>
</body>
</html>
Also you don't need web.xml since you have describe deployment descriptor in your WebConfig and SpringConfig
If you are only trying to make your current code work, then a simple solution is to append Context Root to your form action as shown below.
<html>
<head>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
</head>
<body>
<form action="${ctx}/home/home">
<input type="text" name="t1"><br> <input type="text"
name="t2"><br> <input type="submit">
</form>
</body>
</html>
The controller loads only a String object, but not an html page. Page login.html is in directory templates. Effect is text 'login" on page. Project is in Spring Boot.
#RestController
public class Company {
#RequestMapping("login")
public String company() {
return "login";
}
}
#SpringBootApplication
public class ComJonkSpringBootMvcApplication {
public static void main(String[] args) {
SpringApplication.run(ComJonkSpringBootMvcApplication.class, args);
}
}
<!DOCTYPE HTML>
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
Name : <input name="name" type="text" /> Password : <input name="password" type="password" /> <input type="submit" />
</body>
</html>
Do not use #RestController if you plan to return a JSP.
Use #Controller instead, and read the documentation about #ResponseBody:
Annotation that indicates a method return value should be bound to the
web response body. Supported for annotated handler methods in Servlet
environments.
hi i'm working in a spring mvc project and i'm getting this error when i hit the button in my form
500 (Internal Server Error) jquery.min.js:6
x.ajaxTransport.x.support.cors.e.crossDomain.send jquery.min.js:6
x.extend.ajax AddUser:19
doAjaxPost AddUser:41
onclick
i'm trying to do a simple AJAX JQuery example that adds users to a list but i get that error when i press the add button in my form
this is my controller class:
#Controller
public class UserListController {
private List<User> userList = new ArrayList<User>();
#RequestMapping(value="AddUser",method=RequestMethod.GET)
public String showForm(){
return "AddUser";
}
#RequestMapping(value="AddUser",method=RequestMethod.POST)
public #ResponseBody String addUser(#ModelAttribute(value="user") User user, BindingResult result )
{
String returnText;
if(!result.hasErrors())
{
userList.add(user);
returnText = "User has been added to the list. Total number of users are " + userList.size();
}
else
{
returnText = "Sorry, an error has occur. User has not been added to list.";
}
return returnText;
}
#RequestMapping(value="ShowUsers")
public String showUsers(ModelMap model)
{
model.addAttribute("Users", userList);
return "ShowUsers";
}
}
and this is my AddUser.jsp page
<%# 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>Add Users using ajax</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<!-- <script src="resources/js/libs/jquery-2.0.2.min.js"></script> -->
<script type="text/javascript">
function doAjaxPost() {
// get the form values
var name = $('#name').val();
var education = $('#education').val();
$.ajax({
type: "POST",
url: "AddUser",
data: "name=" + name + "&education=" + education,
success: function(response){
// we have the response
$('#info').html(response);
$('#name').val('');
$('#education').val('');
},
error: function(e){
alert('Error: ' + e);
}
});
}
</script>
</head>
<body>
<h1>Add Users using Ajax ........</h1>
<table>
<tr><td>Enter your name : </td><td> <input type="text" id="name"><br/></td></tr>
<tr><td>Education : </td><td> <input type="text" id="education"><br/></td></tr>
<tr><td colspan="2"><input type="button" value="Add Users" onclick="doAjaxPost()"><br/></td></tr>
<tr><td colspan="2"><div id="info" style="color: green;"></div></td></tr>
</table>
Show All Users
</body>
</html>
and my MvcConfiguration class since i'm using a java based configuration and not using XML
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = { "controllers" })
public class MvcConfig extends WebMvcConfigurerAdapter
{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// JSP VIEW-RESOLVER
#Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setOrder(2);
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
return bean;
}
}
EDIT: i starter a new project just for the sake of trying to know what error i'm having, i delete spring secuirty in my application, but i still can figure out whats wrong.
1) i actually dont delete spring security i just starte a new project to try to solve my url problem
2) i change my controllers and the URL attribute in my ajax script
new RequestMapping controllers:
#RequestMapping(value="AddUser",method=RequestMethod.GET)
i deleted the "/" in the value="AddUser"
i dont have a "/" in any of my controllers if put a "/" in the controllers i have the same 500 Internal server error
This might be because of the CSRF protection which is enabled by default in Java configuration. Try in your configuration...
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// ...
.csrf().disable();
}
Let me know if this works.
EDIT**
To include CSRF token in AJAX request, if you are using JSON, you need to put it on the http header. Sample JSP example typically would be...
<html>
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>
Then in your javascript call, get this parameters and add it to XMLHttpRequest's header.
Hope this helps.
Further reading
In my case, i had to add the below dependency to my pom
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.2</version> </dependency>