Java Spring Friendly Url mapping issues - java

I've been trying to implement friendly url mapping in my first Java spring site. I've been following this tutorial. http://outbottle.com/spring-3-web-mvc-friendly-url-using-requestmapping-variable-uri/
My current mapping works well with id's as parameters. localhost:8080/user?id=1312321321
/*
* User
*/
#RequestMapping(method=RequestMethod.GET, value={"/user","/user/{id}"})
public ModelAndView profileDisplay(
HttpServletRequest request,
HttpServletResponse response,
#RequestParam(value="id", required=false) String id
) throws UnknownHostException, MongoException {
ServiceSerlvet.appendSesssion(request);
//get search ALL users
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", new ObjectId(id));
List<DBObject> searchResponse = PersonController.searchUsers(searchQuery);
//System.out.println("response from search user method: "+searchResponse);
return new ModelAndView("user", "people", searchResponse);
}
My web xml currently looks like this... its working but is it correct to write out various url mapping like this? I take it the * is a wild card to allow say /user/22222?
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Spring3MVC</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>/gallery/*</url-pattern>
<url-pattern>/galleryupload/*</url-pattern>
<url-pattern>/delete/*</url-pattern>
<url-pattern>/edit/*</url-pattern>
<url-pattern>/search/*</url-pattern>
<url-pattern>/members/*</url-pattern>
<url-pattern>/profile/*</url-pattern>
<url-pattern>/messages/*</url-pattern>
<url-pattern>/index/*</url-pattern>
<url-pattern>/login/*</url-pattern>
<url-pattern>/logout/*</url-pattern>
<url-pattern>/register/*</url-pattern>
<url-pattern>/user/*</url-pattern>
<url-pattern>/jsoninterests/*</url-pattern>
<url-pattern>/jsonlocations/*</url-pattern>
<url-pattern>/jsonmembers/*</url-pattern>
<url-pattern>/jsonuniqueuser/*</url-pattern>
</servlet-mapping>
</web-app>
When I try and adapt my code to take just a name like this localhost:8080/user/john
it breaks - but I am unsure how to set the mapping in the web.xml, do I set the mapping like this in web.xml?
#RequestMapping(value="/user/{id}", method= RequestMethod.GET)
public ModelAndView profileDisplay(
#PathVariable(value="id") String id,
HttpServletRequest request,
HttpServletResponse response
) throws UnknownHostException, MongoException {
ServiceSerlvet.appendSesssion(request);
//get search ALL users
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", new ObjectId(id));
List<DBObject> searchResponse = PersonController.searchUsers(searchQuery);
//System.out.println("response from search user method: "+searchResponse);
return new ModelAndView("user", "people", searchResponse);
}

Normally I map every request to the dispatcher servlet in web.xml.
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Then in your Controllers use #RequestMapping annotations to define the more granular mappings:
#RequestMapping("/user/{id}")
public ModelAndView profileDisplay(
HttpServletRequest request,
HttpServletResponse response,
#RequestParam(value="id", required=false) String id
) throws UnknownHostException, MongoException {
...
}

Related

context.getInitParameter("") and config.getInitParameter("") always returning null

I am a beginner in servlets and JSP and I've tried my best to get the values yet I am getting null, any help is welcomed:
This is basic code on using ServletConfig and ServletContext to get param-value from web.xml
Servlet_Ex_4.java (- servlet):
#WebServlet("/Servlet_Ex_4")
public class Servlet_Ex_4 extends HttpServlet {
ServletContext context;
ServletConfig config;
String appUser ;
String Database ;
#Override
public void init() {
ServletContext context =getServletContext();
appUser = context.getInitParameter("appUser");
ServletConfig config =getServletConfig();
Database = config.getInitParameter("Database");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html");
PrintWriter out = response.getWriter();
//get ServletContext object.
//get context parameter from ServletContext object.
out.print("<h1>Application User: " + appUser + "</h1>");
out.print("<h1>Database: " + Database + "</h1>");
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<element>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>Servlet_Exercise_4</display-name>
<servlet>
<servlet-name>Servlet_4</servlet-name>
<servlet-class>Servlet_Ex_4</servlet-class>
<context-param>
<param-name>Database</param-name>
<param-value>Oracle</param-value>
</context-param>
</servlet>
<context-param>
<param-name>appUser</param-name>
<param-value>jai</param-value>
</context-param>
<servlet-mapping>
<servlet-name>Servlet_4</servlet-name>
<url-pattern>/Servlet_Ex_4</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
</element>
tag <element> must be removed from web.xml because it not part of XML definition in this case
<context-param> must not be used inside the <servlet>, it must be replaced by <init-param> to access parameters from ServletConfig object. This is the reason why the OP is getting null value.
<context-param> will work for parameter "appUser", it can be accessed using ServletContext object.
And mixing annotations with XML for same type of configurations can result in undesirable effects. So, #WebServlet should be removed from the source code as majority of configuration is done using XML.
So final web.xml should like below (with #WebServlet annotation removed from the Servlet_Ex_4 class)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
id="WebApp_ID" version="4.0">
<display-name>ServletParams</display-name>
<servlet>
<servlet-name>Servlet_4</servlet-name>
<servlet-class>Servlet_Ex_4</servlet-class>
<init-param>
<param-name>Database</param-name>
<param-value>Oracle</param-value>
</init-param>
</servlet>
<context-param>
<param-name>appUser</param-name>
<param-value>jai</param-value>
</context-param>
<servlet-mapping>
<servlet-name>Servlet_4</servlet-name>
<url-pattern>/Servlet_Ex_4</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

404 Spring root and not root URLs handling

URLs like this http://localhost:8080/app/service/c345gf.html?serviceId=101
goes to my notFoundPage, but the sources in the HTML are wrong http://localhost:8080/app/service/css/panels/rightPanel.css
But this stuff css/panels/rightPanel.css has such proper URL
http://localhost:8080/app/css/panels/rightPanel.css and
PROJECT_URL is hardcoded. So, why I have between hardcoded http://localhost:8080/app/ and /css part this part: /service?
public class ErrorService extends HttpServlet implements ProjectProperties {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
//...
out.println("<html>\n" +
"<head><title></title>\n" +
" <script type=\"text/javascript\" src=\"" + PROJECT_URL
Mapping:
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ErrorService</servlet-name>
<servlet-class>com.vse.uslugi.web.ErrorService</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorService</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>

Session Filter usage

I need to do a session filter. localhost:8080/Project/faces/index.xhtml is the login. If login is successful, the user will be redirected for app/conta.xhtml, but if user writes localhost:8080/Project/faces/app/conta.xhtml directly in address bar and not logged in must be redirected for index.xhtml again.
All pages that are in app/* must not be accessed without successful login.
My class LoginFilter is in the package filtro
#WebFilter("/app/*")
public class LoginFilter implements Filter {
#Override
public void init(FilterConfig config) throws ServletException {
// If you have any <init-param> in web.xml, then you could get them
// here by config.getInitParameter("name") and assign it as field.
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("idUsuario") == null) {
response.sendRedirect(request.getContextPath() + "../index.xhtml"); // No logged-in user found, so redirect to login page.
} else {
chain.doFilter(req, res); // Logged-in user found, so just continue request.
}
}
#Override
public void destroy() {
// If you have assigned any expensive resources as field of
// this Filter class, then you could clean/close them here.
}
}
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<filter>
<filter-name>Login Filter</filter-name>
<filter-class>filtro.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Login Filter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
</web-app>
Despite all this, I can enter /faces/app/conta.xhtml and have normal access!
This is my code for Login Validation = validarLogin()
BeanUsuarios.java
#ManagedBean
#ViewScoped
public class BeanUsuarios {
private Usuario usuario;
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
#PostConstruct
public void BeanUsuario(){
if(getUsuario()==null){
usuario = new Usuario();
}
}
public void validarLogin(){
UsuarioJpaController cUsuario = new UsuarioJpaController();
cUsuario.getEntityManager().createNamedQuery("Usuario.findByLogin").setParameter("login", this.usuario.getLogin()).getSingleResult();
if(usuario != null){
if(usuario.getSenha().equals(this.usuario.getSenha())){
FacesContext fc = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) fc.getExternalContext().getSession(false);
session.setAttribute("idUsuario", this.usuario.getId());
try {
FacesContext.getCurrentInstance()
.getExternalContext()
.redirect("app/conta.xhtml");
} catch (IOException ex) {
Logger.getLogger(BeanUsuarios.class.getName()).log(Level.SEVERE, null, ex);
}
}else{
}
}
}
}
You have two options:
Change the filter URL mapping to /faces/app* since that's how you're accessing your pages.
In the web.xml file, get rid of the /faces/* servlet mapping and use *.xhtml instead. This would require to change your welcome file to index.xhtml only.
IMO I would use option 2 since I don't like the Faces Servlet process the non-JSF related requests as JavaScript, CSS and images files.

When trying to produce a JSON Array with Apache Wink I get WebApplicationException

i'm new to JAX-RS. I'm trying to represent a List to a JSON array:
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/getUsersResource/{userId}")
public List<AbstractResource> getUsersResources(#PathParam("userId") final String userId) {
if (userId == null) {
return null;
}
User user = null;
try {
user = userDao.getUserById(Integer.parseInt(userId));
} catch (NumberFormatException nfe) {
user = userDao.getUser(userId);
}
if (user == null) {
return null;
}
return abstractResourceDao.getUsersResources(null, user.userId);
}
When i execute this url i get:
{"exception": {"name": "WebApplicationException"}}
I annotated my AbstractResource class with the #XmlRootElement only and when i change the #Produces annotation parameter to
#Produces(MediaType.APPLICATION_XML)
I get the proper result. Here is my web.xml:
<servlet>
<servlet-name>REST Application</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.balthaser.b3e.rest.RESTApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>REST Client</servlet-name>
<servlet-class>com.balthaser.b3e.rest.client.RESTClient</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST Client</servlet-name>
<url-pattern>/rest/index.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>REST Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Are there any additional requirements when producing JSON Arrays ?
Apache Wink is using json.org and jettison as a Json provider and they can't handle Java List properly.
So you need to configure Wink to use Jackson instead as a Json provider.
Here is the detail.
http://www.ibm.com/developerworks/java/library/wa-aj-jackson/index.html

Unused URI template variable - can I replace it with a wildcard?

I have code along the following lines in my Spring MVC webapp:
#RequestMapping("/{someVariable}/aPath/aPage.do")
public void serveAPage() {
doStuff();
}
We want "someVariable" to be in the URL, but we aren't interested in capturing and using the value of it. Is there any way of replacing it with a wildcard, e.g. /*/aPath/aPage.do?
Yes, #RequestMapping accepts Ant-style patterns as from http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params()
So this works:
#RequestMapping(value="/*/test2.do")
public void getMeta5(HttpServletRequest request, HttpServletResponse response) throws IOException {
final PrintWriter writer = response.getWriter();
writer.print("requestURI:" + request.getRequestURI());
writer.flush();
}
This assumes that servlet-mapping in web.xml maps that URL path to the DispatcherServlet, e.g.
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

Categories

Resources