Showing posts with label jsp. Show all posts
Showing posts with label jsp. Show all posts

Monday, June 11, 2018

Spring Security alters request URI

Leave a Comment

I integrated Spring Security into an existing Spring Boot project (Version: 1.5.3.RELEASE).

Before the integration, we've got our redirect informations from a request via getRequestURI in a preHandle method which extends HandlerInterceptorAdapater.

The Request URI is correctly pointing to their path (for example: /admin/login).

After the integration, the request URI is pointing to the complete path of the jsp.

In addition, we've registered a ContextUtil class to ConfigurableApplicationContext for further URI checkings. In this class, we fetch the request like this:

public HttpServletRequest getCurrentRequest() {     final ServletRequestAttributes servletRequestAttributes =      (ServletRequestAttributes)      RequestContextHolder.currentRequestAttributes();     return servletRequestAttributes.getRequest(); } 

but the URI is also to its "physical path" under /WEB-INF/

For example: GET Request is pointing to /WEB-INF/pages/admin/admin_login.jsp:

My WebSecurityConfig Class is :

@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {     @Override     protected void configure(HttpSecurity http) throws Exception     {         //jeden Aufruf akzeptieren. Authorisierung und      Authentifizierung von Spring Security wird nicht genutzt     http.authorizeRequests().antMatchers("/").permitAll(); }      @Override     public void configure(WebSecurity web) throws Exception     {     web.ignoring().antMatchers("/resources/**", "/css/**", "/js/**",      "/img/**", "resources/*", "/WEB-INF/**").and().debug(true);     } } 

Relevant applicationContext.xml parts:

<mvc:default-servlet-handler/> <mvc:annotation-driven/> <mvc:resources mapping="/resources/**" location="classpath:/WEB-INF/resources/" />  <mvc:interceptors>     <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">         <property name="paramName" value="lang" />     </bean>     <bean class="de.abc.xyu.zzz.interceptor.RedirectInterceptor" /> </mvc:interceptors>  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />     <property name="prefix" value="/WEB-INF/pages/" />     <property name="suffix" value=".jsp" />     <property name="redirectHttp10Compatible" value="false" /> </bean> 

Debug Log from Spring Security:

Request received for GET '/admin/login':

org.apache.catalina.connector.RequestFacade@70ad489

servletPath:/admin/login pathInfo:null headers: host: localhost:8081 connection: keep-alive cache-control: max-age=0 user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36 upgrade-insecure-requests: 1 accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 referer: http://localhost:8081/admin/login accept-encoding: gzip, deflate, br accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 cookie: JSESSIONID=AE07684D485DA698F1AA4DFE056D5B3A; JSESSIONID=0819B947A685FE3362F23E39CE999D3B

Security filter chain: [ WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter HeaderWriterFilter CsrfFilter
LogoutFilter RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter SessionManagementFilter
ExceptionTranslationFilter FilterSecurityInterceptor ]


[http-nio-8081-exec-1] INFO Spring Security Debugger -


Request received for GET '/WEB-INF/pages/admin/admin_login.jsp':

SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@2eac9514]

servletPath:/WEB-INF/pages/admin/admin_login.jsp pathInfo:null headers: host: localhost:8081 connection: keep-alive cache-control: max-age=0 user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36 upgrade-insecure-requests: 1 accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8 referer: http://localhost:8081/admin/login accept-encoding: gzip, deflate, br accept-language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7 cookie: JSESSIONID=AE07684D485DA698F1AA4DFE056D5B3A; JSESSIONID=0819B947A685FE3362F23E39CE999D3B

Security filter chain: [] empty (bypassed by security='none')

Why is the request pointing to its physical path under /WEB-INF/pages/login.jsp instead of its resolved path and how can we achieve it, that we get the "correct" URI?

1 Answers

Answers 1

Eventually this worked for me:

final ServletRequestAttributes servletRequestAttributes =      (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();  System.out.println("REQUEST URI: " +      servletRequestAttributes.getRequest()          .getAttribute("javax.servlet.forward.request_uri")); 

That gives the real request URI, not its "physical path" under /WEB-INF/.

Read More

Friday, June 8, 2018

How to fill a map inside a map inside a Spring form?

Leave a Comment

I have the following form

public class myForm { private String code; (getter and setter) private Map<String, Map<String, Object>> map(getter and setter) } 

I can fill the code attribute easily but i don't know how to proceed to fill the map, i don't even know if it's possible ...

This is my Spring form

<form:form commandName="myForm" action="${PostUrl}" method="POST" >   <input type="hidden" path="code" value="78967" />   <input type="submit" value="Submit"/> </form:form> 

I will know the key of the first map and i will know the key of the second map, only the value of the second map will be enter by the user.

To try to be as clear as possible here is in java what i wish to do with my form

Map<String, Map<String, Object>> map1 = new HashMap<String, map<String,  Object>>(); Map<String, Object> map2 = new HashMap<String, Object>(); map2.put("DatePickerLabel", DatePickedByTheUser) map1.put("DATEPICKER", map2) 

1 Answers

Answers 1

As there is best option you can do it by the help of inner bean .

public class myForm { private String code; (getter and setter) private Map<String,InnerBeanObject> map(getter and setter) } 

And if you are using inner bean you can do a setter injection to fill your

Map<String, Object> 

If you are using xml bean configuration

    <beans xmlns="http://www.springframework.org/schema/beans"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">          <bean id="MyFormBean" class="Myform">          <property name="code" >          <property name="map">             <map>             <entry key="Key " value-ref="innerBean"></entry>             </map>         </property>         </bean>         <bean id="innerBean" class="InnerBean">                     <property name="InnerBeanMap">                     <map>                       //get ur bean map key and value                    </map>         </bean>       </beans> 

There is similar way by java code also as you know if you are using earlier version of spring.by annotation @bean

Read More

Friday, May 25, 2018

Deploying maven project on glassfish using deploy command

Leave a Comment

I have a java ee application with maven, when i build the project then deploy the ear generated on target folder, i try to signup to the application so i have to call a locale EJB Session (UserService) , i get the following error:

javax.naming.NamingException: Lookup failed for 'java:global/myproject-ear/myproject-ejb-1.0/UserFacade!myproject.service.UserFacade' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: myproject-ear] at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518) at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455) at javax.naming.InitialContext.lookup(InitialContext.java:411) at javax.naming.InitialContext.lookup(InitialContext.java:411) at org.apache.jsp.index_jsp._jspService(index_jsp.java:79) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111) at javax.servlet.http.HttpServlet.service(HttpServlet.java:770) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:411) at   

I tried deploying using the command call asadmin --host localhost --user admin deploy --force "C:\myproject\target\myproject-ear-1.0.ear" an tried deploying from glassfish administration console, but the problem persist.

It works fine when i deploy from netbeans, knowing that the project is structured in the pom file like this:

  <modules>     <module>myproject-ear</module>     <module>myproject-ejb</module>     <module>myproject-web</module>   </modules> 

This is the jsp page :

ConfigUser configUser = (ConfigUser) c.lookup("java:global/myproject-ear/myproject-ejb-1.0/ConfigUser!myproject.service.ConfigUser"); 

0 Answers

Read More

Sunday, May 13, 2018

Field error in object 'user' on field 'userProfiles': rejected value [3];

Leave a Comment

I have downloaded a working demo which working perfectly fine while I ran it. But when I have just made my way and I am using same page and functionality with registration page and then I submitting the form I am getting error:

[Field error in object 'user' on field 'userProfiles': rejected value [3]; codes [typeMismatch.user.userProfiles,typeMismatch.userProfiles,typeMismatch.java.util.Set,typeMismatch]; arguments      [org.springframework.context.support.DefaultMessageSourceResolvable: codes [user.userProfiles,userProfiles]; arguments []; default message [userProfiles]]; default message  [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property 'userProfiles'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type  [com.idev.tpt.model.UserProfile] for property 'userProfiles[0]': no matching editors or conversion strategy found]] 

JSP File:

<form:form id="userForm" action="newuser" modelAttribute="user">     <form:input type="hidden" path="id" id="id" />     <div class="form-group">         <form:input type="text" path="firstName" id="firstName" placeholder="First Name" class="form-control input-sm" />     </div>     <div class="form-group">         <form:input type="text" path="lastName" id="lastName" placeholder="Last Name" class="form-control input-sm" />     </div>     <div class="form-group">         <c:choose>             <c:when test="${edit}">                 <form:input type="text" path="ssoId" id="ssoId" placeholder="SSO ID" class="form-control input-sm" disabled="true" />             </c:when>             <c:otherwise>                 <form:input type="text" path="ssoId" id="ssoId" placeholder="SSO ID" class="form-control input-sm" />                 <div class="has-error">                     <form:errors path="ssoId" class="help-inline" />                 </div>             </c:otherwise>         </c:choose>     </div>     <div class="form-group">         <form:input type="password" path="password" id="password" placeholder="password" class="form-control input-sm" />         <div class="has-error">             <form:errors path="password" class="help-inline" />         </div>     </div>     <div class="form-group">         <form:input type="text" path="email" id="email" placeholder="email" class="form-control input-sm" />         <div class="has-error">             <form:errors path="email" class="help-inline" />         </div>     </div>      <div class="form-group">         <form:select path="userProfiles" items="${roles}" multiple="true" itemValue="id" itemLabel="type" class="form-control input-sm" />     </div>     <!-- <div class="form-group">                                             <textarea class="form-control" id="prop_note" name="note" placeholder="Note" ></textarea>                                         </div> -->     <p class="demo-button btn-toolbar">         <span id="warningLbl" class="label label-warning" style="display: none;"></span>         <button id="propAddBtn" type="submit" class="btn btn-primary pull-right">Save</button>         <button id="propUpdateBtn" type="submit" class="btn btn-primary pull-right" style="display: none;">Update</button>&nbsp;         <button id="propClearBtn" type="button" class="btn btn-primary pull-right" style="display: none;">Clear</button>     </p>     <br> </form:form> 

controller:

@RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)     public String newUser(ModelMap model) {         User user = new User();         model.addAttribute("user", user);         model.addAttribute("edit", false);         model.addAttribute("roles", userProfileService.findAll());         model.addAttribute("loggedinuser", getPrincipal());         return "registration";     }      /**      * This method will be called on form submission, handling POST request for      * saving user in database. It also validates the user input      */     @RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)     public String saveUser(@Valid User user, BindingResult result,             ModelMap model) {         if (result.hasErrors()) {             return "registration";         }          if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){             FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault()));             result.addError(ssoError);             return "registration";         }          userService.saveUser(user);          model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");         model.addAttribute("loggedinuser", getPrincipal());         //return "success";         return "registrationsuccess";     } 

Model :

package com.websystique.springmvc.model;  import java.io.Serializable; import java.util.HashSet; import java.util.Set;  import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table;  import org.hibernate.validator.constraints.NotEmpty;  @SuppressWarnings("serial") @Entity @Table(name="APP_USER") public class User implements Serializable{      @Id @GeneratedValue(strategy=GenerationType.IDENTITY)     private Integer id;      @NotEmpty     @Column(name="SSO_ID", unique=true, nullable=false)     private String ssoId;      @NotEmpty     @Column(name="PASSWORD", nullable=false)     private String password;      @NotEmpty     @Column(name="FIRST_NAME", nullable=false)     private String firstName;      @NotEmpty     @Column(name="LAST_NAME", nullable=false)     private String lastName;      @NotEmpty     @Column(name="EMAIL", nullable=false)     private String email;      @NotEmpty     @ManyToMany(fetch = FetchType.LAZY)     @JoinTable(name = "APP_USER_USER_PROFILE",               joinColumns = { @JoinColumn(name = "USER_ID") },               inverseJoinColumns = { @JoinColumn(name = "USER_PROFILE_ID") })     private Set<UserProfile> userProfiles = new HashSet<UserProfile>();      public Integer getId() {         return id;     }      public void setId(Integer id) {         this.id = id;     }      public String getSsoId() {         return ssoId;     }      public void setSsoId(String ssoId) {         this.ssoId = ssoId;     }      public String getPassword() {         return password;     }      public void setPassword(String password) {         this.password = password;     }      public String getFirstName() {         return firstName;     }      public void setFirstName(String firstName) {         this.firstName = firstName;     }      public String getLastName() {         return lastName;     }      public void setLastName(String lastName) {         this.lastName = lastName;     }      public String getEmail() {         return email;     }      public void setEmail(String email) {         this.email = email;     }      public Set<UserProfile> getUserProfiles() {         return userProfiles;     }      public void setUserProfiles(Set<UserProfile> userProfiles) {         this.userProfiles = userProfiles;     }      @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + ((id == null) ? 0 : id.hashCode());         result = prime * result + ((ssoId == null) ? 0 : ssoId.hashCode());         return result;     }      @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (!(obj instanceof User))             return false;         User other = (User) obj;         if (id == null) {             if (other.id != null)                 return false;         } else if (!id.equals(other.id))             return false;         if (ssoId == null) {             if (other.ssoId != null)                 return false;         } else if (!ssoId.equals(other.ssoId))             return false;         return true;     }      /*      * DO-NOT-INCLUDE passwords in toString function.      * It is done here just for convenience purpose.      */     @Override     public String toString() {         return "User [id=" + id + ", ssoId=" + ssoId + ", password=" + password                 + ", firstName=" + firstName + ", lastName=" + lastName                 + ", email=" + email + "]";     }  } 

I am also using the same model provided in the demo. I didn't change anything in the model also not change related to jsp and controller. I don't understand why I am getting an error I am using the same way as like in a demo.

User profile

package com.websystique.springmvc.model;  import java.io.Serializable;  import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table;  @SuppressWarnings("serial") @Entity @Table(name="USER_PROFILE") public class UserProfile implements Serializable{      @Id @GeneratedValue(strategy=GenerationType.IDENTITY)     private Integer id;       @Column(name="TYPE", length=15, unique=true, nullable=false)     private String type = UserProfileType.USER.getUserProfileType();      public Integer getId() {         return id;     }      public void setId(Integer id) {         this.id = id;     }      public String getType() {         return type;     }      public void setType(String type) {         this.type = type;     }      @Override     public int hashCode() {         final int prime = 31;         int result = 1;         result = prime * result + ((id == null) ? 0 : id.hashCode());         result = prime * result + ((type == null) ? 0 : type.hashCode());         return result;     }      @Override     public boolean equals(Object obj) {         if (this == obj)             return true;         if (obj == null)             return false;         if (!(obj instanceof UserProfile))             return false;         UserProfile other = (UserProfile) obj;         if (id == null) {             if (other.id != null)                 return false;         } else if (!id.equals(other.id))             return false;         if (type == null) {             if (other.type != null)                 return false;         } else if (!type.equals(other.type))             return false;         return true;     }      @Override     public String toString() {         return "UserProfile [id=" + id + ", type=" + type + "]";     } } 

user profile converter

package com.websystique.springmvc.converter;  import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component;  import com.websystique.springmvc.model.UserProfile; import com.websystique.springmvc.service.UserProfileService;  /**  * A converter class used in views to map id's to actual userProfile objects.  */ @Component public class RoleToUserProfileConverter implements Converter<Object, UserProfile>{      static final Logger logger = LoggerFactory.getLogger(RoleToUserProfileConverter.class);      @Autowired     UserProfileService userProfileService;      /**      * Gets UserProfile by Id      * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)      */     public UserProfile convert(Object element) {         Integer id = Integer.parseInt((String)element);         UserProfile profile= userProfileService.findById(id);         logger.info("Profile : {}",profile);         return profile;     }  } 

Updated

one more thing while I printing the form data using model getter method getUserProfiles() I am getting blank data so I think it's not binding the selected value.but any other column I am printing it will perfectly bind.

1 Answers

Answers 1

After your comment I updated my reply:

Probably the problem is in JSP code. When application invokes the saveUser() method in your controller, a new User object is created. But because you have UserProfile type in User object the application has to know how to create UserProfile from String (when passed from <form:select path="userProfiles">).

Either you add a custom converter from String to UserProfile or create an UserDTO class with Java standard types and use it in your Controller save operation. Code will be something similar to:

public String saveUser(@Valid UserDTO dto, ...) {     User user = createUserFromDTO(dto);     userService.saveUser(user); } 

Also make sure, that you have the UserProfile entity correctly defined with JPA annotations.

Read More

Monday, April 9, 2018

submit form on a dynamic link

Leave a Comment

Here is the code below which i am using to submit my form. When i click the link, the new window is behaving as current window and the Current window is behaving as new action link. How can i stop this behaviour.

I am reading the linkURL in a java class from JVM parameters.

<form action="<c:out value='${config.linkURL}'/>" method="GET" id="myForm">     <a href="#" target="_blank" id="myLink"><bean:message key="link.cardholder.info"/></a>     <input type="hidden" name="cardID" value="<c:out value="${config.homeSwitch}"/>" />     <script>          $('#myLink').on('click', function() { window.open('<c:out value="${config.linkURL}"/>',"title").focus();});     </script> </form> 

when i tried here the hidden values are not passing along with the url because of not calling submit() function. Any possible way to call submit function.

1 Answers

Answers 1

This link will provide you with detailed info about the HTMLFormElement.

This link will explain what the submit method of the HTMLFormElement is.

Something like:

myForm.submit(); 
Read More

Monday, March 26, 2018

block jsp page using javascript

Leave a Comment

how to block a jsp page (i want is ,when I click the links to redirect each pages I want to block some specific pages for specific users) I create an java script function to retrieve the jsp pages of each users(pages that user can access).But I have no idea to block other pages for the same user)

4 Answers

Answers 1

use js document.getElementById("id name of link").style.display = 'none'; to remove link from page and use 'block' instead of 'none' for show the link.

Answers 2

You could use the event.preventDefault(); and have a variable saying if the user should or not be blocked. Check the following example:

var BlockUser = true;  function CheckUser() {    if ( BlockUser ) {      event.preventDefault();    }  }
<a href="http://stackoverflow.com/">Link for any user</a>  <br>  <a href="http://stackoverflow.com/" onclick="CheckUser()">Link for certain users</a>

Answers 3

Pure jsp solution:

assuming you have an array of available links: List<String> links, which you pass under the same name to request(or you may retrieve it from user, doesn't matter, assume you have array of those links despite way of getting it), then you can do something like:

    ...     <c:forEach var="link" items="${links}">     <a href="${link}" <c:if test="/*here you test if user have  access, i dont know how you do it*/"> class="inactiveLink" </c:if>>page link</a>     </c:forEach>     ... 

Where ... is rest of your jsp, and define style

.inactiveLink {    pointer-events: none;    cursor: default; } 

Note that in order to use foreach - you should define jstl taglib at the top of your jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

In case you don't know what is jstl, and what is EL generally

A good notion was said about disabling css and js, if you want them to be completely inaccessible, you can just print only allowed links:

... <c:forEach var="link" items="${links}"> <c:if test="/*here you test if user have      access, i dont know how you do it*/">          <a href="${link}">page link</a> </c:if> </c:forEach> ... 

Answers 4

You can use this

document.getElementById( "id of your link element" ).style.display = 'none'; 

style.display is use for not displaying anything by setting it to none

Read More

Thursday, January 18, 2018

Spring boot use resources templates folder with JSP templates instead of webapp folder?

Leave a Comment

I started a Spring Boot MVC project and realized that there are two folder withing resources. One is called templates and the other static. I really like this folder setup.r

The problem is that I use JSP Templates for my views. I could not place a .jsp template inside the templates folder and got it to work. What I needed to do is to create a webapp folder on the same level as src and resources. Placing my JSP templates in there and then my views can be found.

What do I need to reconfigure to actually use my JSP templates within the templates folder which lies within resources?

3 Answers

Answers 1

Official information:

Resource handling:

Links to resources are rewritten at runtime in template, thanks to a ResourceUrlEncodingFilter, auto-configured for Thymeleaf and FreeMarker. You should manually declare this filter when using JSPs. source

Supported template engine

As well as REST web services, you can also use Spring MVC to serve dynamic HTML content. Spring MVC supports a variety of templating technologies including Thymeleaf, FreeMarker and JSPs.

[...]

JSPs should be avoided if possible, there are several known limitations when using them with embedded servlet containers.

[..]

When you’re using one of these templating engines with the default configuration, your templates will be picked up automatically from src/main/resources/templates.

source

Spring boot JSP limitations

  • With Tomcat it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to a standard
    container (not limited to, but including Tomcat).
  • An executable jar will not work because of a hard coded file pattern in Tomcat.
  • With Jetty it should work if you use war packaging, i.e. an executable war will work, and will also be deployable to any standard container.
  • Undertow does not support JSPs.
  • Creating a custom error.jsp page won’t override the default view for error handling, custom error pages should be used instead.

source

Technical change

Tell spring boot to from where to load the JSP files. In application.properties set

spring.mvc.view.prefix: /WEB-INF/views/ spring.mvc.view.suffix: .jsp 

source

Sample spring boot with JSP

In case you do want to use JSP with spring boot here are two examples:

https://github.com/spring-projects/spring-boot/tree/v1.5.9.RELEASE/spring-boot-samples/spring-boot-sample-web-jsp

https://github.com/joakime/spring-boot-jsp-demo

Answers 2

To summarize it, none of the suggested answers worked for me so far. Using a blank Spring boot starter project.

Somehow, something looks hardwired inside Spring or servlets so that JSP must be in /webapp (or a subfolder). Unlike default thymeleaf templates which are looked up in /resources/templates.

I tried all kind of changes, really a lot of different configurations, but wasn't able to modify that behavior. It just produced complexity and was unable to serve the JSPs anymore. So, bottom line, if you're using JSPs, just put them in /webapp. It also works by addding zero configuration using a controller like:

@GetMapping("/foo") public String serveFoo() { return "relative-path-inside-webapp/foo.jsp"; }

On another note, by default, the /webapp folder will also be hidden in the Spring Toolsuite, so you'll have to manually configure it as a "source folder".

Answers 3

According to the Maven documentation src/main/resources will end up in WEB-INF/classes in the WAR.

This does the trick for Spring Boot in your application.properties:

spring.mvc.view.prefix = /WEB-INF/classes/templates spring.mvc.view.suffix = .jsp 

If you prefer Java configuration this is the way to go (I tested this with a sample project here):

@EnableWebMvc @Configuration public class ApplicationConfiguration extends WebMvcConfigurerAdapter {      @Bean     public ViewResolver jspViewResolver() {         InternalResourceViewResolver bean = new InternalResourceViewResolver();         bean.setPrefix("/WEB-INF/classes/templates/");         bean.setSuffix(".jsp");         return bean;     } } 
Read More

Thursday, September 21, 2017

Spring MVC - Drop Down Object Selection - No primary identifier

Leave a Comment

A fairly common use case occurs where there is a list of Java objects, from which selections can be made on a web form - usually you'd use the primary key of the object as the value so that the controller could either do a lookup, or just bind the key to whichever object is created/updated.

My problem is that the list to choose from are not persistent, keyed objects, they are business models from a service which have no reasonable way to retrieve them based on the data contained. Below is some psuedo code where a list of Foo's are given to the page, and we can easily communicate to the controller onSubmit the name of Foo, but what if there are other fields of Foo that need to be submitted?

controller:

referenceData() {     ...     List foos = fooService.getFoosForBar( bar )     return { 'foos', foos } } 

jsp:

<form>    ... <spring:bind path="formData.foo">     <select name="<c:out value="${status.expression}" />">         <c:forEach items="${foos}" var="foo">             <option value="<c:out value="${foo.name}"/>">                 <c:out value="${foo.name}"/>             </option>         </c:forEach>     </select> </spring:bind>    ... </form> 

Some example solutions would be to use hidden fields to submit Foo's other properties and keep them in sync as the selection is changed, but I prefer not to use JavaScript in a situation like this where it will likely add confusion. There are certainly other ways to accomplish this too.

My question is does there exist any standard practice for accomplishing this? Or should I just come up with my own way of doing so? I'd rather not re-invent wheels if possible, and this is so seemingly common that just winging it may not be the best approach.

2 Answers

Answers 1

Based on your limitations, you must encode the other data memebers of foos as the value of the option.
<option label="${foo.name}" value="${foo.encodedValues}"/>
The encodedValues method might look something like this:

      private String SEPERATOR = ",";      public String getEncodedValues()     {         StringBuffer returnValue = new StringBuffer();          returnValue.append(field1);         returnValue.append(SEPERATOR);         returnValue.append(field2);         returnValue.append(SEPERATOR);         returnValue.append(field3);          return returnValue.toString();     }  

If you have a number of selects that need to have encoded values, you may want to create a class that does the encoding and decoding of these values to centralize the code.

Answers 2

You can use the index of the element in the list to get it back in the POST request.

<spring:bind path="formData.fooIndex">   <select name="<c:out value="${status.expression}" />">     <c:forEach items="${foos}" var="foo" varStatus="i">         <option value="<c:out value="${i.index}"/>">             <c:out value="${foo.name}"/>         </option>     </c:forEach>   </select> </spring:bind> 

In your POST handler, use foos.get(formData.getFooIndex()) If foos can change between the GET and POST requests, you need to put foos in session so that you definitely reference the same object in your POST handler as you did in the GET handler.

Read More

Wednesday, July 12, 2017

Spring-Security: MySQL JDBC Authentication fails

Leave a Comment

I am manipulating an open source project in this repo. The file bank.sql is the schema of the database in mysql. Here is the pom.xml:

 <dependencies>      <!-- https://mvnrepository.com/artifact/org.apache.tomcat/juli -->     <dependency>         <groupId>org.apache.tomcat</groupId>         <artifactId>juli</artifactId>         <version>6.0.26</version>     </dependency>      <dependency>         <groupId>javax.servlet</groupId>         <artifactId>jsp-api</artifactId>         <version>2.0</version>         <scope>provided</scope>     </dependency>        <dependency>         <groupId>javax.servlet</groupId>         <artifactId>servlet-api</artifactId>         <version>2.5</version>         <scope>provided</scope>     </dependency>    <dependency>    <groupId>junit</groupId>    <artifactId>junit</artifactId>    <version>4.11</version>    <scope>test</scope>   </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>3.2.3.RELEASE</version>   </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>3.2.3.RELEASE</version>   </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>3.2.3.RELEASE</version>   </dependency>    <dependency>       <groupId>org.springframework.security</groupId>       <artifactId>spring-security-core</artifactId>       <version>3.2.3.RELEASE</version>   </dependency>    <dependency>       <groupId>org.springframework.security</groupId>       <artifactId>spring-security-config</artifactId>       <version>3.2.3.RELEASE</version>   </dependency>    <dependency>        <groupId>org.springframework.security</groupId>        <artifactId>spring-security-web</artifactId>        <version>3.2.3.RELEASE</version>   </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-jdbc</artifactId>        <version>3.2.3.RELEASE</version>   </dependency>    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.6</version>   </dependency>    <dependency>        <groupId>jstl</groupId>        <artifactId>jstl</artifactId>        <version>1.2</version>   </dependency>    <dependency>        <groupId>opensymphony</groupId>        <artifactId>sitemesh</artifactId>        <version>2.4.2</version>   </dependency>  </dependencies> 

I have a login form as below:

    <form name="loginForm" class="form-login"         action="<c:url value="/j_spring_security_check" />" method="POST">         <h2>Please sign in</h2>          <c:if test="${not empty error}">             <div class="alert alert-danger">${error}</div>         </c:if>         <c:if test="${not empty msg}">             <div class="alert alert-info">${msg}</div>         </c:if>          <input type="text" class="form-control" placeholder="Username" name="username">         <input type="password" class="form-control" placeholder="Password" name="password" />         <button type="submit" class="btn btn-lg btn-primary btn-block" name="submit">Login</button>         <input type="hidden" name="${_csrf.parameterName}"             value="${_csrf.token}" />      </form> 

The file Spring-Security.xml is as below:

<beans:beans xmlns="http://www.springframework.org/schema/security"     xmlns:beans="http://www.springframework.org/schema/beans"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/security     http://www.springframework.org/schema/security/spring-security-3.2.xsd">      <http auto-config="true" use-expressions="true">         <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" />         <intercept-url pattern="/user**" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />         <intercept-url pattern="/change**" access="hasRole('ROLE_NEWUSER')" />          <access-denied-handler error-page="/403" />          <form-login              login-page="/login"              authentication-success-handler-ref="bankCustomAuthenticationSuccessHandler"             authentication-failure-url="/login?error"              username-parameter="username"             password-parameter="password" />         <logout logout-success-url="/login?logout"  />         <!-- enable csrf protection -->         <csrf/>     </http>      <beans:bean id="bankCustomAuthenticationSuccessHandler"         class="ee.mikkelsaar.bank.security.MyUrlAuthenticationSuccessHandler" />      <authentication-manager>         <authentication-provider>             <password-encoder hash="sha" />             <jdbc-user-service data-source-ref="dataSource" users-by-username-query="select username,password, enabled from users where username=?" authorities-by-username-query="select u.username, a.authority from users u, authorities a where u.username = a.username and u.username =?" />         </authentication-provider>     </authentication-manager>      <beans:import resource="spring-datasource.xml" />      <beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.MessageDigestPasswordEncoder">       <beans:constructor-arg value="sha" />     </beans:bean>   </beans:beans> 

And there is a bean to obtain the datasource to provide it for Authentication-manager such as below:

<beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">      <bean id="dataSource"         class="org.springframework.jdbc.datasource.DriverManagerDataSource">          <property name="driverClassName" value="com.mysql.jdbc.Driver" />         <property name="url" value="jdbc:mysql://localhost:3306/bank" />         <property name="username" value="root" />         <property name="password" value="" />     </bean>  </beans> 

I am sure the MySQL Server is running on port 3306 well.

The correct credential is username:Tom and password:Tom but everytime I try to login with them it fails. I am wondering, what is wrong with my authentication process?

How can i fix it?

I guess, maybe the datasource bean is not created correctly, but i have no idea how to check it?

Update:

When i add the <http security="none" pattern="/login"/> to my Spring-Security.xml it complains with

HTTP Status 405 - Request method 'POST' not supported for (username, password) `(Tom, tom)`, which is not a valid credential. But for a valid credential like `(Tom,Tom)` is still navigates to the login page again.  

but it happens

3 Answers

Answers 1

First of all, in Spring Security prior to version 4, default parameter names are j_username and j_password (like in the post you mentioned) and not username/password.

In Spring Security 4, the default names are username and password, but the default URL to which UsernamePasswordAuthenticationFilter binds is /login and not /j_spring_security_check.

So in all Spring Security versions, your URL and parameter names combination does not match the defaults.

Here is an example of how username-password authentication against a database may be configured: http://www.mkyong.com/spring-security/spring-security-form-login-using-database/ (for Spring Security 3.x)

Another example (much more short and simple), for Spring Security 4: https://spring.io/guides/gs/securing-web/

How the parameters are passed

Basically, if you have a form-based authentication, it works like this:

  1. User tries to access some URL that requires authentication; user lacks that authentication
  2. Spring Security redirects the user to a login page
  3. User enters login and password on that page and submits it; in the default configuration in Spring Security versions before 4, username is submitted as j_username and password as j_password to /j_spring_security_check
  4. Spring Security-supplied UsernamePasswordAuthenticationFilter processes submissions to /j_spring_security_check URL. Once it gets a request (from login form), it extracts the parameters (username/password), packs them into UsernamePasswordAuthenticationToken and feeds it to AuthenticationManager for authentication.
  5. AuthenticationManager checks access (JDBC can be used to check against a database, for example)
  6. If the authentication is successful (user exists with the supplied name, password matches), the result Authentication is constructed (which contains information about roles), saved, and AuthenticationSuccessHandler is invoked; it gets that Authentication result
  7. After authentication succeeds, the user is redirected back to the URL he tried to access on step 1, and only here a business logic controller will be executed.

Answers 2

You can do one change, try for and for Authentication-manager Authentication-manager

    <security:authentication-manager alias="authManager">         <security:authentication-provider             ref="daoAuthProvider">         </security:authentication-provider>     </security:authentication-manager>    <beans:bean id="daoAuthProvider"         class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">         <beans:property name="userDetailsService">             <beans:ref bean="userDetailsService" />         </beans:property>         <beans:property name="passwordEncoder" ref="encoder"/>     </beans:bean>  <beans:bean id="userDetailsService"         class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">         <beans:property name="dataSource">             <beans:ref bean="coreDataSource" />         </beans:property>         <beans:property name="usersByUsernameQuery">             <beans:value>                 SELECT username,password as password FROM userdetails WHERE                 password != '' and username= ?              </beans:value>         </beans:property>         <beans:property name="authoritiesByUsernameQuery">             <beans:value>                 SELECT username,authority FROM authorities JOIN userdetails ON authorities.user_id = userdetails.user_id ..                 WHERE userdetails.username= ? and             </beans:value>         </beans:property>   <security:http pattern="/admin/admin.jsp" security="none" /> <security:http pattern="/**/*.js" security="none" /> ..           <security:custom-filter ref="formAuthFilter"             after="FORM_LOGIN_FILTER" />     <beans:bean id="formAuthFilter"         class="com.sca.security.SCAAuthenticationProcessingFilter">          <beans:property name="authenticationManager" ref="authManager" />         <beans:property name="allowSessionCreation" value="true" />         <beans:property name="authenticationFailureHandler"             ref="authFailureHandler" /> <!-- define authFailureHandler -->         <beans:property name="authenticationSuccessHandler"             ref="authSuccessHandler" /><!-- define authSuccessHandler -->         <beans:property name="filterProcessesUrl" value="/j_spring_security_check" /> <!-- define userDAO, globalFilter-->          </beans:property>       </beans:bean> 

This is what exactly you are asking for. Please do not forget to accept the answer if you are satisfied or ask more if needed.

Answers 3

Your spring security config is right. The key for resolving this problem is understanding spring-security csrf protection strategy.More detail you can see [org.springframework.security.web.csrf.CsrfFilter.java][1] source code.

Server side CSRF token repository is session based. It will generated when you first get request. Get request will not trigger CSRF validation, so it can pass.But if your client side token is wrong or empty server will prevent your any modify request(.eg POST,PUT,DELETE), response 403 state code.

Your error is caused by that your page is holding an old csrf token in the hidden input, and every login request is forwarded to an error page, so your client side csrf token can not be refreshed.

So simply, you can try refresh you login page and try login again.

Read More

Friday, February 24, 2017

Tomcat/Spring boot reloading META-INF/resources/ jsp files (live updates)

Leave a Comment

I have a problem using jsp in spring boot/tomcat instances. Basically, I have all jsp files inside module A (A/src/main/resources/META-INF/resources/jsp) and this module is included into module B (main module, war packaging) as a jar dependency. The problem is, when app is running in debug mode (either in Eclipse or in IntelliJ Idea), none of the jsp files located in module A, are being auto reloaded(changes in file are not seen on the rendered webpage), only restart of tomcat actually reloads the files and shows the changes. The overriden jsp files in Module B are being reloaded themselves, just the jsp files in Module A are having problems(probably because of META-INF/resources folder).

Module A structure(dependency, packaged as jar): src/main/resources/META-INF/resources/jsp/*.jsp

Module B structure(main module, packaged as war, jsp in here override the ones in Module A): src/main/webapp/jsp/*.jsp

I have searched for a solution to this, but the closest I came to an answer was this(Using JRebel): https://zeroturnaround.com/forums/topic/jsps-in-servlet-3-0-jars-are-not-reloading/

Also, this is an example on how I have jsp set up: https://github.com/ghillert/spring-boot-jsp-demo

2 Answers

Answers 1

This is highly likely the same as: http://stackoverflow.com/a/8656527/696632

All resources in classpath are subject to a cache. You should evaluate the answer.

Answers 2

I don't know if it fits your constraints but there is a solution like this out there : https://spring.io/blog/2015/06/17/devtools-in-spring-boot-1-3

Another option: https://github.com/spring-projects/spring-loaded

I use JSF and Facelets and hot reload is always a bit problematic for web technologies which has dynamic rendering. So my suggestion apart from spring-boot-devtools will be separating static content development process from rendering related process. If you only need hot reload for css, html, js editing than most of technologies out there will help you but rendering related component editing going to ask you to rebuilt redeploy your app time to time. How frequently they going to ask you that depends on quality of the tool you will be using.

Read More

Friday, October 7, 2016

Oracle SSO URL regex to exclude if URL has an specific param

Leave a Comment

Currently, we have SSO enabled in our web application and works well. But, when an user is configured in SSO but not in our web application, we are having a redirect loop.

We have noticed that, when this happens, webapp invokes an URL like this:

/login.jsp?errormsg=The+User%3A+SOMEUSER+doesn%27t+exist 

And my configuration of enforced URLs is the next:

com.sun.identity.agents.config.notenforced.uri[0] = / com.sun.identity.agents.config.notenforced.uri[1] = /-*-.jsp com.sun.identity.agents.config.notenforced.uri[2] = /-*-.jsp* com.sun.identity.agents.config.notenforced.uri[3] = /-*-.jsp?* ... com.sun.identity.agents.config.notenforced.uri.invert = true 

I enforce all jsps to be validated through SSO. But, what i want to do is to define an URI like:

  • If an .jsp is being invoked, but it doesn't have errormsg parameter in it, validate session through SSO;
  • But if an .jsp is being invoked and errormsg parameter is in the URL, don't validate it, let it go.

The thing is, can i use regular expressions on SSO URIs? Because those patterns

/-*-.jsp

as far as i know, aren't regular expressions.

How can i create that filter?

1 Answers

Answers 1

You're right in thinking the not enforced list pattern in AMAgent.properties isn't a regular expression. As it seems you've already discovered, it uses a far more limited wildcard matching syntax.

The answer to the question "Can I use regular expressions on SSO URIs?" seems to be no. Unfortunately what can be done here is very limited as the syntax does not include a way of excluding particular characters or phrases. Without further understanding the requirements, my best suggestion would be to use an exclude list rather than an include list:

com.sun.identity.agents.config.notenforced.uri[0] = /-*-.jsp?errormsg* ... 

(with com.sun.identity.agents.config.notenforced.uri.invert = false)

Of course you may need to add many further entries to this list and it may become large but at least it is more compliant with Oracle's advice:

When the not-enforced list is inverted, the number of resources for which the agent will not enforce access control is potentially very large. The use of this feature should therefore be used with extreme caution and only after extensive evaluation of the security requirements of the deployed applications.

Read More

Thursday, August 4, 2016

spring-boot using multiple view resolvers from xml configuration not redirecting correctly

Leave a Comment

I have a legacy application using spring xml which I am migrating to spring-boot.

The application starts and I get the authentication page, mapped in the applicationContext-login.xml. On login successful it should load WEB-INF/client/home.jsp, but, instead, it tries to load /WEB-INF/auth/home.jsp and I get 404. In the startup log I see it mapping all the paths. Why is it conflicting on these redirects and what can I do to fix this? Does it encounter issues because of multiple @ImportResource containing view resolvers?

Extract from security http configuration:

    <s:http use-expressions="true" entry-point-ref="delegatingAuthenticationEntryPoint">         <s:form-login login-page="/auth/login"                       login-processing-url="/auth/j_spring_security_check"                       authentication-failure-url="/auth/login-secure?loginFailed=true"                       default-target-url="/auth/defaultEntry"/>         <s:logout logout-url="/auth/logout" logout-success-url="/auth/logout-success" delete-cookies="jsessionid"/>     </s:http> 

The controller it points to:

    @RequestMapping(value = "/defaultEntry", method = RequestMethod.GET)     public String defaultEntry() {         if (authentication.isAuthenticated()) {               return "redirect:/client/home";         } else {             return "redirect:login";         }     } 

The application has multiple view resolvers configured in xml files:

  • classpath*:/springContext/applicationContext-login.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:context="http://www.springframework.org/schema/context"     xmlns:mvc="http://www.springframework.org/schema/mvc"     xsi:schemaLocation="http://www.springframework.org/schema/beans                       http://www.springframework.org/schema/beans/spring-beans.xsd                       http://www.springframework.org/schema/context                       http://www.springframework.org/schema/context/spring-context.xsd                       http://www.springframework.org/schema/mvc                       http://www.springframework.org/schema/mvc/spring-mvc.xsd"     default-init-method="init"     default-destroy-method="destroy">    <import resource="applicationContext-web-common.xml" />    <!-- Static login resources -->   <mvc:resources mapping="/css/**" location="/WEB-INF/auth/css/"/>   <mvc:resources mapping="/assets/**" location="/WEB-INF/auth/assets/"/>   <mvc:resources mapping="/js/**" location="/WEB-INF/auth/js/"/>    <context:component-scan base-package="org.myCompany.auth" />    <!-- view resolver for JSP -->   <bean id="loginViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>       <property name="prefix" value="/WEB-INF/auth/"/>       <property name="suffix" value=".jsp"/>   </bean>    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">       <property name="defaultLocale" value="en_US"/>   </bean> 

  • classpath*:/springContext/applicationContext-client.xml"

    <?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xsi:schemaLocation="http://www.springframework.org/schema/beans                         http://www.springframework.org/schema/beans/spring-beans.xsd                         http://www.springframework.org/schema/context                         http://www.springframework.org/schema/context/spring-context.xsd                         http://www.springframework.org/schema/mvc                         http://www.springframework.org/schema/mvc/spring-mvc.xsd"       default-init-method="init"       default-destroy-method="destroy">      <import resource="applicationContext-web-common.xml" />      <context:component-scan base-package="org.myCompany.client" />      <!-- Static resources -->     <mvc:resources mapping="/player/**" location="/WEB-INF/client/player/"/>     <mvc:resources mapping="/css/**" location="/WEB-INF/client/css/"/>     <mvc:resources mapping="/data/**" location="/WEB-INF/client/data/"/>     <mvc:resources mapping="/js/**" location="/WEB-INF/client/js/"/>     <mvc:resources mapping="/locales/**" location="/WEB-INF/client/locales/"/>     <mvc:resources mapping="/media/**" location="/WEB-INF/client/media/"/>     <mvc:resources mapping="/index.html" location="/WEB-INF/client/index.html"/>     <mvc:resources mapping="/test.html" location="/WEB-INF/client/test.html"/>     <mvc:resources mapping="/admin/**" location="/WEB-INF/client/admin/"/>     <mvc:resources mapping="/documentation/**" location="/WEB-INF/client/documentation/"/>       <bean id="clientViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>         <property name="prefix" value="/WEB-INF/client/"/>         <property name="suffix" value=".jsp"/>     </bean>   </beans> 

There are also a few others following the same configuration pattern.

I am loading the resources in the Application.java

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})     //@EnableWebMvc     @ComponentScan({"org.myCompany"})     @ImportResource({"classpath*:/springContext/applicationContext-controllers.xml",             "classpath*:/springContext/applicationContext-rest.xml",             "classpath*:/springContext/applicationContext-login.xml",             "classpath*:/springContext/applicationContext-client.xml",             "classpath*:/springContext/applicationContext-admin.xml",             "classpath*:/springContext/applicationContext-logging.xml",             "classpath*:/springContext/applicationContext-web-common.xml"     })     public class Application extends SpringBootServletInitializer {          public static void main(String[] args) throws UnknownHostException {             SpringApplication app = new SpringApplication(Application.class);             ApplicationContext ctx = app.run(args);             Environment env = ctx.getEnvironment();              logger.info(String.format("\n----------------------------------------------------------\n\t" +                             "Application '%s' is running! Access URLs:\n\t" +                             "Local: \t\thttp://localhost:%s\n\t" +                             "External: \thttp://%s:%s\n----------------------------------------------------------",                     env.getProperty("spring.application.name"),                     env.getProperty("server.port"),                     InetAddress.getLocalHost().getHostAddress(),                     env.getProperty("server.port")));         }          @Bean         public ServletRegistrationBean restDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(),                     "/rest/*", "/websocket/*");             registration.setName("rest-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-rest.xml");             registration.setInitParameters(params);             return registration;         }          @Bean         public ServletRegistrationBean authDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(), "/auth/*");             registration.setName("auth-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-login.xml");             registration.setInitParameters(params);             return registration;         }          @Bean         public ServletRegistrationBean clientDispatcher() {             ServletRegistrationBean registration = new ServletRegistrationBean(new DispatcherServlet(), "/client/*");             registration.setName("client-dispatcher");             registration.setLoadOnStartup(2);             Map<String, String> params = new HashMap<>();             params.put("contextConfigLocation", "classpath*:springContext/applicationContext-client.xml");             registration.setInitParameters(params);             return registration;         }      //... other servlets registration, filters registration      } 

3 Answers

Answers 1

You are returning redirect:/client/home from your login screen which will get processed by your loginViewResolver:

<bean id="loginViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>       <property name="prefix" value="/WEB-INF/auth/"/>       <property name="suffix" value=".jsp"/>   </bean> 

The clientViewResolver does not get invoked since there is no order specified on the view resolvers. You can set the order using the order property.,

Answers 2

I may assume, that this is caused by Spring Security configuration, and does not depend from View Resolvers. It looks like after success login user is being redirected to page, which he tried to access before, and it may not be /defaultEntry. Try edit your Spring Security http configuration as follows:

<s:http use-expressions="true" entry-point-aref="delegatingAuthenticationEntryPoint">     <s:form-login login-page="/auth/login"                   login-processing-url="/auth/j_spring_security_check"                   authentication-failure-url="/auth/login-secure?loginFailed=true"                   default-target-url="/auth/defaultEntry"                   always-use-default-target="true"/>     <s:logout logout-url="/auth/logout" logout-success-url="/auth/logout-success" delete-cookies="jsessionid"/> </s:http> 

If it helps - you'll get a clue where to look further.

Also, check it out this StackOverFlow answer.

Answers 3

The problem with your dispatcher servlet configuration you defined

  <bean id="clientViewResolve" class="org.springframework.web.servlet.view.InternalResourceViewResolver">   <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>   <property name="prefix" value="/WEB-INF/client/"/>   <property name="suffix" value=".jsp"/> 

With that configuration , its likely to get resolved to /WEB-INF/client/client/*.jsp

Its better to use a single viewresolver rather than complexing the task of having two view resolvers.

Read More

Thursday, April 21, 2016

How can compile I `.java file` in jsp?

Leave a Comment

Using java compiler API I want to compile a java file in jsp. I created a html file and using its textArea element I sent its text, which is expected to be code in java entered by user, to JSP on server and after collecting it in a string I made a file with .java extension and wrote it with textArea contents then i used compiler API but it is not compiling the file. I want to do something like this

index.html

  <form action="formAction.jsp" method="post">         Please enter your text:         <br/>         <textarea name="textarea1" rows="5"></textarea>         <br/>         <input type="SUBMIT" value="Submit"/>     </form>      

formAction.jsp

 <%          String convert = request.getParameter("textarea1");         PrintWriter wr = response.getWriter();         File f =new File("file121.java");         if(!f.exists())         {             f.createNewFile();             wr.println("File is created\n");          }         FileWriter write = new FileWriter(f);         BufferedWriter bf = new BufferedWriter(write);         bf.write(convert);         bf.close();         wr.println("File writing done\n");          JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();         int result = compiler.run(null,null,null,"file121.java");         if(result==0){             wr.println("Compilation Successful");         }         else{             wr.println("Compilation Failed");         }          %>    

2 Answers

Answers 1

  1. Please do not use scriptlets, write java code that you can call from your jsp.
  2. Java requires a file name with the name of the class, this was probably your main problem.
  3. What is the expected format of java code the user can enter? Method, Class or only a script inside a method?
  4. With your level of java knowledge, please do not allow unknown users to enter code or your server will get hacked very soon!

The following code compiles the code in variable convert. It automaticaly detects the name of the class entered. If no class has been found, it creates a template with the classname MyClass.

      String convert = "public class NewClass {  public static void main(String[] args) {    System.out.println(\"test\");  }}";   String filename = "MyClass.java";    int i = convert.indexOf(" class ");   if(i == -1) {     convert = "public class MyClass { " + convert + " } ";   } else {     int classNameIndex = convert.indexOf(" ", i+1);     int classNameIndexEnd = convert.indexOf(" ", classNameIndex+1);             filename = convert.substring(classNameIndex+1, classNameIndexEnd) + ".java";   }    PrintWriter wr = response.getWriter();   File f = new File(filename);   if (!f.exists()) {     f.createNewFile();     wr.println("File is created\n");    }   FileWriter write = new FileWriter(f);   BufferedWriter bf = new BufferedWriter(write);   bf.write(convert);   bf.close();   wr.println("File writing done\n");    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();   int result = compiler.run(null, null, null, filename);   if (result == 0) {     wr.println("Compilation Successful");   } else {     wr.println("Compilation Failed");   } 

Answers 2

There are several ways of implementing this scenario but we must include Java code in the JSPs rather use Expression Language (EL) for the same or we can even write custom jsp tags for our custom functionality. This link will explain a lot about this process.

http://www.journaldev.com/2099/jsp-custom-tags-example-tutorial

Even though if you like going through text books then Head First Servlet and JSP explains this whole concept in detail and elegantly. So for having proper functioning information this book is a must have book.

Happy Learning..

Read More

Sunday, April 10, 2016

why Ng Repeat is not working if button invoked from a different form?

Leave a Comment

I have a html table that contains an ng repeat directive and two button.The first one will open a modal that contains a new form and let me create my user and then when i click save it will add it to the list.The second one is in the same original form and do the add a user.

What i did not understand why when i click on the first button which is in a different form i can not update the ng repeat however for the second one it's possible. This is the code:

homepage.jsp

<body ng-app="myApp">     <div class="generic-container" ng-controller="UserController as ctrl">         <div id="createUserContent.jsp" ng-include="createUserContent"></div>         <table>             <tr>                 <td>                     <button type="button" class="btn btn-primary"                     ng-click="ctrl.openCreateUser()">Create</button>                 </td>             </tr>         </table>         <table class="table table-hover">             <thead>                 <tr>                     <th>ID.</th>                     <th>Name</th>                     <th>Address</th>                     <th>Email</th>                     <th width="20%"></th>                 </tr>             </thead>             <tbody>                 <tr ng-repeat="u in ctrl.users">                     <td><span ng-bind="u.ssoId"></span></td>                     <td><span ng-bind="u.firstName"></span></td>                     <td><span ng-bind="u.lastName"></span></td>                     <td><span ng-bind="u.email"></span></td>                 </tr>             </tbody>         </table>     </div> </body> 

user_controller.js

'use strict';  App.controller('UserController', function ($scope, UserService, $window, $log, $uibModalStack,         $uibModal, $rootScope) {     var self = this;      self.users = [];      self.fetchAllUsers = function () {         console.log('----------Start Printing users----------');         for (var i = 0; i < self.users.length; i++) {             console.log('FirstName ' + self.users[i].firstName);         }     };         /**     this function will not work     **/     self.saveUser = function (user) {         self.users.push(user);         self.fetchAllUsers();         $log.log("saving user");         $uibModalStack.dismissAll();     };      /**     this function works fine     **/     self.addNewRow = function () {         var specialUser = {                 id : 12,                 firstName : 'john',                 lastName: 'travolta',                 homeAddress : {location:'chicago'},                 email : 'trav@email.com'         };         self.users.push(specialUser);         $log.log("saving specialUser");     };     self.openCreateUser = function () {          var modalInstance = $uibModal.open({                 animation : true,                 templateUrl : 'createUserContent',                 controller : 'UserController',                 resolve : {                     items : function () {                         return $scope.items;                     }                 }             });          modalInstance.result.then(function (selectedItem) {             $scope.selected = selectedItem;         }, function () {             $log.info('Modal dismissed at: ' + new Date());         });     };     self.fetchAllUsers(); }); 

createUserContent.jsp

<form role="form" ng-controller="UserController as ctrl" >     <div class="form-group">         <label for="FirstName">FirstName</label> <input type="FirstName"             ng-model="ctrl.user.firstName" class="form-control"             id="FirstName" placeholder="Enter FirstName" /> <label             for="lastName">lastName</label> <input type="lastName"             class="form-control" id="lastName"             ng-model="ctrl.user.lastName" placeholder="Enter lastName" />         <label for="email">Email address</label> <input type="email"             ng-model="ctrl.user.email" class="form-control" id="email"             placeholder="Enter email" />     </div>     <div class="form-group">         <label for="homeAddressLocation">Home Address</label> <input class="form-control"             ng-model="ctrl.user.homeAddress.location" id="homeAddressLocation"             placeholder="homeAddressLocation" />     </div>     <div class="form-group">         <label for="SSOId">SSOId</label> <input class="form-control"             ng-model="ctrl.user.ssoId" id="SSOId" placeholder="SSOId" />     </div>     <button type="submit" class="btn btn-default"         ng-click="ctrl.saveUser(ctrl.user)">Save</button>     <button type="submit" class="btn btn-default">Cancel</button> </form> 

1 Answers

Answers 1

Because of your modal template can't access your UserController object and doesn't show error because you used in modal template same controller so reloaded as new Ctrl doesn't refer parent Ctrl.

However better to use different controller and pass parent controller object to modal controller and then modal body can use all parent object. so you should pass parent object to modal controller.

When you include createUserContent.jsp popup file in your main file then no need to use ng-controller="UserController as ctrl" in your modal template you used in modalInstance controller : 'Ctrl',

like:

var modalInstance = $uibModal.open({       templateUrl: 'createUserContent.jsp',       controller: 'ModalCtrl', // ModalCtrl for modal       controllerAs:'modal', // as modal so no need to use in modal template       size: 'lg',       resolve: {         items: function () {           return $scope.items;         },         parent: function(){ // pass self object as a parent to 'ModalCtrl'                 return self;         }       } 

and ModalCtrl like:

.controller('ModalCtrl', ['parent', function (parent) {     this.parent = parent; }]); 

here used ModalCtrl for modal as modal so you can access parent object like: modal.parent.user

template like:

<form role="form" >     <div class="form-group">     <label for="FirstName">FirstName</label> <input type="FirstName" ng-model="modal.parent.user.firstName" class="form-control" id="FirstName" placeholder="Enter FirstName" />         .....         ....     <button type="submit" class="btn btn-default" ng-click="modal.parent.saveUser(modal.parent.user)">Save</button>     <button type="submit" class="btn btn-default">Cancel</button>     </form> 

More details Visit PLUNKER DEMO

Read More

Wednesday, March 23, 2016

Unable to compile class for JSP error when I'm running my code in eclipse gwt project

Leave a Comment

Hi I'm getting following error when I'm trying to access jsp page in my gwt project. Other pages which are not jsp pages are acessing fine.

It is strange that I'm able to see JSP file when GWT SDK is moved to bottom in build path order which is giving another error that GWT SDK is not installed

Can any one help me please ?

org.apache.jasper.JasperException: Unable to compile class for JSP Generated servlet error: 2016/01/07 14:30:51:128 IST [ERROR] Compiler - Javac exception  <Compile failed; see the compiler error output for details.>Compile failed; see the compiler error output for details. at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:933) at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:757) at org.apache.jasper.compiler.Compiler.generateClass(Compiler.java:379) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:472) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:439) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:511) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:295) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236) at javax.servlet.http.HttpServlet.service(HttpServlet.java:848) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1494) at com.rapapp.gwt.server.common.util.CompressionFilter.doFilter(CompressionFilter.java:113) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1482) at com.rapapp.gwt.server.common.util.CacheFilter.doFilter(CacheFilter.java:69) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1474) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:499) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:68) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:370) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489) at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543) at java.lang.Thread.run(Unknown Source)    Generated servlet error: 2016/01/07 14:30:51:129 IST [ERROR] Compiler - Env: Compile:  javaFileName=/C:/Users/USER/AppData/Local/Temp/jetty-127.0.0.1-8888-war-_-any-//org/apache/jsp\login_jsp.java 

1 Answers

Answers 1

As you are not providing login.jsp file, So I want to share couple of suggestions to solve this issue.

  1. Use latest tomcat - http://www.howopensource.com/2015/07/unable-to-compile-class-for-jsp-the-type-java-util-mapentry-cannot-be-resolved/

  2. The jsp-api is provided by your Servlet container. Use at least 2.1 version. Change the dependency in your pom.xml

<dependency>     <groupId>javax.servlet</groupId>     <artifactId>jsp-api</artifactId>     <version>2.1</version>     <scope>provided</scope> </dependency> 
  1. Use your bean where class name will be written with package name. As an example,
<%@ page import="com.Test.Person" %>  <html>  <head></head>  <body>  <jsp:useBean id="person" class="com.Test.Person" scope="request" />  <jsp:setProperty name="person" property="name" value="Tripti" />  This JSP Page is created by:<jsp:getProperty name="person" property="name" />   </body>  </html> 
  1. The Tomcat container caches .java and .class files generated by the JSP parser they are used by the web application. Sometimes these get corrupted or cannot be found. This may occur after a patch or upgrade that contains modifications to JSPs.

Resolution

  • Delete the contents of the <JIRA_INSTALL>/work folder if using standalone JIRA or <CATALINA_BASE>/work if using EAR/WAR installation.
  • Verify the user running the JIRA application process has Read/Write permission to the<JIRA_INSTALL|CATALINA_BASE>/work directory.
  • Restart the JIRA application container to rebuild the files.

There are also some other ways--

  1. Classes not within a package are discouraged in modern Java, to the point where they don't work in a number of cases. Put your classes into packages (use a package statement at the top of the .java file)--all of them.

  2. This problem is generated by the default values used by JspServlet, which compiles using 1.4 for source/target values.

You can cofigure this servlet by adding

<servlet>     <servlet-name>jsp</servlet-name>     <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>     <init-param>         <param-name>compilerSourceVM</param-name>         <param-value>1.5</param-value>     </init-param>     <init-param>         <param-name>compilerTargetVM</param-name>         <param-value>1.5</param-value>     </init-param>     <load-on-startup>3</load-on-startup> </servlet> 
  1. There is one more issue as you can't configure JspServlet with the current jasper-compiler-5.0.28. You should download jasper-compiler-5.0.30 and make sure is in your classpath before gwt. There are other latest jasper compiler jars out-there but i'm not sore of how compatible are with jakarta-tomcat-5.0.28

  2. https://code.google.com/archive/p/raisercostin/wikis/GwtEclipsePluginDebug.wiki

  3. This maybe caused by jar conflict. Remove the servlet-api.jar in your servlet/WEB-INF/ directory, %Tomcat home%/lib already have this lib.

  4. Every time I have seen those errors it has been because jasper could not find the java compilier. Try and put tools.jar in your common/lib and see if the service works then..

Read More