Spring MVC navigation - java

I want to create simple navigation with Spring MVC, so far I got this:
#Controller
#RequestMapping("/secure")
public class NavigationController {
#ModelAttribute("myPath/operation")
public OperationForm getOperationForm() {
return new OperationForm();
}
#RequestMapping("/myPath/operation")
public String processOperationPage() {
//Some logic goes here
return "myPath/operation";
}
#ModelAttribute("myPath/configuration")
public ConfigurationForm getConfigurationForm() {
return new ConfigurationForm();
}
#RequestMapping("/myPath/configuration")
public String processConfigurationPage(Map model) {
return "myPath/configuration";
}
}
And in my JSP page:
Configuration
Operation
Is this solution for navigating through pages efficient? Could you suggest me some other ways to make the navigation? I am sure there is but I can't find anything on the internet.

For the jsp's this is a bit neater imho :
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<c:url var="config" value="/secure/myPath/configuration.htm"/>
Configuration

Related

HDIV + Spring MVC - getting always Unauthorized Access error HDIV_PARAMETER_DOES_NOT_EXIST

I am using HDIV with Spring MVC based on Spring Java Configuration which I derived from their showcase implementation. The configuration get loaded but when I try to access protected URLs i.e. "/messages/message" I get always Unauthorized Access error HDIV_PARAMETER_DOES_NOT_EXIST. It works when I change the config to exclude the URL from HDIV processing but this of course is not an option
Anybody an idea what I missed?
hdiv reference documentation
hdiv example showcase configuration code
Logfile error statement
10:04:17.304 [http-nio-8080-exec-22] INFO org.hdiv.logs.Logger - HDIV_PARAMETER_DOES_NOT_EXIST;/spring-security-example/messages/message;_HDIV_STATE_;;;127.0.0.1;127.0.0.1;megloff;
Java Configuration
#Configuration
#EnableHdivWebSecurity
public class HdivSecurityConfig extends HdivWebSecurityConfigurerAdapter {
#Override
public void configure(SecurityConfigBuilder builder) {
}
#Override
public void addExclusions(ExclusionRegistry registry) {
registry.addUrlExclusions("/").method("GET");
registry.addUrlExclusions("/login");
registry.addUrlExclusions("/logout");
registry.addUrlExclusions("/static/.*");
registry.addParamExclusions("_csrf");
// registry.addUrlExclusions("/messages/.*"); <-- would allow access, but not an option
}
#Override
public void configureEditableValidation(ValidationConfigurer validationConfigurer) {
validationConfigurer.addValidation("/messages/.*");
validationConfigurer.addValidation("/addUser");
}
}
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {
"ch.megloff.spring.security.example.mvc.controller",
"ch.megloff.spring.security.example.mvc.action",
"ch.megloff.spring.security.example.repository",
"ch.megloff.spring.security.example.listener",
"ch.megloff.spring.security.example.service"})
public class SpringMVCConfiguration extends WebMvcConfigurerAdapter {
#Autowired
#Qualifier("hdivEditableValidator")
private Validator hdivEditableValidator;
#Override
public Validator getValidator() {
return hdivEditableValidator;
}
...
}
public class SpringWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringMVCConfiguration.class, SpringHibernateConfig.class, SpringSecurityConfiguration.class, SpringSecurityJDBCConfiguration.class, SpringWebFlowConfig.class, HdivSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringMVCConfiguration.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
public void onStartup(ServletContext container) throws ServletException {
super.onStartup(container);
container.addFilter("ValidatorFilter", ValidatorFilter.class).addMappingForUrlPatterns(
EnumSet.of(DispatcherType.REQUEST), false, "/*");
container.addListener(new InitListener());
}
}
I found a solution. HDIV requires that all links get enriched with a "_HDIV_STATE_" parameter in its URL. in order to achieve that you have to use taglib from HDIV and not the original JSTL taglib.
Please refer also to the reference documentation of HDIV regarding JSTL
e.g. in your POM
<dependency>
<groupId>org.hdiv</groupId>
<artifactId>hdiv-jstl-taglibs-1.2</artifactId>
<version>${org.hdiv-version}</version>
</dependency>
e.g. in your JSP (note the 'www.hdiv.org' in the taglib statement)
<%# taglib prefix="c" uri="http://www.hdiv.org/jsp/jstl/core"%>
<c:url value="/messages/messages" var="url" />
<li>Messages</li>
So you need to render the URL via th <c:url> utility tag. This renders then the URL with the required HDIV parameter i.e.
localhost:8080/spring-security-example/messages/message?_HDIV_STATE_=26-0-830046F08D66980D1B35F52F2D6677E0
another option may be is to use the utility class from HDIV
see class LinkUrlProcessor at the github repository of hdiv
LinkUrlProcessor urlProcessor = HDIVUtil.getLinkUrlProcessor(servletContext);
String processUrl = urlProcessor.processUrl(request, "/messages/messages");

How private fields accessible on jsp page in struts 2.x?

Hello every one I am working with struts 2.x and very new for this framework . I follow list of tutorials and steps and my application working properly but there is one thing which is not clear to me Like when I declare one private field in my action class and using struts tag that private field is accessible to the jsp page . So how it happen that is not understandable for me:
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" namespace="/home" extends="struts-default">
<action name="message" class="com.csc.action.MessageAction">
<result name="hello">/hello.jsp</result>
<result name="bye">/bye.jsp</result>
</action>
<action name="add" class="com.csc.action.Mathaction">
<result name="success">/hello.jsp</result>
<result name="fail">/bye.jsp</result>
</action>
</package>
</struts>
MessageAction.java
package com.csc.action;
import com.csc.service.BussniessServ;
public class MessageAction {
private String result;
private String value;
private String fstvalue;
private String scndvalue;
public String getFstvalue() {
return fstvalue;
}
public void setFstvalue(String fstvalue) {
this.fstvalue = fstvalue;
}
public String getScndvalue() {
return scndvalue;
}
public void setScndvalue(String scndvalue) {
this.scndvalue = scndvalue;
}
// method which get value from input parameter
public String getValue() {
return value;
}
// method which show the value of input parameter
public void setValue(String value) {
this.value = value;
}
// method which run as default and execute
public String execute() {
BussniessServ serv = new BussniessServ();
setMessag(serv.Addition(fstvalue, scndvalue));
return "hello";
}
// method to show message on jsp page
public String getResult() {
return result;
}
// method for save message
public void setResult(String result) {
this.result = result;
}
}
Result.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!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>
<s:property value="result"/>
</body>
</html>
Struts uses reflection to find a method that returns that variable. For example, if you have a variable called result then Struts looks for a method called getResult() and calls it to obtain a value.
Also, if you want properties to be accessible in the JSP you have to make sure that you name these methods correctly. A property called "abc" would match the method getAbc() (unless it is a boolean, in which case would match the method isAbc() instead).
OGNL does not actually require accessors to be present, although this varies by version–earlier versions (~S2.0) required accessor methods. Later versions (~S2.1+) "helpfully" removed this restriction.
Public properties with private getters also works, although it's obviously pathological.
IMO it was a step backwards for data encapsulation.
It may be configurable in later/current versions of OGNL, I'm not sure.

Missing Resource in EL implementation: ???propertyNotReadable?

I'm using JSF2.1. I don't have any jars in my WEF-INF folder. My classpath is only referencing JSF2.1 and Java EE. I'm using JDK1.7.
I'm getting "Missing Resource in EL implementation: ???propertyNotReadable???" when trying to test out processing GET parameters using f:event type="preRenderComponent". Right now I'm just trying to do a simple test. My page has a lot on it, so I'm only showing the important parts here. The part I added is the <f:metadata> block. When I remove that block, the error goes away.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<f:metadata>
<f:viewParam name="team" value="#{appBean.team}" />
<f:event type="preRenderComponent" listener="#{appBean.init}" />
</f:metadata>
In my backing bean, I have:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class AppBean implements Serializable{
private static final long serialVersionUID = 1778234L;
private Long team;
public AppBean(){
}
public void init(){
if (team != null) System.out.println(team);
else System.out.println("team undefined");
}
public void setTeam(Long team){
this.team = team;
}
}
And the way I'm testing this out is to go to my url and add ?team=123 to the end. I'm expecting System.out to print 123. Any ideas on how to fix this error?
I figuered it out... I forgot to include:
public Long getTeam(){
return team;
}

how to move a variable's value from jsf's bean page (i.e, bean.java) to another java class?

how to move a variable's value from jsf's bean page (i.e, bean.java) to another java class? when i tried to do that, the value assinged to the variable in the second java class is NULL.,
I have used primefaces UI framework(something like jsf) and assigned every fields value in to a bean class. the value assigned to every variable in bean class is proper. but when i tried to move those values to another .java file. The scope of the variable dies, and the value is NULL. Check out my codings..
LOGIN.XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head></h:head>
<h:body>
<p:panel header="Login" style="">
<h:form>
<h:panelGrid columns="2" cellpadding="2">
<h:outputText value="Username"></h:outputText>
<p:inputText id="userName" value="#{loginBean.userName}"></p:inputText>
<h:outputText value="Password"></h:outputText>
<p:password id="password" value="#{loginBean.password}"></p:password>
<p:commandButton value="Sign in" ajax="false" actionListener="#{loginBean.forward}"></p:commandButton>
</h:panelGrid>
</h:form>
</p:panel>
</h:body>
</html>
loginBean.java
package bean;
import receive.*;
public class loginBean {
public String userName;
public String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void forward()
{
System.out.println(getUserName());
receiveclass r=new receiveclass();
r.dbc();
}
}
receiveclass.java
package receive;
import bean.loginBean;
public class receiveclass {
loginBean lb=new loginBean();
public void dbc()
{
String s= lb.getUserName();
String p=lb.getPassword();
System.out.println(s);
System.out.println(p);
//System.out.println("hi");
}
}
output is,
if i give as admin, admin in text fields
i am receiving as
admin
null
null
You're manually creating the beans instead of letting JSF manage the beans. Manually created beans won't be used by JSF at all. You need to let JSF auto-create and manage those beans. You can access other JSF managed beans by injecting it as #ManagedProperty:
In your particular case, the following should work:
#ManagedBean
#RequestScoped
public class LoginBean {
private String userName;
private String password;
#ManagedProperty
private ReceiveClass receiveClass;
public void forward() {
receiveClass.dbc(this);
}
// Add/generate getters and setters.
}
with
#ManagedBean
#SessionScoped
public class ReceiveClass {
public void dbc(LoginBean loginBean) {
System.out.println(loginBean.getUserName());
}
}
(Note that I fixed the code to adhere the Java Naming Conventions properly. Class names ought to start with uppercase)
See also:
Communication in JSF 2.0 - Injecting managed beans in each other
in your receiveclass you create a completely new instance of loginBean. Values can only be null.
I do it this way: I created a Java class in which I have static functions like this one
public class JSFHelper
{
public static Object getMyObject(String objname, Class<?> classname )
{
FacesContext fCtx = FacesContext.getCurrentInstance();
ELContext elCtx = fCtx.getELContext();
ExpressionFactory ef = fCtx.getApplication().getExpressionFactory();
ValueExpression ve =
ef.createValueExpression(elCtx, "#{" + objname+ "}",classname);
return (Object) ve.getValue(elCtx);
}
}
If I need a value from another Bean it would look like this in your receiveclass:
public class receiveclass
{
public void dbc()
{
loginBean lb=(loginBean)JSFHelper.getMyObject("loginBean",loginBean.class);
String s= lb.getUserName();
String p=lb.getPassword();
System.out.println(s);
System.out.println(p);
//System.out.println("hi");
}
}

Using jsp:setProperty to set one bean in other bean

I would like to know how to use jsp:setProperty in the following scenario. Here is a simple example of two java classes.
public class MyExample {
private MyName myNameExample = new MyName();
public MyExample() {}
public MyName getMyNameExample() {
return myNameExample;
}
public void setMyNameExample(MyName setTo) {
myNameExample = setTo;
}
}
public class MyName {
private String firstName;
public MyName() {}
public String getFirstName() {
return firstName;
}
public String setFirstName(String setTo) {
firstName = setTo;
}
}
I was trying to use something like:
<jsp:useBean id="example" class="MyExample" scope="page"/>
<jsp:setProperty name="example" property="????" value="aFirstName"/>
The important part here is that I want to reference the MyName object from within MyExample. Therefore, creating a bean to directly access MyName will not help me. So I am not looking for this answer:
<jsp:useBean id="name" class="MyName" scope="page"/>
<jsp:setProperty name="name" property="firstName" value="aFirstName"/>
You could just create both beans and set one in other by ${}.
<jsp:useBean id="myName" class="MyName" scope="page" />
<jsp:setProperty name="myName" property="firstName" value="aFirstName" />
<jsp:useBean id="myExample" class="MyExample" scope="page" />
<jsp:setProperty name="myExample" property="myExampleName" value="${myName}" />
Unrelated to the concrete problem, I'd suggest to invest time in learning servlets and MVC. The above is a pretty old fashioned and tight-coupled way of controlling the models in the view.
Note that using packageless classes may not work in all circumstances (since they are invisible for normal classes inside a package). Only in certain Apache Tomcat configurations it will work. Rather put your classes inside a package in order to be not dependent of that.

Categories