I am having problem in some request access, in my web application. I am not able to figure out the issue.
In my we application servlet mapping configuration is like this..
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
and the spring configuration for dispatcher servlet is like this.
In WebApplicationInitializerConfig
AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherContext);
ServletRegistration.Dynamic dispatcher;
dispatcher = servletContext.addServlet("api/", dispatcherServlet);
dispatcher.setLoadOnStartup(1);
String apiMappingPath = /api/*;
dispatcher.addMapping(apiMappingPath);
When I make some API request, the call goes to the method and method sout also print in server log.But no response comes out.
For information I am deploying the application on glassfish server.
I am not able to get the issue reason also. If any one knows then help me out.
Method code:
#RequestMapping(value = "/email", method = RequestMethod.POST)
public Map passwordResetMail(#RequestBody(required = false) String email, HttpServletRequest request, HttpServletResponse response) {
system.out.println("email"+email);
Map map = new HashMap();
map.put("email",email);
return map;
}
Related
I am trying to use Jersey to provide a simple web service for my struts application.
When I call the client action I get the following error
com.sun.jersey.api.client.UniformInterfaceException
Message: GET http://localhost:8080/shumer/rest/employee/get returned a response status of 404
servlet declaration in web.xml
<servlet>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>spring.autowire</param-name>
<param-value>byName</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Server resource
#Path("employee")
public class EmployeeResource {
#Autowired
EmpDao empDao;
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Employee> get(#QueryParam("empCode") String empCode) throws Exception {
EmpCriteria criteria = new EmpCriteria();
criteria.setEmpCode(empCode);
return empDao.searchByCondition(criteria);
}
}
Client action
public class EmployeeClientTestAction extends Action {
#Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/shumer/rest/employee/get");
String employees= resource.accept(MediaType.APPLICATION_JSON)
.get(String.class);
System.out.println(employees);
request.setAttribute("employees", employees);
return mapping.findForward("successful");
}
}
I have tried this with and without the /get and the end of the resource url, and with and without a leading / in the EmployeeResource #Path annotation. My guess is that there is somewhere I have to declare where my resources are lcoated at in order for the Jersey servlet to handle them, but I can't figure it out. A point in the right direction would be much appreciated.
EDIT
I have added the following init-param to the servlet element and it is still not working (this package is where my resource class is)
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>shumer.rest.resource</param-value>
</init-param>
in get method write #Path("/get")
Not an expert in developing APIs so need some help/advice from the community.
I have an application that used Java Spring MVC for APIs. I am using ResponseEntity to return responses back to anyone who would use the APIs (third-party or UI).
Example of my API
#Controller
#RequestMapping("/Test/")
public ResponseEntity<TestGroup> getTestsById(#PathVariable("id") Integer id) {
TestGroup testGroup = testService.getTestById(id); //calls a service that returns test from the db
if(testGroup != null) {
return new ResponseEntity(testGroup, HttpStatus.OK);
} else {
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
}
I have other APIs similar to this. My question is whether there are any frameworks or ways so that I can make my APIs return JSON response for errors or success in a well formatted JSON. Example
{
"code": 400,
"message": "Bad Request",
"description": "There were no credentials found."
}
{
"code": 200,
"data": "{<JSON blob of the object to be returned>}"
}
Also,
Have implemented a Filter to check for session information (think of them as oauth tokes) for authentication before any of the routes are mapped. I need this process of error handling to work at that stage too, so that if there is an expired token or invalid token I get back a well formatted JSON. Example
{
"code": 401,
"message": "Unauthorized",
"description": "The token used in the request is incorrect or has expired."
}
Right now I get the default message Spring's authentication Filter throws in the form of an HTML
<html><head><title>Apache Tomcat/7.0.50 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - Access is denied</h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u>Access is denied</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>org.springframework.security.access.AccessDeniedException: Access is denied
org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83)
org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
com.test.security.CookieAuthenticationFilter.doFilter(CookieAuthenticationFilter.java:95)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
</pre></p><p><b>note</b> <u>The full stack trace of the root cause is available in the Apache Tomcat/7.0.50 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0.50</h3></body></html>
Apologize for not communicating this, I am not using spring security for the APIs and my web.xml for the filter looks like this
<web-app 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_2_5.xsd"
version="2.5">
<display-name>Webapp</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.spring.config</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.test.spring.config=</param-value>
</init-param>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Here is how the security configuration is handled.
#EnableWebSecurity
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfiguration.class);
#Autowired
private AbstractConfiguration configurationManager;
public SecurityConfiguration() {
super(true);
}
#Override
#Bean
protected AuthenticationManager authenticationManager() {
return new CustomAuthenticationManager();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/health/**").permitAll().and().authorizeRequests()
.antMatchers("/complete/**").permitAll().and()
.addFilterBefore(cookieAuthenticationFilter(), ChannelProcessingFilter.class).authorizeRequests()
.antMatchers("/**").hasAuthority("tests");
}
#Bean
public GenericFilterBean cookieAuthenticationFilter() {
if (System.getProperty("noauth") != null) {
return new SecurityFilterMock();
} else {
return new CookieAuthenticationFilter(redisTemplate());
}
}
}
As per suggestions if you read below, I have made the following EntryPoint class to handle the token authentication and display a JSON
public class TokenAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
private static final Logger log = LoggerFactory.getLogger(TokenAuthenticationEntryPoint.class);
#Override
public void commence(HttpServletRequest request,HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
log.info(String.format("Unauthorized access with session id '%s'",
request.getSession().getId()));
ErrorHandler errorResponse = new ErrorHandler();
// populate your response object with all the info you need
errorResponse.setCode(401);
errorResponse.setDescription("The token used in the request is incorrect or invalid.");
errorResponse.setMessage("Unauthorized");
ObjectMapper jsonMapper = new ObjectMapper();
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
PrintWriter out = response.getWriter();
out.print(jsonMapper.writeValueAsString(errorResponse));
}
}
Any suggestions or directions would be really appreciated
To return JSON formatted errors to authentication with Spring you can have a look at my answer here: How to return JSON response for unauthorized AJAX calls instead of login page as AJAX response?
Basically, you'll have to tweak authentication mechanism and redefine the entry point to properly hendle the response.
I'm trying to connect to a Jersey service using JQuery. But, it's not getting connected to the service, because I'm checking the logs whether it has hit the service or not. Is there anything missing?
$('#update').click(function() {
alert("updating the labelll");
$.ajax({
url:"/updatecontent",
type: 'POST',
dataType:"json",
data:$( "#labels option:selected" ).text(),
async:false,
success:function(contentdata) { // Success Call Back Function.
if(contentdata == "1") {
alert("successfully updated");
} else {
alert("sorry.. failed in updating");
}
},
error:function(){ // Error Call back function.
alert("sorry.. failed in updating in Error call back");
}
});
});
Service
---------
#Path("/updatecontent")
public class updatecontent {
private static final org.slf4j.Logger LOGGER=org.slf4j.LoggerFactory.getLogger(updatecontent.class);
#Context
HttpServletRequest request;
#Context
HttpServletResponse response;
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String updateStatus(String packet) throws JSONException {
// Get the object from the UI.
LOGGER.info("In the API class of updating content for review.");
return "1";
}
}
Web.xml
---------
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>net.my.services</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>6</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Am I missing anything here? There should be a minor issue. Any ideas would be greatly appreciated.
Your web.xml has an url-pattern of
<url-pattern>/rest/*</url-pattern>
So jQuery must connect to
/rest/updatecontent
I am following a tutorial book to develop a CRUD web application with J2EE and now it started using HttServlet. It might be that the book is not very new or that I don't really know how to do this.
I have my controller class, something like this:
public class Controller extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatcher = null;
Action action = null;
if (request.getServletPath().equals("/Insert.do")) {
action = new InsertAction();
} else if (request.getServletPath().equals("/Delete.do")) {
action = new DeleteAction();
.....
} else {
action = new FilterShowAction();
}
dispatcher = request.getRequestDispatcher(action.execute(request, response));
dispatcher.forward(request, response);
}
}
The tutorial made me create a new different class for every different CRUD action, forms, and a couple more things.
Here's the Action class:
public abstract class Action {
public abstract String execute(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException;
}
But then when I type localhost:8080/myapp/Controller/SomeAction.do I get an Error 404. Only when I type localhost:8080/myapp/Controller I get something else: the last else block in the doGet method is executed; anyway, I get a NullPointerException.
I have no idea how to do this thing right, and the book doesn't give any more information. I couldn't find a solution anywhere else.
Also, I don't understad what is the .do extension. The book just comes up with it and makes you include it in your code without explaining what the heck it is. I didn't find any information in the Internet either.
Any help would be much appreciated.
EDIT
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>Controller</servlet-name>
<display-name>Controller</display-name>
<servlet-class>mypackage.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>Controller</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/Error.jsp</location>
</error-page>
</web-app>
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>