I want to have references on my welcomePage.jsp page to other jsp pages - loginPage.jsp and registerPage.jsp. I tried to use simple like this:
<head>
<title>${title}</title>
</head>
<body>
<jsp:include page="header.jsp"/>
<jsp:include page="_menu.jsp" />
<h1>Welcome to the page!</h1>
Register
<p>or</p>
Log In
<p>if you already have an account</p>
<jsp:include page="footer.jsp"/>
</body>
</html>
But I keep getting HTTP Status 404 The requested resource is not available.
I also tried but as a result the contents of the pages I was referencing too just apperead on this welcomePage. Although I need them to be accessible through links only.
All the mentioned files are located in WEB-INF/pages.
This is my first project with Spring MVC so any help is welcomed.
Suppose, in your configuration, you have set the location of views e.g. /WEB-INF/view/ where you put all of your .jsp files - loginpage.jsp, registerPage.jsp etc. Now, you can simply access the location of view i.e. /WEB-INF/view/ via pageContext.servletContext.contextPath.
//For example
href="${pageContext.servletContext.contextPath}/loginpage"
I suggest you to go to a controller first, than call a ModelAndView in this controller. This also keeps the relations clear between the JSP files.
To apply this your controller class should be like this:
#Controller
public class LoginPageController {
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView printLoginPage() {
ModelAndView modelAndView = new ModelAndView("loginPage");
return modelAndView;
}
}
You can also pass parameters from a JSP page to another by going through a controller method.
Related
I am trying to use Micronaut Views annotation to send back few params and set local storage then redirect. I used script tag inside autoredirect.html template which should set local storage and then window.location.replace to redirect. Please help me with following 2 concerns.
Request hits the post and get methods, but corresponding view is not sent back, instead after computing everything I get 404 Not Found.
GET request -> http://localhost:8081/someapp/api/sso
Is this right way to set localstorage and redirect to another relative path?
POST request with necessary params to compute roles and JWT -> http://localhost:8081/someapp/api/sso/saml
added below additional entry in build.gradle
compile "io.micronaut:micronaut-views"
runtime "org.thymeleaf:thymeleaf:3.0.11.RELEASE"
view location
My controller
#Controller('/someapp/api/sso')
#Slf4j
#CompileStatic
class SomeController {
#View("home")
#Get("/")
HttpResponse index() {
return HttpResponse.ok(CollectionUtils.mapOf("loggedIn", true, "username", "raka"))
}
#View("autoredirect")
#Post('/saml')
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.TEXT_HTML)
HttpResponse<String> samlLogin(#Nullable #Body LinkedHashMap payload) {
//... some operations, computing user roles & jwt
if (payload != null) {
String results = handler.call(payload)
return HttpResponse.ok(results).
header("JWT", jwt.toString())
} else {
return HttpResponse.badRequest()
}
}
}
home.html
<!DOCTYPE html>
<html lang="en" th:replace="~{layoutFile :: layout(~{::title}, ~{::section})}" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Home</title>
</head>
<body>
<section>
<h1 th:if="${loggedIn}">username: <span th:text="${username}"></span></h1>
<h1 th:unless="${loggedIn}">You are not logged in</h1>
</section>
</body>
</html>
autoredirect.html
<!DOCTYPE html>
<html>
<head>
<title>Cassini</title>
</head>
<script type="text/javascript">
localStorage.setItem('username', '${username}');
localStorage.setItem('perm', '${perm}');
localStorage.setItem('userDetails', '${userDetails}')
window.location.replace('${redirectURL}');
</script>
<body>
</body>
</html>
Update
I tried explicitly adding below lines in my application.yml, but still no luck. Gives 13:10:56.476 [pool-2-thread-3] DEBUG io.micronaut.views.ViewsFilter - view autoredirect not found message instead.
micronaut.views.enabled: true
micronaut.views.folder: views
micronaut.router.static-resources.*.enabled: true
micronaut.router.static-resources.*.paths: classpath:public
You should just have an endpoint to return the users information. Then the client side can call it and do whatever needs to happen. Trying to put things in local storage then redirect in an HTML file seems like a hack to me
For your 1st question:
Request hits the post and get methods, but corresponding view is not
sent back, instead after computing everything I get 404 Not Found.
I think you are missing the starting forward slash / while trying to specific view path in #View annotation.
Following basic code block renders the index.html located inside resources folder views/home/index.html
#Controller("/home")
class HomeController {
#Get("/")
#View("/home/index")
public Map index() {
return [:]
}
}
For you 2nd question:
Is this right way to set localstorage and redirect to another relative
path?
I am not sure completely on your requirement but if you trying to have session management and security in micronaut, you can look for
Micronaut Session
Micronaut Security
#Secured([RoleConstant.SUPER_ADMIN, RoleConstant.ADMIN])
#Controller("/home")
class HomeController {
#Get("/")
#View("/home/index")
public Map index(#Nullable Principal principal) {
return [username: principal.name]
}
}
Refer documentation of Mirconaut, also make sure you upgrade to latest 1.1.1 version as few bugs are fixed in latest release for thymeleaf & cookie path used in security & session.
I have a simple Maven servlet/jsp application that I deploy to a local Tomcat 9 (via Eclipse). JSP pages are stored under root folder (src\main\webapp\*.jsp) which when Maven installs a WAR, they go under the root folder (MyAppContext\*.jsp along side MyAppContext\META-INF\ and MyAppContext\WEB-INF\).
The servlets' URL patterns are annotated for each servlet, e.g. /doactionone, /doactiontwo, etc. Most servlets perform the dispatching to various JSP pages, but I do have a direct anchor link on one.
I wanted to move these JSP pages into their own respective directory, so I moved them to src\main\webapp\jsp\*.jsp folder, and when the Maven install is run, they get placed under MyAppContext\jsp\.
The only entry I have in web.xml is a welcome file that after relocating the JSP files, it points to jsp\doactionone.jsp which loads that corresponding JSP page. This page contains a simple form:
<form action="doactionone" method="post">
...
<a href="jsp/doactiontwo.jsp">
<input type="submit" />...
</form>
The submission on this page actually calls the right servlet (the one defined with doactionone URL pattern). I also have a link that takes the user to the second page (doactiontwo.jsp).
However, when I navigate to that second page via this link, which has another simple form (see below), and perform the submission (post), I see in browser's debugging that the URL request is http://localhost:8080/MyAppContext/jsp/doactiontwo which, for obvious reason, would return a 404 status (and get no hit to this servlet's doPost() (or doGet()) methods either).
<form action="doactiontwo" method="post">
...
<input type="submit" />...
</form>
If I try to modify the second servlet's URL pattern to /jsp/doactiontwo, I can hit the servlet, but when doactiontwo actually dispatches/forwards the request after processing to the first servlet (doactionone) with:
RequestDispatcher rd = request.getRequestDispatcher("doactionone.jsp");
rd.forward(request, response);
when it gets loaded, when hover over the URL on the first page that initially was pointing to the second JSP page (<a href="jsp/doactiontwo.jsp">), now actually points to:
jsp/jsp/doactiontwo.jsp
The funny part is that the source code of doactionone.jsp still shows it as jsp/doactiontwo.jsp, but hovering over it shows http://localhost:8080/MyAppContext/jsp/jsp/doactiontwo, and when clicked, it obviously results in 404 status.
Can somebody explain why, first of all, the submission on the second JSP page requires the servlet to have a pattern of /jsp/doactiontwo to work rather than /doactiontwo? And is there a way around to avoid appending /jsp to the URL pattern?
And second, why when the second servlet processes the request and dispatches/forwards it to the first page, the URL now contains two jsp/'s?
You need to change your design to allow the controllers, a.k.a. Servlets, to drive your application. In this particular case, use the URL Pattern of second Servlet (doactiontwo) in place of you link:
#WebServlet(urlPatterns = { "doactiontwo" }
public class DoActionTwoServlet extends HttpServlet { /* ... */ }
<form action="doactionone" method="post">
...
<a href="doactiontwo"> <!-- This should match your second servlet's URL pattern -->
<input type="submit" />...
</form>
Now, since the default method when anchor link is invoked is GET, you need to overwrite DoActionTwoServlet's doGet() method, and forward those requests to an actual doactiontwo.jsp:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("jsp/doactiontwo.jsp");
rd.forward(request, response);
}
How can I include(load) more than one jsp files in spring mvc conroller class?
eg:
#RequestMapping("/")
public void welcome() {
include("file1.jsp");
include("file2.jsp");
include("file3.jsp");
}
At framework level, No you cannot do it. However, there is a hack you could try.
Create an array of name of pages you need to merge. Send it as a parameter to a dummy empty page.
The dummy page does this:
<c:forEach var="page" items="${pages}">
<c:import url="${page}"></c:import>
</c:forEach>
This will iterate all the JSP files that you wish to show as a single view.
Hope this helps. Let me know if any further help is required.
I feel like page title ought to be defined by the view rather than by a controller or model.
In Zend Framework, I could write this in the view:
$this->headTitle('Signup');
And that would change the page's window title to 'Signup'.
How can I do that in Java Spring MVC using Velocity for the view?
I thought maybe I could use something like:
$page.setTitle("Signup")
but it didn't work.
This is probably similar to this question: https://stackoverflow.com/questions/18539645/how-to-set-head-meta-tag-from-view-layer-in-spring-mvc-velocity
P.S. I'm also using Apache Tiles, so I have a Velocity file for layout.vm (which creates the HTML, HEAD, BODY, etc) and a Velocity file for signup.vm (which just creates the signup form). I want to be able to specify within signup.vm what the page's title should be.
Your velocity view is generating all of the HTML that is sent to the browser. You just add a <title> element to your page.
SignupController.java
#RequestMapping(value = "/signUp", method = RequestMethod.GET)
public ModelAndView signup() {
ModelAndView modelView = new ModelAndView("sign_up");
modelView.setObect("personName", "The Dude");
return modelView;
}
sign_up.vm
<html>
<head>
<title>Signup</title>
</head>
<body>
<p>Looks like you are signing up for something, ${personName}</p>
</body>
</html>
From a servlet, I'm forwarding the request to a JSP page which renders a FusionChart.
But I've a problem in loading the chart. The JSP file is not detecting the JavaScript file. The folder structure is:
axis
|
WebContent
|
WEB-INF
|
classes
|_ com
|_FusionCharts.js
|_MyChartJsp.jsp
|_Line.swf
And the JSP code:
<html>
<head>
<script language="text/javascript" src="/WEB-INF/classes/FusionCharts.js"></script>
</head>
<body bgcolor="#ffffff">
<div id="chartdiv" align="left">The chart will appear within
this DIV. This text will be replaced by the chart.</div>
<script type="text/javascript">
var foo = //value fetched from DAO
var myChart = new FusionCharts("/WEB-INF/classes/Line.swf",
"myChartId", "1000", "500");
myChart
.setDataXML("<graph caption='aCaption' xAxisName='xAxis' yAxisName='yAxis' showNames='1' decimalPrecision='0' formatNumberScale='0'>"+foo+"</graph>");
myChart.render("chartdiv");
</script>
</body>
</html>
The Servlet code to forward the request:
final RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/classes/MyChartJsp.jsp");
requestDispatcher.forward(request, response);
The request is getting forwarded to the JSP. But the chart is not getting displayed because it is unable to figure out what FusionCharts is in the line
var myChart = new FusionCharts("/WEB-INF/classes/Line.swf",
"myChartId", "1000", "500");
I tried
src="/FusionCharts.js"
src="FusionCharts.js"
but no luck.
Has it something to do with the request being forwarded??
You cannot have .js (or .swf, .jpg, etc.) files in WEB-INF - they are not publically accessible.
Move it to /js/
There is no reason to hide static resources (like scripts and css) in WEB-INF. If you insist on that, you should make a servlet that, given the name of the js/css, would read it from its location and will serve it as a response. This is what the default servlet does when you access static resources.
The flow of the page loading is as follows: the browser sends a request to the servlet; the servlet forwards internally to the JSP, and the JSP is rendered as a response; then the browser parses the <script> tag and fires another request to the script. If the script is not accessible via URL, it's not loaded.
Then, to make the script url fixed to the servlet context root, use
src="<c:url value="/js/script.js" />"
This will work regardless of what is the current url
Not the cause of your problem, but also note that your <script> element is incorrect. It should be <script type="text/javascript"....
(I tried to post this as a comment, but for some reason it wouldn't let me.)
I was facing same issue. In my case when I calling the myFile.jsp directly its reading the myFile.js;
But when calling through login-> myFile.jsp, its not reading the myFile.js;
After analyzing the path through the Developer tools :=> console, I found that its inserting the uri, so final path was incorrect.
Final Solution:
I'd used the absolute path for all .js and .css. Now its called from everywhere.
My Project Structure is:
In my servlet-context.xml
i) <context:component-scan base-package="com.SBP.SHWeb" />
ii) <resources mapping="/resources/**" location="/resources/" />
My old path for including .js was: /resources/MyJs/myfile.js ===> Its not get called sometimes.
My Absolute path, which get called from all places is like this:
/SHweb/resources/MyJs/myfile.js ==> Its get called from everywhere.
Hope it help you.